<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>KyungRyeol Yoon</title><link>https://kyungryeol-yoon.github.io/</link><description>Recent content on KyungRyeol Yoon</description><generator>Hugo</generator><lastBuildDate>Wed, 10 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://kyungryeol-yoon.github.io/index.xml" rel="self" type="application/rss+xml"/><item><title>[Kubernetes] 🔒 Gateway API로 HTTP→HTTPS 리다이렉트 (HTTPRoute RequestRedirect)</title><link>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-gateway-api-http-to-https-redirect/</link><pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-gateway-api-http-to-https-redirect/</guid><description>&lt;p&gt;Gateway API에서 HTTP→HTTPS 리다이렉트는 Ingress의 annotation(&lt;code&gt;ssl-redirect&lt;/code&gt;)이 아니라 **표준 필터 &lt;code&gt;RequestRedirect&lt;/code&gt;**로 합니다. 이 글에서는 &lt;strong&gt;HTTP(80)·HTTPS(443) 리스너 2개 + HTTPRoute 2개&lt;/strong&gt;로 구성하는 기본형과, 앱 팀이 &lt;code&gt;sectionName&lt;/code&gt;을 빠뜨려도 평문 노출이 안 되도록 &lt;strong&gt;&lt;code&gt;allowedRoutes&lt;/code&gt;로 80 리스너를 잠그는&lt;/strong&gt; 실무 패턴, 그리고 &amp;ldquo;구성했는데 http가 계속 되는&amp;rdquo; 트러블슈팅을 정리합니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;이 시리즈는&lt;/strong&gt; 쿠버네티스 gRPC 삽질에서 출발해 HTTP/2·TLS·로드밸런서·Gateway API·인증서까지 풀어가는 기록입니다. 앞선 &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-ingress-to-gateway-api-httproute/"&gt;Ingress → Gateway API 편&lt;/a&gt;과 &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-cert-manager-pki-tls/"&gt;cert-manager TLS 편&lt;/a&gt;을 먼저 보면 이해가 빠릅니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-핵심-requestredirect-필터"&gt;
 🎯 핵심: RequestRedirect 필터
 &lt;a class="heading-anchor" href="#-%ed%95%b5%ec%8b%ac-requestredirect-%ed%95%84%ed%84%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;RequestRedirect&lt;/code&gt;는 클라이언트에 3XX 응답을 돌려줘 다른 위치로 다시 요청하게 하는 Gateway API 표준 필터입니다.&lt;/strong&gt; HTTPRoute의 &lt;code&gt;rules[].filters&lt;/code&gt;에 &lt;code&gt;type: RequestRedirect&lt;/code&gt;를 선언하고, HTTP→HTTPS 업그레이드는 &lt;code&gt;scheme: https&lt;/code&gt; + &lt;code&gt;statusCode: 301&lt;/code&gt;이 정석입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;RequestRedirect&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requestRedirect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;301&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;리다이렉트는 &lt;strong&gt;지정한 URL 요소만 바꾸고 나머지는 보존&lt;/strong&gt;합니다. 예를 들어 &lt;code&gt;GET http://redirect.example/cinnamon&lt;/code&gt; 요청은 다음과 같이 응답됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-http" data-lang="http"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;301&lt;/span&gt; &lt;span class="ne"&gt;Moved Permanently&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;https://redirect.example/cinnamon&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;scheme만 &lt;code&gt;https&lt;/code&gt;로 바뀌고 host(&lt;code&gt;redirect.example&lt;/code&gt;)·path(&lt;code&gt;/cinnamon&lt;/code&gt;)는 그대로 유지됩니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;code&gt;RequestRedirect&lt;/code&gt;와 &lt;code&gt;URLRewrite&lt;/code&gt;는 &lt;strong&gt;한 rule 안에서 동시에 쓸 수 없습니다.&lt;/strong&gt; RequestRedirect는 클라이언트에게 3XX로 &amp;ldquo;다시 요청해라&amp;quot;를 돌려주는 것이고, URLRewrite는 백엔드로 보내기 전에 요청을 조용히 바꾸는 것이라 성격이 다릅니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="지원하는-상태-코드는"&gt;
 지원하는 상태 코드는?
 &lt;a class="heading-anchor" href="#%ec%a7%80%ec%9b%90%ed%95%98%eb%8a%94-%ec%83%81%ed%83%9c-%ec%bd%94%eb%93%9c%eb%8a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;코드&lt;/th&gt;
					&lt;th&gt;의미&lt;/th&gt;
					&lt;th&gt;메모&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;301&lt;/td&gt;
					&lt;td&gt;영구 이동 (Moved Permanently)&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;HTTP→HTTPS 업그레이드 권장&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;302&lt;/td&gt;
					&lt;td&gt;임시 (Found)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;statusCode&lt;/code&gt; 생략 시 기본값&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;303&lt;/td&gt;
					&lt;td&gt;See Other&lt;/td&gt;
					&lt;td&gt;POST→GET 패턴&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;307&lt;/td&gt;
					&lt;td&gt;임시 + &lt;strong&gt;메서드 보존&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Extended 지원&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;308&lt;/td&gt;
					&lt;td&gt;영구 + &lt;strong&gt;메서드 보존&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Extended 지원&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 307/308과 path 단위 redirect는 &amp;ldquo;Extended&amp;rdquo; 지원이라 구현체(Contour·Istio·Envoy Gateway 등)별로 지원 여부가 다릅니다. 사용 전 &lt;a href="https://gateway-api.sigs.k8s.io/concepts/conformance/"&gt;conformance 문서&lt;/a&gt;로 확인하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-기본-구성-리스너-2개--라우트-2개"&gt;
 🧱 기본 구성: 리스너 2개 + 라우트 2개
 &lt;a class="heading-anchor" href="#-%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%84%b1-%eb%a6%ac%ec%8a%a4%eb%84%88-2%ea%b0%9c--%eb%9d%bc%ec%9a%b0%ed%8a%b8-2%ea%b0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;HTTP→HTTPS 리다이렉트의 기본형은 Gateway에 80·443 리스너를 모두 두고, HTTPRoute를 2개(80=리다이렉트, 443=백엔드 전달) 만드는 것입니다.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="1-gateway--httphttps-리스너-둘-다"&gt;
 1️⃣ Gateway — HTTP·HTTPS 리스너 둘 다
 &lt;a class="heading-anchor" href="#1-gateway--httphttps-%eb%a6%ac%ec%8a%a4%eb%84%88-%eb%91%98-%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Gateway&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redirect-gateway&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gateway-system &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 플랫폼팀 소유&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gatewayClassName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;foo-lb&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;HTTP&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;HTTPS&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Terminate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;certificateRefs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redirect-example &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# TLS Secret (cert-manager가 발급)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="2-httproute---80-리스너에-붙여-리다이렉트"&gt;
 2️⃣ HTTPRoute ① — 80 리스너에 붙여 리다이렉트
 &lt;a class="heading-anchor" href="#2-httproute---80-%eb%a6%ac%ec%8a%a4%eb%84%88%ec%97%90-%eb%b6%99%ec%97%ac-%eb%a6%ac%eb%8b%a4%ec%9d%b4%eb%a0%89%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;HTTPRoute&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http-filter-redirect&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gateway-system &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 80 리스너에 붙이려면 Gateway와 같은 네임스페이스&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parentRefs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redirect-gateway&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;sectionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# http(80) 리스너만 선택&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostnames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;redirect.example&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;RequestRedirect&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requestRedirect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;301&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="3-httproute---443-리스너에-붙여-백엔드로-전달"&gt;
 3️⃣ HTTPRoute ② — 443 리스너에 붙여 백엔드로 전달
 &lt;a class="heading-anchor" href="#3-httproute---443-%eb%a6%ac%ec%8a%a4%eb%84%88%ec%97%90-%eb%b6%99%ec%97%ac-%eb%b0%b1%ec%97%94%eb%93%9c%eb%a1%9c-%ec%a0%84%eb%8b%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;HTTPRoute&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https-route&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;team-a &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 앱 팀 네임스페이스&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gateway-access&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 443 리스너 allowedRoutes selector와 매칭 (아래 참고)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parentRefs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redirect-gateway&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gateway-system &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Gateway가 다른 네임스페이스라 명시&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;sectionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostnames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;redirect.example&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;backendRefs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;example-svc &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# team-a 안의 Service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;네임스페이스 배치 메모&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Gateway + 리다이렉트 라우트&lt;/strong&gt; → &lt;code&gt;gateway-system&lt;/code&gt;(플랫폼). 80 리스너가 기본 &lt;code&gt;from: Same&lt;/code&gt;이라 리다이렉트 라우트도 같은 ns에 둬야 붙습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;백엔드 라우트&lt;/strong&gt; → &lt;code&gt;team-a&lt;/code&gt;(앱 팀). Gateway가 다른 ns라 &lt;code&gt;parentRefs.namespace&lt;/code&gt;를 명시하고, 443 리스너의 &lt;code&gt;allowedRoutes&lt;/code&gt;가 이 ns를 허용해야 합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;backendRefs&lt;/code&gt;가 다른 ns의 Service&lt;/strong&gt;를 가리키면 그쪽에 &lt;strong&gt;ReferenceGrant&lt;/strong&gt;가 필요합니다. 같은 ns면 불필요.&lt;/li&gt;
&lt;li&gt;모두 한 네임스페이스에 둘 거면 namespace 표기는 생략해도 됩니다(공식 가이드 예시 형태).&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-왜-라우트가-꼭-2개여야-하나"&gt;
 ❓ 왜 라우트가 꼭 2개여야 하나?
 &lt;a class="heading-anchor" href="#-%ec%99%9c-%eb%9d%bc%ec%9a%b0%ed%8a%b8%ea%b0%80-%ea%bc%ad-2%ea%b0%9c%ec%97%ac%ec%95%bc-%ed%95%98%eb%82%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;한 HTTPRoute의 &lt;code&gt;rules&lt;/code&gt;는 그 라우트가 붙은 모든 리스너에 똑같이 적용되기 때문입니다.&lt;/strong&gt; 그래서 &amp;ldquo;80=리다이렉트 / 443=백엔드 전달&amp;quot;을 한 라우트 안에서 나눌 수 없습니다. 역할별로 라우트를 분리해야 합니다.&lt;/p&gt;
&lt;h3 id="리다이렉트-라우트는-게이트웨이당-1개로-충분합니다"&gt;
 리다이렉트 라우트는 게이트웨이당 1개로 충분합니다
 &lt;a class="heading-anchor" href="#%eb%a6%ac%eb%8b%a4%ec%9d%b4%eb%a0%89%ed%8a%b8-%eb%9d%bc%ec%9a%b0%ed%8a%b8%eb%8a%94-%ea%b2%8c%ec%9d%b4%ed%8a%b8%ec%9b%a8%ec%9d%b4%eb%8b%b9-1%ea%b0%9c%eb%a1%9c-%ec%b6%a9%eb%b6%84%ed%95%a9%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;리다이렉트 라우트에서 &lt;code&gt;hostnames&lt;/code&gt;를 생략하면 그 80 리스너로 들어오는 &lt;strong&gt;모든 호스트&lt;/strong&gt;에 적용됩니다. 따라서 앱이 여러 개여도 리다이렉트 라우트는 하나면 되고, 나머지는 각 앱의 443 백엔드 라우트만 추가하면 됩니다(어차피 만들 것).&lt;/p&gt;
&lt;h3 id="sectionname-https만-박으면-404-리다이렉트가-아닙니다"&gt;
 &lt;code&gt;sectionName: https&lt;/code&gt;만 박으면 404, 리다이렉트가 아닙니다
 &lt;a class="heading-anchor" href="#sectionname-https%eb%a7%8c-%eb%b0%95%ec%9c%bc%eb%a9%b4-404-%eb%a6%ac%eb%8b%a4%ec%9d%b4%eb%a0%89%ed%8a%b8%ea%b0%80-%ec%95%84%eb%8b%99%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;앱 라우트를 443에만 고정하면 80으로 온 요청은 &lt;strong&gt;매칭되는 라우트가 없어 404&lt;/strong&gt;가 납니다(리다이렉트 ❌). 브라우저로 테스트했을 때 https로 넘어갔다면 그건 브라우저의 https-first 동작일 뿐, 게이트웨이가 리다이렉트한 게 아닙니다. curl·모바일 앱 등 http 클라이언트를 부드럽게 https로 보내려면 &lt;strong&gt;리다이렉트 라우트는 여전히 필요&lt;/strong&gt;합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-allowedroutes로-평문-노출-원천-차단"&gt;
 🛡️ allowedRoutes로 평문 노출 원천 차단
 &lt;a class="heading-anchor" href="#-allowedroutes%eb%a1%9c-%ed%8f%89%eb%ac%b8-%eb%85%b8%ec%b6%9c-%ec%9b%90%ec%b2%9c-%ec%b0%a8%eb%8b%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;앱 팀이 &lt;code&gt;sectionName&lt;/code&gt;을 빠뜨리면 그 라우트가 80 리스너에도 바인딩돼 평문(HTTP)으로 서빙될 수 있습니다.&lt;/strong&gt; 개별 라우트의 &amp;ldquo;예의&amp;quot;에 기대지 말고, 80 리스너를 플랫폼 전용으로 잠가서 막는 것이 안전합니다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sectionName&lt;/code&gt;이 없으면 라우트는 호환되는 &lt;strong&gt;모든 리스너(80 포함)에 바인딩&lt;/strong&gt;됩니다. 그러면 80에서 백엔드 라우트가 리다이렉트 라우트보다 더 구체적으로 매칭되어 평문 서빙이 일어날 수 있습니다. &lt;code&gt;allowedRoutes&lt;/code&gt;로 다음처럼 잠급니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;HTTP&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;allowedRoutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespaces&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Same &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 게이트웨이 네임스페이스(=플랫폼 리다이렉트 라우트)만 허용&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;HTTPS&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Terminate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;certificateRefs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redirect-example&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;allowedRoutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespaces&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Selector &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 앱 팀 라우트는 여기에만&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gateway-access&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이렇게 하면 앱 팀이 &lt;code&gt;sectionName&lt;/code&gt;을 빠뜨려도 그 라우트는 &lt;strong&gt;80에서는 거부&lt;/strong&gt;되고 443에만 붙습니다. 80은 플랫폼 리다이렉트 라우트가 독점하므로 &lt;strong&gt;평문 노출이 원천 차단&lt;/strong&gt;됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-트러블슈팅-구성했는데-http가-계속-될-때"&gt;
 🔧 트러블슈팅: 구성했는데 http가 계속 될 때
 &lt;a class="heading-anchor" href="#-%ed%8a%b8%eb%9f%ac%eb%b8%94%ec%8a%88%ed%8c%85-%ea%b5%ac%ec%84%b1%ed%96%88%eb%8a%94%eb%8d%b0-http%ea%b0%80-%ea%b3%84%ec%86%8d-%eb%90%a0-%eb%95%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;순서대로 확인합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1️⃣ 리다이렉트 라우트가 80에 진짜 붙었나?&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl describe httproute http-filter-redirect -n gateway-system&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;status.parents[].conditions&lt;/code&gt;에서 &lt;code&gt;Accepted: True&lt;/code&gt;인지 확인합니다. 안 붙는 흔한 원인:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;allowedRoutes&lt;/code&gt; 네임스페이스 불일치(기본값이 &lt;code&gt;Same&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sectionName&lt;/code&gt; 오타 (&lt;code&gt;http&lt;/code&gt;인데 &lt;code&gt;https&lt;/code&gt;로 쓰는 등)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;parentRefs.namespace&lt;/code&gt; 오류&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hostnames&lt;/code&gt; 불일치&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2️⃣ 80에 백엔드 라우트가 끼어들었나?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;앱 라우트가 &lt;code&gt;sectionName&lt;/code&gt; 없이 80에도 붙으면 매칭 우선순위에서 백엔드가 이겨 평문으로 서빙됩니다. → 앱 라우트에 &lt;code&gt;sectionName: https&lt;/code&gt;를 명시하거나, 위 &lt;code&gt;allowedRoutes&lt;/code&gt; 잠금을 적용합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3️⃣ 요청이 이 Gateway를 거치긴 하나?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;예전 ingress-nginx가 아직 80을 서비스하고 있거나, NodePort·LB로 백엔드에 직접 접근하거나, &lt;code&gt;port-forward&lt;/code&gt;로 테스트하는 경우 Gateway가 트래픽 경로에 없어 리다이렉트가 적용될 리 없습니다.&lt;/p&gt;
&lt;p&gt;리다이렉트 동작 확인은 curl로 합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -I http://redirect.example/cinnamon
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# HTTP/1.1 301 Moved Permanently&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# location: https://redirect.example/cinnamon&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-ingress의-ssl-redirect-annotation과-무엇이-다른가요"&gt;
 Q. Ingress의 &lt;code&gt;ssl-redirect&lt;/code&gt; annotation과 무엇이 다른가요?
 &lt;a class="heading-anchor" href="#q-ingress%ec%9d%98-ssl-redirect-annotation%ea%b3%bc-%eb%ac%b4%ec%97%87%ec%9d%b4-%eb%8b%a4%eb%a5%b8%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Ingress는 컨트롤러마다 &lt;code&gt;nginx.ingress.kubernetes.io/ssl-redirect: &amp;quot;true&amp;quot;&lt;/code&gt; 같은 &lt;strong&gt;벤더 전용 annotation&lt;/strong&gt;으로 리다이렉트했습니다. Gateway API는 이를 표준 필터 &lt;code&gt;RequestRedirect&lt;/code&gt;로 정의해 &lt;strong&gt;구현체에 상관없이 동일한 스펙&lt;/strong&gt;으로 동작하게 합니다.&lt;/p&gt;
&lt;h3 id="q-301과-302-중-무엇을-써야-하나요"&gt;
 Q. 301과 302 중 무엇을 써야 하나요?
 &lt;a class="heading-anchor" href="#q-301%ea%b3%bc-302-%ec%a4%91-%eb%ac%b4%ec%97%87%ec%9d%84-%ec%8d%a8%ec%95%bc-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;HTTP→HTTPS 영구 전환에는 **301(영구 이동)**을 권장합니다. 브라우저·검색엔진이 결과를 캐시해 다음부터 바로 https로 요청하기 때문입니다. &lt;code&gt;statusCode&lt;/code&gt;를 생략하면 기본값은 302(임시)입니다.&lt;/p&gt;
&lt;h3 id="q-리다이렉트-라우트를-빼고-443-라우트만-두면-안-되나요"&gt;
 Q. 리다이렉트 라우트를 빼고 443 라우트만 두면 안 되나요?
 &lt;a class="heading-anchor" href="#q-%eb%a6%ac%eb%8b%a4%ec%9d%b4%eb%a0%89%ed%8a%b8-%eb%9d%bc%ec%9a%b0%ed%8a%b8%eb%a5%bc-%eb%b9%bc%ea%b3%a0-443-%eb%9d%bc%ec%9a%b0%ed%8a%b8%eb%a7%8c-%eb%91%90%eb%a9%b4-%ec%95%88-%eb%90%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;브라우저는 https-first 동작 때문에 잘 넘어가는 것처럼 보이지만, 80으로 직접 온 요청(curl·구형 클라이언트·외부 연동)은 &lt;strong&gt;404&lt;/strong&gt;가 납니다. 부드러운 리다이렉트를 보장하려면 80 리스너에 붙는 리다이렉트 라우트가 반드시 필요합니다.&lt;/p&gt;
&lt;h3 id="q-post-요청도-리다이렉트되나요"&gt;
 Q. POST 요청도 리다이렉트되나요?
 &lt;a class="heading-anchor" href="#q-post-%ec%9a%94%ec%b2%ad%eb%8f%84-%eb%a6%ac%eb%8b%a4%ec%9d%b4%eb%a0%89%ed%8a%b8%eb%90%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;301/302는 리다이렉트 시 메서드가 GET으로 바뀔 수 있습니다. POST 등 메서드를 보존해야 하면 &lt;strong&gt;307/308&lt;/strong&gt;을 사용해야 하지만, 이는 Extended 지원이라 구현체 지원 여부를 먼저 확인하세요.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📚 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gateway-api.sigs.k8s.io/guides/user-guides/http-redirect-rewrite/"&gt;HTTP redirects and rewrites (Gateway API 공식 가이드)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gateway-api.sigs.k8s.io/reference/api-types/httproute/"&gt;HTTPRoute API 레퍼런스&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gateway-api.sigs.k8s.io/reference/api-spec/main/spec/#httprequestredirectfilter"&gt;HTTPRequestRedirectFilter 스펙&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gateway-api.sigs.k8s.io/guides/user-guides/multiple-ns/"&gt;Cross-Namespace routing (allowedRoutes)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gateway-api.sigs.k8s.io/guides/user-guides/tls/"&gt;TLS 설정 가이드&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gateway-api.sigs.k8s.io/concepts/conformance/"&gt;Conformance(지원 레벨) 개념&lt;/a&gt;
&lt;/content&gt;
&lt;/invoke&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] 🔏 인증서와 cert-manager: 두 갈래 PKI와 TLS 자동화</title><link>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-cert-manager-pki-tls/</link><pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-cert-manager-pki-tls/</guid><description>&lt;p&gt;쿠버네티스를 다루다 보면 kubeadm로 클러스터를 세울 때도 인증서가 나오고, Ingress·Gateway에도 인증서가 나옵니다. 같은 걸까요? 이 글에서는 &lt;code&gt;key&lt;/code&gt;·&lt;code&gt;cert&lt;/code&gt;·&lt;code&gt;CA&lt;/code&gt;·&lt;code&gt;TLS&lt;/code&gt; 용어를 신분증 비유로 정리하고, 쿠버네티스에 **PKI가 두 갈래(클러스터 내부 mTLS vs 앱/인그레스 TLS)**로 별개라는 점, 그리고 cert-manager가 &amp;ldquo;받은 인증서를 넣는&amp;rdquo; 게 아니라 &lt;strong&gt;발급·갱신 행위를 자동화&lt;/strong&gt;한다는 핵심을 다룹니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;이 시리즈는&lt;/strong&gt; 쿠버네티스 gRPC 삽질에서 출발해 HTTP/2·TLS·로드밸런서·Gateway API·인증서까지 풀어가는 기록입니다. 이번 6편은 &lt;strong&gt;인증서와 cert-manager&lt;/strong&gt; 편입니다. 앞선 &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-http2-vs-h2c-tls/"&gt;2편(h2 vs h2c)&lt;/a&gt;, &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-ingress-to-gateway-api-httproute/"&gt;5편(Gateway API)&lt;/a&gt;을 먼저 보면 좋습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-용어-4개--경쟁-관계가-아니라-한-시스템의-역할들"&gt;
 🪪 용어 4개 — 경쟁 관계가 아니라 한 시스템의 역할들
 &lt;a class="heading-anchor" href="#-%ec%9a%a9%ec%96%b4-4%ea%b0%9c--%ea%b2%bd%ec%9f%81-%ea%b4%80%ea%b3%84%ea%b0%80-%ec%95%84%eb%8b%88%eb%9d%bc-%ed%95%9c-%ec%8b%9c%ec%8a%a4%ed%85%9c%ec%9d%98-%ec%97%ad%ed%95%a0%eb%93%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;key·CA·certificate·TLS는 서로 다른 선택지가 아니라, 하나의 신분증 시스템을 이루는 역할들입니다.&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;용어&lt;/th&gt;
					&lt;th&gt;신분증 비유&lt;/th&gt;
					&lt;th&gt;실제 의미&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;key(키)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;나만 만들 수 있는 서명&lt;/td&gt;
					&lt;td&gt;개인키 + 검증용 공개키. 모든 것의 토대&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;CA(인증기관)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;신분증 발급 기관(정부)&lt;/td&gt;
					&lt;td&gt;자기 키(CA key)로 인증서에 도장을 찍음&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;certificate(cert/crt)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;신분증 카드 그 자체&lt;/td&gt;
					&lt;td&gt;공개키 + 신원 + CA의 서명&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;TLS&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;검문소에서 신분증 제시·검증&lt;/td&gt;
					&lt;td&gt;위 재료를 실제로 쓰는 프로토콜&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;정리하면 &amp;ldquo;&lt;strong&gt;CA가 자기 키로 인증서(신분증)에 서명하고, TLS가 연결할 때 그걸 제시·검증한다.&lt;/strong&gt;&amp;rdquo; 넷이 한 흐름의 부품이지, 서로 다른 선택지가 아닙니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-헷갈림의-핵심-같은-기술을-쓰는-별개의-두-체계"&gt;
 🍴 헷갈림의 핵심: 같은 기술을 쓰는 별개의 두 체계
 &lt;a class="heading-anchor" href="#-%ed%97%b7%ea%b0%88%eb%a6%bc%ec%9d%98-%ed%95%b5%ec%8b%ac-%ea%b0%99%ec%9d%80-%ea%b8%b0%ec%88%a0%ec%9d%84-%ec%93%b0%eb%8a%94-%eb%b3%84%ea%b0%9c%ec%9d%98-%eb%91%90-%ec%b2%b4%ea%b3%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;쿠버네티스에는 완전히 별개인 두 종류의 인증서 체계가 있고, 둘 다 같은 기술(X.509 + TLS)을 써서 똑같아 보입니다.&lt;/strong&gt; 여기가 진짜 함정입니다.&lt;/p&gt;
&lt;h3 id="-클러스터-내부-pki-kubeadm-certs--컴포넌트끼리-인증용"&gt;
 ① 클러스터 내부 PKI (kubeadm certs) — 컴포넌트끼리 인증용
 &lt;a class="heading-anchor" href="#-%ed%81%b4%eb%9f%ac%ec%8a%a4%ed%84%b0-%eb%82%b4%eb%b6%80-pki-kubeadm-certs--%ec%bb%b4%ed%8f%ac%eb%84%8c%ed%8a%b8%eb%81%bc%eb%a6%ac-%ec%9d%b8%ec%a6%9d%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;클러스터에 &lt;strong&gt;자체 CA&lt;/strong&gt;(&lt;code&gt;ca.crt&lt;/code&gt;/&lt;code&gt;ca.key&lt;/code&gt;)가 있고, 그게 API 서버·etcd·kubelet 등의 인증서를 서명합니다.&lt;/li&gt;
&lt;li&gt;컴포넌트들은 &amp;ldquo;상대 인증서가 우리 클러스터 CA가 서명한 거냐&amp;quot;로 서로를 믿습니다(mTLS, 상호 인증).&lt;/li&gt;
&lt;li&gt;이게 보통 갱신하는 그 인증서입니다. (잎사귀(leaf) 인증서는 기본 1년, CA 자체는 보통 10년)&lt;/li&gt;
&lt;li&gt;관리 도구: kubeadm (&lt;code&gt;kubeadm certs renew&lt;/code&gt; 등). &lt;strong&gt;외부 서비스와 무관.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="-앱인그레스-tls-gatewayingress--cert-manager--외부-클라이언트용"&gt;
 ② 앱/인그레스 TLS (Gateway·Ingress + cert-manager) — 외부 클라이언트용
 &lt;a class="heading-anchor" href="#-%ec%95%b1%ec%9d%b8%ea%b7%b8%eb%a0%88%ec%8a%a4-tls-gatewayingress--cert-manager--%ec%99%b8%eb%b6%80-%ed%81%b4%eb%9d%bc%ec%9d%b4%ec%96%b8%ed%8a%b8%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;공인 CA(또는 사내 CA)가 &lt;code&gt;a.example.com&lt;/code&gt; 같은 &lt;strong&gt;도메인 인증서&lt;/strong&gt;를 서명합니다.&lt;/li&gt;
&lt;li&gt;외부 브라우저·클라이언트가 &amp;ldquo;이 https 서버 믿어도 되나&amp;quot;를 판단하는 용도입니다.&lt;/li&gt;
&lt;li&gt;관리 도구: cert-manager나 수동 Secret. &lt;strong&gt;클러스터 내부 통신과 무관.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;🧠 둘은 별개의 CA, 별개의 목적, 별개의 수명·관리 도구입니다. 클러스터 CA는 &lt;code&gt;a.example.com&lt;/code&gt; 인증서와 아무 상관이 없고, 브라우저는 클러스터 CA를 모르며, 컴포넌트들은 Let&amp;rsquo;s Encrypt를 신경 쓰지 않습니다. 기술은 같지만(X.509+TLS), 다른 건 &lt;strong&gt;&amp;ldquo;누구를 위한 신뢰냐&amp;rdquo;&lt;/strong&gt; — ①은 클러스터 식구들끼리, ②는 바깥 손님에게입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;구분&lt;/th&gt;
					&lt;th&gt;① 클러스터 내부 PKI&lt;/th&gt;
					&lt;th&gt;② 앱/인그레스 TLS&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;목적&lt;/td&gt;
					&lt;td&gt;컴포넌트 상호 인증(mTLS)&lt;/td&gt;
					&lt;td&gt;외부 클라이언트 신뢰&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CA&lt;/td&gt;
					&lt;td&gt;클러스터 자체 CA&lt;/td&gt;
					&lt;td&gt;공인/사내 CA (Let&amp;rsquo;s Encrypt 등)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;수명&lt;/td&gt;
					&lt;td&gt;leaf 1년, CA 10년&lt;/td&gt;
					&lt;td&gt;발급처별(Let&amp;rsquo;s Encrypt 90일)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;관리&lt;/td&gt;
					&lt;td&gt;kubeadm&lt;/td&gt;
					&lt;td&gt;cert-manager / 수동 Secret&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;이제부터는 ②(앱/인그레스 TLS) 얘기입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-gateway에서-tls를-중앙화하기"&gt;
 🏢 Gateway에서 TLS를 중앙화하기
 &lt;a class="heading-anchor" href="#-gateway%ec%97%90%ec%84%9c-tls%eb%a5%bc-%ec%a4%91%ec%95%99%ed%99%94%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Gateway API에서는 TLS 설정이 Gateway의 listener로 올라가, TLS 개인키가 플랫폼팀 한 곳에 모입니다.&lt;/strong&gt; 5편에서 본 역할 분리가 여기서 보안 이점으로 이어집니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;예전 Ingress 방식의 약점&lt;/strong&gt;: Ingress의 TLS Secret은 Ingress와 같은 네임스페이스, 즉 &lt;strong&gt;앱팀 네임스페이스&lt;/strong&gt;에 있어야 했습니다. 그래서 TLS 개인키가 팀마다 흩어졌고, 관리·감사 범위가 컸습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gateway API에서는&lt;/strong&gt; Gateway(플랫폼팀 리소스)의 listener에 TLS를 두므로, &lt;strong&gt;개인키가 플랫폼팀 한 곳에 모이고 앱팀은 Route만 붙입니다.&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Gateway&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;shared-gateway&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gateway-system &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 플랫폼팀 소유&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;team-a&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;HTTPS&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;a.example.com&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 프로젝트별 도메인&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Terminate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;certificateRefs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;team-a-tls &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 프로젝트별 인증서&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;allowedRoutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespaces&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Selector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;team&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;프로젝트별로 다른 인증서&lt;/strong&gt;도 가능합니다. listener를 도메인별로 나누면 TLS의 SNI(접속하려는 도메인)로 인증서가 자동 선택됩니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;추가 통제 장치&lt;/strong&gt;: &lt;code&gt;allowedRoutes&lt;/code&gt;로 어느 네임스페이스의 Route만 붙을지 제한하고, 다른 네임스페이스의 Secret을 참조하려면 &lt;strong&gt;ReferenceGrant&lt;/strong&gt;로 명시적 허용이 필요합니다(크로스 네임스페이스 접근 기본 차단 = 보안 기능).&lt;/li&gt;
&lt;li&gt;HTTPRoute가 어느 listener에 붙을지는 &lt;code&gt;hostname&lt;/code&gt; 교집합으로 자동 매칭되고, 명확히 하려면 &lt;code&gt;sectionName&lt;/code&gt;(listener 이름)을 적어주면 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-cert-manager--받은-인증서를-넣는-게-아니라-받는-행위를-자동화"&gt;
 🤖 cert-manager — &amp;ldquo;받은 인증서를 넣는&amp;rdquo; 게 아니라 &amp;ldquo;받는 행위를 자동화&amp;rdquo;
 &lt;a class="heading-anchor" href="#-cert-manager--%eb%b0%9b%ec%9d%80-%ec%9d%b8%ec%a6%9d%ec%84%9c%eb%a5%bc-%eb%84%a3%eb%8a%94-%ea%b2%8c-%ec%95%84%eb%8b%88%eb%9d%bc-%eb%b0%9b%eb%8a%94-%ed%96%89%ec%9c%84%eb%a5%bc-%ec%9e%90%eb%8f%99%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;cert-manager는 담당자에게 받은 인증서를 넣어주는 도구가 아니라, 직접 개인키를 만들고 CA에 인증서를 요청해 받아오는 도구입니다.&lt;/strong&gt; 작동 방향이 반대라는 점이 큰 오해 포인트입니다. 즉 완성된 인증서를 사람한테 받아 넣는 게 아니라, &lt;strong&gt;사람의 손을 거치는 단계 자체를 없앱니다.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="자동화-흐름"&gt;
 자동화 흐름
 &lt;a class="heading-anchor" href="#%ec%9e%90%eb%8f%99%ed%99%94-%ed%9d%90%eb%a6%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;cert-manager 설치 (클러스터에 Pod로)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Issuer/ClusterIssuer&lt;/strong&gt; 정의 — &amp;ldquo;인증서를 어디서 받을지&amp;rdquo;(Let&amp;rsquo;s Encrypt, Vault, 사내 CA 등)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Certificate&lt;/strong&gt; 생성(또는 애너테이션) — &amp;ldquo;a.example.com 인증서 필요&amp;rdquo;&lt;/li&gt;
&lt;li&gt;cert-manager가 발급처와 통신하고 &lt;strong&gt;도메인 소유를 증명&lt;/strong&gt;(HTTP-01 / DNS-01 챌린지)&lt;/li&gt;
&lt;li&gt;받은 인증서+키를 &lt;strong&gt;Secret에 자동 저장&lt;/strong&gt; → Gateway가 그 Secret 참조&lt;/li&gt;
&lt;li&gt;만료 전 &lt;strong&gt;자동 갱신&lt;/strong&gt; (예: Let&amp;rsquo;s Encrypt는 90일)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;핵심은 &lt;strong&gt;사람이 개인키를 만들거나 &lt;code&gt;secret.yaml&lt;/code&gt;을 주고받을 일이 사라진다&lt;/strong&gt;는 것입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# ClusterIssuer (Let&amp;#39;s Encrypt ACME)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cert-manager.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterIssuer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;letsencrypt-prod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;acme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://acme-v02.api.letsencrypt.org/directory&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;admin@example.com&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;privateKeySecretRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;letsencrypt-prod-account-key&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;solvers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;http01&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ingress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;class&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Certificate — cert-manager가 발급·갱신·Secret 저장을 자동 처리&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cert-manager.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Certificate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;team-a-tls&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gateway-system&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secretName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;team-a-tls &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Gateway가 참조하는 Secret 이름&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dnsNames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;a.example.com&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;issuerRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;letsencrypt-prod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterIssuer&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;발급처(issuer) 종류도 다양합니다: ACME(Let&amp;rsquo;s Encrypt 등), HashiCorp Vault, Venafi, 사내 CA, self-signed. 핵심은 &amp;ldquo;사람이 아니라 &lt;strong&gt;프로그램이 자동으로 요청·수령할 수 있는&lt;/strong&gt; 발급처&amp;quot;라는 점입니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ cert-manager가 수동 발급을 대체하려면 회사 CA가 &lt;strong&gt;자동 연동(ACME/Vault 등) 가능&lt;/strong&gt;해야 합니다. 순수 수동 발급뿐이면 cert-manager가 그 발급을 자동화하지 못합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;수동 발급을 유지해야 한다면&lt;/strong&gt; 적어도 &lt;code&gt;secret.yaml&lt;/code&gt;을 손으로 쓰는 대신 이렇게 줄일 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create secret tls my-tls &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; --cert&lt;span class="o"&gt;=&lt;/span&gt;tls.crt --key&lt;span class="o"&gt;=&lt;/span&gt;tls.key -n my-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-한-줄-요약"&gt;
 📝 한 줄 요약
 &lt;a class="heading-anchor" href="#-%ed%95%9c-%ec%a4%84-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;key·cert·CA·TLS는 한 신분증 시스템의 역할들입니다.&lt;/li&gt;
&lt;li&gt;쿠버네티스엔 PKI가 &lt;strong&gt;두 갈래&lt;/strong&gt; — 클러스터 내부(kubeadm, mTLS)와 앱/인그레스 TLS — 로 완전히 별개입니다.&lt;/li&gt;
&lt;li&gt;cert-manager는 &amp;ldquo;받은 인증서를 넣는&amp;rdquo; 게 아니라 &lt;strong&gt;&amp;ldquo;받는 행위(발급·갱신)를 자동화&amp;rdquo;&lt;/strong&gt; 하는 도구이며, 자동 연동 가능한 CA가 전제입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-kubeadm-인증서와-ingress-tls-인증서는-같은-건가요"&gt;
 Q. kubeadm 인증서와 Ingress TLS 인증서는 같은 건가요?
 &lt;a class="heading-anchor" href="#q-kubeadm-%ec%9d%b8%ec%a6%9d%ec%84%9c%ec%99%80-ingress-tls-%ec%9d%b8%ec%a6%9d%ec%84%9c%eb%8a%94-%ea%b0%99%ec%9d%80-%ea%b1%b4%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;아닙니다. kubeadm 인증서는 클러스터 컴포넌트끼리의 mTLS용(클러스터 자체 CA), Ingress/Gateway TLS는 외부 클라이언트용(공인/사내 CA)입니다. CA·목적·수명·관리 도구가 모두 다릅니다.&lt;/p&gt;
&lt;h3 id="q-cert-manager에-회사에서-받은-pfx를-넣으면-관리해주나요"&gt;
 Q. cert-manager에 회사에서 받은 .pfx를 넣으면 관리해주나요?
 &lt;a class="heading-anchor" href="#q-cert-manager%ec%97%90-%ed%9a%8c%ec%82%ac%ec%97%90%ec%84%9c-%eb%b0%9b%ec%9d%80-pfx%eb%a5%bc-%eb%84%a3%ec%9c%bc%eb%a9%b4-%ea%b4%80%eb%a6%ac%ed%95%b4%ec%a3%bc%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;그게 cert-manager의 방식이 아닙니다. cert-manager는 직접 키를 만들고 CA에 발급을 요청합니다. 회사 CA가 ACME/Vault 등으로 자동 연동되지 않고 순수 수동 발급만 한다면, cert-manager로 자동화할 수 없습니다.&lt;/p&gt;
&lt;h3 id="q-lets-encrypt-인증서-유효기간은-얼마인가요"&gt;
 Q. Let&amp;rsquo;s Encrypt 인증서 유효기간은 얼마인가요?
 &lt;a class="heading-anchor" href="#q-lets-encrypt-%ec%9d%b8%ec%a6%9d%ec%84%9c-%ec%9c%a0%ed%9a%a8%ea%b8%b0%ea%b0%84%ec%9d%80-%ec%96%bc%eb%a7%88%ec%9d%b8%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;90일입니다. cert-manager는 만료 전에 자동으로 갱신하므로 수동 개입이 필요 없습니다.&lt;/p&gt;
&lt;h3 id="q-http-01과-dns-01-챌린지의-차이는"&gt;
 Q. HTTP-01과 DNS-01 챌린지의 차이는?
 &lt;a class="heading-anchor" href="#q-http-01%ea%b3%bc-dns-01-%ec%b1%8c%eb%a6%b0%ec%a7%80%ec%9d%98-%ec%b0%a8%ec%9d%b4%eb%8a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;둘 다 도메인 소유를 증명하는 방식입니다. HTTP-01은 도메인의 특정 경로에 토큰을 노출(80 포트 필요), DNS-01은 DNS TXT 레코드로 증명합니다. 와일드카드 인증서(&lt;code&gt;*.example.com&lt;/code&gt;)는 DNS-01만 가능합니다.&lt;/p&gt;
&lt;h3 id="q-gateway-api에서-다른-네임스페이스의-인증서-secret을-참조하려면"&gt;
 Q. Gateway API에서 다른 네임스페이스의 인증서 Secret을 참조하려면?
 &lt;a class="heading-anchor" href="#q-gateway-api%ec%97%90%ec%84%9c-%eb%8b%a4%eb%a5%b8-%eb%84%a4%ec%9e%84%ec%8a%a4%ed%8e%98%ec%9d%b4%ec%8a%a4%ec%9d%98-%ec%9d%b8%ec%a6%9d%ec%84%9c-secret%ec%9d%84-%ec%b0%b8%ec%a1%b0%ed%95%98%eb%a0%a4%eb%a9%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;ReferenceGrant로 명시적 허용이 필요합니다. 크로스 네임스페이스 접근은 기본 차단되어 있어, 이 보안 기능을 통해 어떤 네임스페이스가 어떤 리소스를 참조할 수 있는지 통제합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📚 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cert-manager.io/docs/"&gt;cert-manager 공식 문서&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cert-manager.io/docs/configuration/acme/"&gt;cert-manager - ACME / Let&amp;rsquo;s Encrypt Issuer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/setup/best-practices/certificates/"&gt;Kubernetes Docs - PKI certificates and requirements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/"&gt;Kubernetes Docs - Certificate Management with kubeadm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gateway-api.sigs.k8s.io/guides/tls/"&gt;Gateway API - TLS Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-ingress-to-gateway-api-httproute/"&gt;관련 글: Gateway API (5편)&lt;/a&gt; · &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-http2-vs-h2c-tls/"&gt;h2 vs h2c (2편)&lt;/a&gt;
&lt;/content&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] 🌐 Ingress에서 Gateway API로: HTTPProxy vs HTTPRoute 비교</title><link>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-ingress-to-gateway-api-httproute/</link><pubDate>Thu, 04 Jun 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-ingress-to-gateway-api-httproute/</guid><description>&lt;p&gt;쿠버네티스에서 앱 트래픽을 라우팅하는 방법은 Ingress로 시작해 벤더별 CRD를 거쳐 표준 &lt;strong&gt;Gateway API&lt;/strong&gt;(HTTPRoute·GRPCRoute)로 수렴하고 있습니다. 이 글에서는 그 진화의 흐름과 함께, &lt;strong&gt;설정(API)과 엔진(Envoy)이 다른 층&lt;/strong&gt;이라는 핵심 구분, 그리고 Contour 전용 &lt;strong&gt;HTTPProxy&lt;/strong&gt; vs 표준 &lt;strong&gt;HTTPRoute&lt;/strong&gt;의 차이를 실무 관점에서 정리합니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;이 시리즈는&lt;/strong&gt; 쿠버네티스 gRPC 삽질에서 출발해 HTTP/2·TLS·로드밸런서·Gateway API·인증서까지 풀어가는 기록입니다. 이번 5편은 &lt;strong&gt;Ingress → Gateway API&lt;/strong&gt; 편입니다. 앞선 &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-l4-l7-load-balancing/"&gt;3편(L4 vs L7)&lt;/a&gt;, &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-traffic-control-plane-data-plane/"&gt;4편(트래픽 구조)&lt;/a&gt;을 먼저 보면 좋습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-먼저-api설정와-엔진envoy은-다른-층이다"&gt;
 🧩 먼저: API(설정)와 엔진(Envoy)은 다른 층이다
 &lt;a class="heading-anchor" href="#-%eb%a8%bc%ec%a0%80-api%ec%84%a4%ec%a0%95%ec%99%80-%ec%97%94%ec%a7%84envoy%ec%9d%80-%eb%8b%a4%eb%a5%b8-%ec%b8%b5%ec%9d%b4%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Ingress·HTTPProxy·Gateway API는 &amp;ldquo;설정(API)&amp;ldquo;이고, Envoy·nginx는 그 설정을 실행하는 &amp;ldquo;엔진&amp;quot;입니다.&lt;/strong&gt; 이걸 안 나누면 &amp;ldquo;Gateway → Envoy → HTTPRoute&amp;rdquo; 식으로 머릿속에서 다 섞입니다. 두 층을 분리합시다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;API 층 (내가 쓰는 설정)&lt;/strong&gt;: Ingress, HTTPProxy, Gateway API(Gateway + HTTPRoute + GRPCRoute). &amp;ldquo;이렇게 라우팅해라&amp;quot;라고 적는 문서입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;데이터 플레인 엔진 (실제로 트래픽을 처리하는 것)&lt;/strong&gt;: Envoy(또는 nginx). 내가 적은 설정대로 진짜 패킷을 나르는 프록시입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 Envoy는 API가 아니라 &lt;strong&gt;엔진&lt;/strong&gt;입니다. Contour도, Istio도, Envoy Gateway도 전부 그 밑에서 Envoy를 엔진으로 씁니다. 그러니 &amp;ldquo;Gateway API라는 설정을 Envoy라는 엔진이 실행한다&amp;quot;가 올바른 그림입니다. Envoy를 HTTPRoute와 같은 줄에 두면 안 됩니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-진화의-흐름"&gt;
 🧬 진화의 흐름
 &lt;a class="heading-anchor" href="#-%ec%a7%84%ed%99%94%ec%9d%98-%ed%9d%90%eb%a6%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;쿠버네티스 라우팅 API는 3세대를 거쳐 진화했습니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;세대&lt;/th&gt;
					&lt;th&gt;대표&lt;/th&gt;
					&lt;th&gt;특징&lt;/th&gt;
					&lt;th&gt;한계&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;1세대&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Ingress (빌트인)&lt;/td&gt;
					&lt;td&gt;1.19(2020) GA, HTTP 노출 표준&lt;/td&gt;
					&lt;td&gt;너무 단순 → 애너테이션 남발, 파편화&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;2세대&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;벤더 CRD&lt;/td&gt;
					&lt;td&gt;Contour &lt;strong&gt;HTTPProxy&lt;/strong&gt;, Istio &lt;strong&gt;VirtualService&lt;/strong&gt;, Traefik IngressRoute&lt;/td&gt;
					&lt;td&gt;기능은 풍부하나 &lt;strong&gt;벤더 락인&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;3세대&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Gateway API&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;GatewayClass·Gateway·HTTPRoute·GRPCRoute&lt;/td&gt;
					&lt;td&gt;벤더 중립, 이식성 높음 (표준)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="1세대-ingress-원조-빌트인"&gt;
 1세대: Ingress (원조, 빌트인)
 &lt;a class="heading-anchor" href="#1%ec%84%b8%eb%8c%80-ingress-%ec%9b%90%ec%a1%b0-%eb%b9%8c%ed%8a%b8%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Ingress API는 쿠버네티스 1.19(2020)에서 GA가 된 기능으로, 오랫동안 HTTP 서비스를 노출하는 표준이었습니다. 하지만 너무 단순해서 컨트롤러마다 부족한 기능을 &lt;strong&gt;애너테이션으로 메우기&lt;/strong&gt; 시작했고, 설정이 파편화되고 이식성이 떨어졌습니다.&lt;/p&gt;
&lt;h3 id="2세대-벤더별-crd"&gt;
 2세대: 벤더별 CRD
 &lt;a class="heading-anchor" href="#2%ec%84%b8%eb%8c%80-%eb%b2%a4%eb%8d%94%eb%b3%84-crd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;벤더들이 각자 풍부한 CRD를 만들어 한계를 메웠습니다 — Contour의 &lt;strong&gt;HTTPProxy&lt;/strong&gt;, Istio의 &lt;strong&gt;VirtualService&lt;/strong&gt;, Traefik의 IngressRoute처럼요. 기능은 좋았지만 전부 &lt;strong&gt;벤더 락인&lt;/strong&gt;이었습니다.&lt;/p&gt;
&lt;h3 id="3세대-gateway-api-표준"&gt;
 3세대: Gateway API (표준)
 &lt;a class="heading-anchor" href="#3%ec%84%b8%eb%8c%80-gateway-api-%ed%91%9c%ec%a4%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;그 교훈을 모아 커뮤니티가 표준으로 수렴한 게 Gateway API입니다. GatewayClass·Gateway·HTTPRoute·GRPCRoute 같은 타입화된 리소스로, 벤더 중립적이고 이식성이 높습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-httpproxy-vs-httproute"&gt;
 ⚔️ HTTPProxy vs HTTPRoute
 &lt;a class="heading-anchor" href="#-httpproxy-vs-httproute" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;HTTPProxy는 Contour 전용 CRD이고, HTTPRoute는 표준 Gateway API의 일부입니다.&lt;/strong&gt; 둘 다 L7 라우팅을 하지만 출신이 다릅니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;구분&lt;/th&gt;
					&lt;th&gt;HTTPProxy&lt;/th&gt;
					&lt;th&gt;HTTPRoute&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;출신&lt;/td&gt;
					&lt;td&gt;Contour 전용 CRD (벤더 독자)&lt;/td&gt;
					&lt;td&gt;Gateway API 표준&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;동작 범위&lt;/td&gt;
					&lt;td&gt;Contour에서만&lt;/td&gt;
					&lt;td&gt;표준 구현 게이트웨이 어디서나&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;성숙도&lt;/td&gt;
					&lt;td&gt;풍부·성숙&lt;/td&gt;
					&lt;td&gt;표준, 빠르게 성숙 중&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;gRPC 전용&lt;/td&gt;
					&lt;td&gt;(HTTPProxy 내 설정)&lt;/td&gt;
					&lt;td&gt;표준 &lt;strong&gt;GRPCRoute&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;이식성&lt;/td&gt;
					&lt;td&gt;낮음(벤더 종속)&lt;/td&gt;
					&lt;td&gt;높음&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;한 줄로: &lt;strong&gt;&amp;ldquo;한 벤더 전용이지만 성숙(HTTPProxy)&amp;rdquo; vs &amp;ldquo;표준이라 이식성 높음(HTTPRoute)&amp;rdquo;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;gRPC 라우팅을 표준으로 작성하면 다음과 같습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# GRPCRoute (Gateway API 표준)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;GRPCRoute&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-grpc-route&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parentRefs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-gateway &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 플랫폼팀이 만든 Gateway 참조&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;helloworld.Greeter &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# gRPC 서비스명으로 매칭&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;backendRefs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-grpc-svc&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-역할-분리--gateway-api의-핵심-장점"&gt;
 🤝 역할 분리 — Gateway API의 핵심 장점
 &lt;a class="heading-anchor" href="#-%ec%97%ad%ed%95%a0-%eb%b6%84%eb%a6%ac--gateway-api%ec%9d%98-%ed%95%b5%ec%8b%ac-%ec%9e%a5%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Gateway API는 플랫폼팀(인프라)과 앱팀(라우팅)의 책임을 공식적으로 나눕니다.&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;리소스&lt;/th&gt;
					&lt;th&gt;소유 주체&lt;/th&gt;
					&lt;th&gt;담당&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;GatewayClass / Gateway&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;플랫폼·인프라 팀&lt;/td&gt;
					&lt;td&gt;리스너·포트·TLS&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;HTTPRoute / GRPCRoute&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;앱·프로젝트 팀&lt;/td&gt;
					&lt;td&gt;라우팅 규칙&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;즉 플랫폼팀이 인프라(Gateway)를, 앱팀이 라우트를 따로 소유하는 구조입니다. 이 &amp;ldquo;관심사의 분리(separation of concerns)&amp;ldquo;가 핵심 이점입니다. (다음 6편에서 TLS 인증서를 이 구조로 중앙화하는 걸 다룹니다.)&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-왜-istio-문서랑-비슷하게-느껴질까"&gt;
 🕸️ 왜 Istio 문서랑 비슷하게 느껴질까
 &lt;a class="heading-anchor" href="#-%ec%99%9c-istio-%eb%ac%b8%ec%84%9c%eb%9e%91-%eb%b9%84%ec%8a%b7%ed%95%98%ea%b2%8c-%eb%8a%90%ea%bb%b4%ec%a7%88%ea%b9%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Istio의 자체 CRD(VirtualService·Gateway·DestinationRule)가 Gateway API 설계에 큰 영향을 줬기 때문입니다.&lt;/strong&gt; Istio는 Envoy 기반 서비스 메시이고, 지금은 Istio도 Gateway API를 지원합니다. 그래서 &amp;ldquo;어디서 본 것 같다&amp;quot;는 감이 정확합니다.&lt;/p&gt;
&lt;p&gt;단, 결이 하나 다릅니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Gateway API / Ingress&lt;/strong&gt; = &lt;strong&gt;north-south&lt;/strong&gt; 트래픽 (외부 ↔ 클러스터)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;서비스 메시&lt;/strong&gt; = &lt;strong&gt;east-west&lt;/strong&gt; 트래픽 (서비스 ↔ 서비스)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;둘은 경쟁이 아니라 보완 관계입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-2026년-현재-상태"&gt;
 📅 2026년 현재 상태
 &lt;a class="heading-anchor" href="#-2026%eb%85%84-%ed%98%84%ec%9e%ac-%ec%83%81%ed%83%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;빠르게 변하는 영역이라 작성 시점(2026년 6월) 기준이며, 최신 공식 문서 확인을 권장합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Gateway API&lt;/strong&gt;: 2023년 10월 v1.0 GA에 도달했고, 2026년 들어 &lt;strong&gt;v1.5&lt;/strong&gt;까지 릴리스되며 여러 기능이 Standard(Stable)로 승격된 성숙·프로덕션 레디 상태입니다. SIG Network의 공식 권고는 Gateway API로의 이전입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ingress는 사라지지 않습니다.&lt;/strong&gt; Ingress API 자체는 폐기·제거 계획이 없고, 다만 더 이상 적극 개발되지 않는 &amp;ldquo;feature-frozen&amp;rdquo; 상태입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;⚠️ 주의 — ingress-nginx 은퇴&lt;/strong&gt;: 가장 널리 쓰이던 커뮤니티 ingress-nginx 컨트롤러는 &lt;strong&gt;2026년 3월 retired&lt;/strong&gt; 되었습니다. 저장소는 &lt;code&gt;kubernetes-retired&lt;/code&gt;로 옮겨져 read-only가 되었고, 더 이상 릴리스·버그픽스·&lt;strong&gt;CVE 패치가 없습니다.&lt;/strong&gt; 기존 배포는 계속 동작하지만 신규 보안 취약점은 패치되지 않으므로 마이그레이션이 권장됩니다. (이는 커뮤니티 프로젝트 얘기이며, F5/NGINX의 상용 컨트롤러는 별개입니다.) 이전을 돕는 공식 도구 &lt;strong&gt;ingress2gateway&lt;/strong&gt;도 제공됩니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;표준이라 구현체가 여럿&lt;/strong&gt;입니다. 완전 적합 구현으로 Envoy Gateway·Istio·NGINX Gateway Fabric·Traefik·Cilium·kgateway 등이 있고, Contour·AWS LB Controller·GKE Gateway·Kong 등은 부분 적합입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-실무-권장"&gt;
 🎯 실무 권장
 &lt;a class="heading-anchor" href="#-%ec%8b%a4%eb%ac%b4-%ea%b6%8c%ec%9e%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;신규로 시작한다면 Gateway API가 자연스럽고, 잘 돌아가는 Ingress 설정이 있다면 구체적인 한계에 부딪힐 때 옮기면 됩니다. 1편에서 HTTPProxy를 썼더라도 당장 바꿀 필요는 없지만, &lt;strong&gt;신규 설계·멀티 벤더·이식성&lt;/strong&gt;이 중요하면 HTTPRoute/GRPCRoute 방향이 미래지향적입니다. 다만 ingress-nginx를 쓰고 있다면 은퇴(EOL)로 인해 이전이 사실상 필수입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-한-줄-요약"&gt;
 📝 한 줄 요약
 &lt;a class="heading-anchor" href="#-%ed%95%9c-%ec%a4%84-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ingress(원조, 애너테이션 한계) → 벤더 CRD(HTTPProxy 등) → 표준 Gateway API(HTTPRoute·GRPCRoute)로 진화 중입니다.&lt;/li&gt;
&lt;li&gt;HTTPProxy는 Contour 전용, HTTPRoute는 표준이라 이식성이 높습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API(설정)와 Envoy(엔진)는 다른 층&lt;/strong&gt;입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-httpproxy와-httproute-중-무엇을-써야-하나요"&gt;
 Q. HTTPProxy와 HTTPRoute 중 무엇을 써야 하나요?
 &lt;a class="heading-anchor" href="#q-httpproxy%ec%99%80-httproute-%ec%a4%91-%eb%ac%b4%ec%97%87%ec%9d%84-%ec%8d%a8%ec%95%bc-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;이식성·표준·멀티 벤더가 중요하면 HTTPRoute(Gateway API)를 권장합니다. 이미 Contour와 HTTPProxy로 잘 돌아가고 있다면 당장 바꿀 필요는 없지만, 신규 설계는 표준 방향이 미래지향적입니다.&lt;/p&gt;
&lt;h3 id="q-ingress는-이제-안-쓰나요"&gt;
 Q. Ingress는 이제 안 쓰나요?
 &lt;a class="heading-anchor" href="#q-ingress%eb%8a%94-%ec%9d%b4%ec%a0%9c-%ec%95%88-%ec%93%b0%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Ingress API 자체는 제거 계획이 없는 feature-frozen 상태로 계속 동작합니다. 다만 커뮤니티 ingress-nginx 컨트롤러가 2026년 3월 은퇴해 CVE 패치가 중단되었으므로, 해당 컨트롤러 사용자는 마이그레이션이 필요합니다.&lt;/p&gt;
&lt;h3 id="q-gateway-api와-서비스-메시istio는-무엇이-다른가요"&gt;
 Q. Gateway API와 서비스 메시(Istio)는 무엇이 다른가요?
 &lt;a class="heading-anchor" href="#q-gateway-api%ec%99%80-%ec%84%9c%eb%b9%84%ec%8a%a4-%eb%a9%94%ec%8b%9cistio%eb%8a%94-%eb%ac%b4%ec%97%87%ec%9d%b4-%eb%8b%a4%eb%a5%b8%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Gateway API는 north-south(외부↔클러스터) 트래픽을, 서비스 메시는 east-west(서비스↔서비스) 트래픽을 주로 다룹니다. 경쟁이 아니라 보완 관계이며, Istio는 Gateway API도 지원합니다.&lt;/p&gt;
&lt;h3 id="q-envoy와-gateway-api의-관계는"&gt;
 Q. Envoy와 Gateway API의 관계는?
 &lt;a class="heading-anchor" href="#q-envoy%ec%99%80-gateway-api%ec%9d%98-%ea%b4%80%ea%b3%84%eb%8a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Envoy는 트래픽을 실제로 처리하는 데이터 플레인 &amp;ldquo;엔진&amp;quot;이고, Gateway API는 &amp;ldquo;이렇게 라우팅하라&amp;quot;를 적는 설정(API)입니다. Contour·Istio·Envoy Gateway 등이 Gateway API 설정을 받아 Envoy 엔진으로 실행합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📚 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/blog/2023/10/31/gateway-api-ga/"&gt;Gateway API v1.0: GA Release (Kubernetes Blog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/blog/2026/04/21/gateway-api-v1-5/"&gt;Gateway API v1.5: Moving features to Stable (Kubernetes Blog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/blog/2025/11/11/ingress-nginx-retirement/"&gt;Ingress NGINX Retirement: What You Need to Know (Kubernetes Blog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gateway-api.sigs.k8s.io/implementations/"&gt;Gateway API 공식 문서 - Implementations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes-sigs/ingress2gateway"&gt;ingress2gateway - 마이그레이션 도구&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-traffic-control-plane-data-plane/"&gt;관련 글: 트래픽 구조 (4편)&lt;/a&gt; · &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-l4-l7-load-balancing/"&gt;L4 vs L7 (3편)&lt;/a&gt;
&lt;/content&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] 🚦 쿠버네티스 트래픽 구조: 로드밸런서는 어디에 들어갈까</title><link>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-traffic-control-plane-data-plane/</link><pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-traffic-control-plane-data-plane/</guid><description>&lt;p&gt;쿠버네티스에서 로드밸런서가 정확히 어디에 들어가는지 헷갈리면 트래픽 구조 전체가 안 그려집니다. 이 글에서는 LB가 들어갈 **두 자리(마스터 API 서버 앞, 앱 인그레스 앞)**를 구분하고, &amp;ldquo;마스터가 여러 대면 LB가 필요 없다&amp;quot;는 흔한 오해를 정정하며, &lt;strong&gt;앱 요청은 마스터를 거치지 않는다&lt;/strong&gt;는 컨트롤 플레인 vs 데이터 플레인의 핵심 구조를 정리합니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;이 시리즈는&lt;/strong&gt; 쿠버네티스 gRPC 삽질에서 출발해 HTTP/2·TLS·로드밸런서·Gateway API·인증서까지 풀어가는 기록입니다. 이번 4편은 &lt;strong&gt;쿠버네티스 트래픽 구조&lt;/strong&gt; 편입니다. 앞선 &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-dotnet-http2-tls-troubleshooting/"&gt;1편(문제와 해결)&lt;/a&gt;, &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-http2-vs-h2c-tls/"&gt;2편(h2 vs h2c)&lt;/a&gt;, &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-l4-l7-load-balancing/"&gt;3편(L4 vs L7)&lt;/a&gt;을 먼저 보면 좋습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-로드밸런서가-들어갈-두-자리"&gt;
 📍 로드밸런서가 들어갈 두 자리
 &lt;a class="heading-anchor" href="#-%eb%a1%9c%eb%93%9c%eb%b0%b8%eb%9f%b0%ec%84%9c%ea%b0%80-%eb%93%a4%ec%96%b4%ea%b0%88-%eb%91%90-%ec%9e%90%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;쿠버네티스에서 로드밸런서가 들어갈 자리는 두 군데입니다.&lt;/strong&gt; 이 둘을 분리하는 게 이번 편의 전부입니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;자리&lt;/th&gt;
					&lt;th&gt;위치&lt;/th&gt;
					&lt;th&gt;다루는 트래픽&lt;/th&gt;
					&lt;th&gt;사용 LB&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;자리 ①&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;마스터(API 서버) 앞&lt;/td&gt;
					&lt;td&gt;관리 트래픽 (kubectl·워커노드 → 마스터)&lt;/td&gt;
					&lt;td&gt;외부 L4 (HAProxy, kube-vip)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;자리 ②&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;앱(인그레스) 앞&lt;/td&gt;
					&lt;td&gt;서비스 트래픽 (외부 사용자 → Pod)&lt;/td&gt;
					&lt;td&gt;인그레스 컨트롤러 L7 (nginx, Contour)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;이 둘은 목적도, 위치도, 다루는 트래픽도 완전히 다릅니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-자리--인그레스--nginxcontourhaproxy는-서로-대안"&gt;
 🚪 자리 ②: 인그레스 — nginx·Contour·HAProxy는 서로 대안
 &lt;a class="heading-anchor" href="#-%ec%9e%90%eb%a6%ac--%ec%9d%b8%ea%b7%b8%eb%a0%88%ec%8a%a4--nginxcontourhaproxy%eb%8a%94-%ec%84%9c%eb%a1%9c-%eb%8c%80%ec%95%88" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;앱 트래픽이 들어오는 입구이며, 3편에서 본 L7 로드밸런서가 여기 들어갑니다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;nginx·Contour·HAProxy(인그레스 컨트롤러)·Envoy Gateway 등은 &lt;strong&gt;같은 자리를 놓고 경쟁하는 대안들&lt;/strong&gt;입니다. 위로 쌓는 게 아니라 &lt;strong&gt;하나만 고르면 됩니다.&lt;/strong&gt; nginx나 Contour를 인그레스 컨트롤러로 쓰면, 그 역할에서 HAProxy는 따로 필요 없습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-자리--마스터-앞-lb--흔한-오해"&gt;
 🧭 자리 ①: 마스터 앞 LB — 흔한 오해
 &lt;a class="heading-anchor" href="#-%ec%9e%90%eb%a6%ac--%eb%a7%88%ec%8a%a4%ed%84%b0-%ec%95%9e-lb--%ed%9d%94%ed%95%9c-%ec%98%a4%ed%95%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;❓ &lt;strong&gt;흔한 오해&lt;/strong&gt;: &amp;ldquo;마스터가 여러 대면 알아서 분산하니까, LB는 필요 없는 거 아냐?&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;사실은 정반대입니다. 마스터가 여러 대인 것이 곧 LB가 필요한 이유입니다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;API 서버들은 서로 클라이언트 요청을 나눠주지 않습니다. 마스터 3대 = 독립적으로 도는 API 서버 3개이고, &amp;ldquo;대표 창구&amp;quot;가 내장돼 있지 않습니다. LB가 없으면 kubectl이 마스터 한 대의 IP를 콕 찍어야 하고, 그 마스터가 죽으면 나머지가 멀쩡해도 접속이 끊깁니다. HA(고가용성)의 의미가 사라집니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl ──▶ LB ──┬─ master1 (API서버)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; ├─ master2 (API서버) ← 한 대 죽어도 LB가 다른 데로
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; └─ master3 (API서버)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이 자리엔 인그레스 컨트롤러(nginx/Contour)를 &lt;strong&gt;못 씁니다.&lt;/strong&gt; 그들은 클러스터 &lt;em&gt;안&lt;/em&gt;에서 Pod로 도는데, 마스터 앞 LB는 클러스터가 떠 있기 &lt;em&gt;전에&lt;/em&gt; &lt;em&gt;바깥&lt;/em&gt;에 있어야 하기 때문입니다(닭-달걀 문제). 그래서 자리 ①은 HAProxy·kube-vip 같은 &lt;strong&gt;외부 L4 LB&lt;/strong&gt;가 필요합니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: 마스터가 1대인 보통의 테스트/홈랩 구성이면 이 자리는 아예 필요 없습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-그럼-마스터들끼리-알아서-하는-건-뭘까"&gt;
 🔄 그럼 마스터들끼리 &amp;ldquo;알아서&amp;rdquo; 하는 건 뭘까
 &lt;a class="heading-anchor" href="#-%ea%b7%b8%eb%9f%bc-%eb%a7%88%ec%8a%a4%ed%84%b0%eb%93%a4%eb%81%bc%eb%a6%ac-%ec%95%8c%ec%95%84%ec%84%9c-%ed%95%98%eb%8a%94-%ea%b1%b4-%eb%ad%98%ea%b9%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;마스터들이 협조하긴 하지만, 그 협조는 상태 공유이지 요청 분배가 아닙니다.&lt;/strong&gt; 오해의 뿌리가 여기 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;etcd&lt;/strong&gt;라는 공동 저장소에 클러스터 상태를 함께 보관하고, 내부적으로 리더를 뽑아 동기화합니다.&lt;/li&gt;
&lt;li&gt;일부 컴포넌트(스케줄러, 컨트롤러 매니저 등)도 리더를 선출해 하나만 동작합니다(leader election).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;하지만 이건 전부 &amp;ldquo;데이터를 맞추는&amp;rdquo; 얘기입니다. &amp;ldquo;들어온 클라이언트 요청을 창구에서 나눠주는&amp;rdquo; 일은 아닙니다. 그 창구 분배가 바로 LB의 몫입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-컨트롤-플레인-vs-데이터-플레인--앱-요청은-마스터를-안-거친다"&gt;
 🧠 컨트롤 플레인 vs 데이터 플레인 — 앱 요청은 마스터를 안 거친다
 &lt;a class="heading-anchor" href="#-%ec%bb%a8%ed%8a%b8%eb%a1%a4-%ed%94%8c%eb%a0%88%ec%9d%b8-vs-%eb%8d%b0%ec%9d%b4%ed%84%b0-%ed%94%8c%eb%a0%88%ec%9d%b8--%ec%95%b1-%ec%9a%94%ec%b2%ad%ec%9d%80-%eb%a7%88%ec%8a%a4%ed%84%b0%eb%a5%bc-%ec%95%88-%ea%b1%b0%ec%b9%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;가장 중요한 구조적 사실은 앱 요청이 마스터 서버를 통과하지 않는다는 것입니다.&lt;/strong&gt; 쿠버네티스엔 분리된 두 경로가 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;[관리 경로 — 마스터 사용 (컨트롤 플레인)]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl / kubelet ──▶ 마스터(API서버)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;[앱 요청 경로 — 마스터 안 거침 (데이터 플레인)]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;클라이언트 ──▶ 인그레스(nginx/Contour) ──▶ Service ──▶ Pod&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;마스터는 &amp;ldquo;어떤 Pod가 있는지&amp;rdquo; 정보를 &lt;strong&gt;관리&lt;/strong&gt;하고 인그레스·노드에 &lt;strong&gt;미리 뿌려둘&lt;/strong&gt; 뿐, 요청을 직접 받아 전달하지 않습니다.&lt;/p&gt;
&lt;h3 id="건물-관리실-비유"&gt;
 건물 관리실 비유
 &lt;a class="heading-anchor" href="#%ea%b1%b4%eb%ac%bc-%ea%b4%80%eb%a6%ac%ec%8b%a4-%eb%b9%84%ec%9c%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;마스터 = 건물 관리실.&lt;/strong&gt; 누가 몇 호에 사는지 명부를 관리하고, 입주자가 오고 가면(Pod 생성·삭제) 명부를 갱신합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;인그레스 = 로비의 안내 표지판.&lt;/strong&gt; 관리실이 갱신해둔 정보로 채워져 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;방문자(요청)&lt;/strong&gt; 는 관리실에 들르지 않습니다. 표지판만 보고 곧장 해당 호실(Pod)로 갑니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그래서 마스터가 잠깐 바빠도, 이미 떠 있는 앱들은 멀쩡히 요청을 처리합니다. 마스터는 &amp;ldquo;정보를 나눠주는 두뇌&amp;quot;이지 &amp;ldquo;요청을 나눠주는 창구&amp;quot;가 아닙니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;📌 1편에서 &lt;code&gt;port-forward&lt;/code&gt;로 앱을 격리 테스트했는데, 이건 예외입니다. port-forward 같은 디버그 통로는 관리 경로(API 서버)를 거치는 특수 케이스입니다. &lt;strong&gt;일반 서비스 트래픽&lt;/strong&gt;이 마스터를 안 거친다는 뜻입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-덤-ingress와-egress"&gt;
 ↔️ 덤: Ingress와 Egress
 &lt;a class="heading-anchor" href="#-%eb%8d%a4-ingress%ec%99%80-egress" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;같은 맥락에서 자주 나오는 짝이 &lt;strong&gt;Ingress / Egress&lt;/strong&gt;이며, 트래픽의 방향을 가리킵니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;구분&lt;/th&gt;
					&lt;th&gt;방향&lt;/th&gt;
					&lt;th&gt;예시&lt;/th&gt;
					&lt;th&gt;다루는 방법&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Ingress&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;외부 → 클러스터 안&lt;/td&gt;
					&lt;td&gt;사용자가 앱에 접속&lt;/td&gt;
					&lt;td&gt;Ingress 객체, Gateway API&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Egress&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;클러스터 안 → 외부&lt;/td&gt;
					&lt;td&gt;Pod가 외부 API·DB 호출&lt;/td&gt;
					&lt;td&gt;NetworkPolicy egress, Egress Gateway&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Ingress는 정식 객체가 있지만 &lt;code&gt;Egress&lt;/code&gt;라는 단일 객체는 없고, NetworkPolicy의 egress 규칙이나 Egress Gateway로 다룹니다. 홈랩 테스트 수준에선 보통 egress를 따로 신경 쓰지 않아도 됩니다(Pod는 기본적으로 외부로 자유롭게 나갑니다).&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-한-줄-요약"&gt;
 📝 한 줄 요약
 &lt;a class="heading-anchor" href="#-%ed%95%9c-%ec%a4%84-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;LB가 들어갈 자리는 둘 — &lt;strong&gt;마스터 앞(관리용, 외부 L4)&lt;/strong&gt; 과 **앱 앞(서비스용, 인그레스 L7)**입니다.&lt;/li&gt;
&lt;li&gt;마스터가 여러 대면 LB가 &lt;em&gt;더&lt;/em&gt; 필요하고(오해 정정), &lt;strong&gt;앱 요청은 마스터를 거치지 않습니다&lt;/strong&gt;(컨트롤 플레인 ≠ 데이터 플레인).&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-마스터가-3대면-로드밸런서-없이도-ha가-되나요"&gt;
 Q. 마스터가 3대면 로드밸런서 없이도 HA가 되나요?
 &lt;a class="heading-anchor" href="#q-%eb%a7%88%ec%8a%a4%ed%84%b0%ea%b0%80-3%eb%8c%80%eb%a9%b4-%eb%a1%9c%eb%93%9c%eb%b0%b8%eb%9f%b0%ec%84%9c-%ec%97%86%ec%9d%b4%eb%8f%84-ha%ea%b0%80-%eb%90%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;안 됩니다. API 서버는 서로 요청을 분배하지 않으므로 kubectl·워커노드가 접속할 &amp;ldquo;대표 창구&amp;quot;인 LB가 필요합니다. LB가 없으면 특정 마스터 IP에 묶여 그 마스터가 죽을 때 접속이 끊깁니다.&lt;/p&gt;
&lt;h3 id="q-인그레스-컨트롤러를-마스터-앞-lb로-쓸-수-있나요"&gt;
 Q. 인그레스 컨트롤러를 마스터 앞 LB로 쓸 수 있나요?
 &lt;a class="heading-anchor" href="#q-%ec%9d%b8%ea%b7%b8%eb%a0%88%ec%8a%a4-%ec%bb%a8%ed%8a%b8%eb%a1%a4%eb%9f%ac%eb%a5%bc-%eb%a7%88%ec%8a%a4%ed%84%b0-%ec%95%9e-lb%eb%a1%9c-%ec%93%b8-%ec%88%98-%ec%9e%88%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;없습니다. 인그레스 컨트롤러는 클러스터 안에서 Pod로 동작하므로, 클러스터가 뜨기 전·바깥에 있어야 하는 마스터 앞 LB 역할은 못 합니다. 그 자리엔 HAProxy·kube-vip 같은 외부 L4 LB가 필요합니다.&lt;/p&gt;
&lt;h3 id="q-앱-요청이-느려지면-마스터api-서버-부하가-원인인가요"&gt;
 Q. 앱 요청이 느려지면 마스터(API 서버) 부하가 원인인가요?
 &lt;a class="heading-anchor" href="#q-%ec%95%b1-%ec%9a%94%ec%b2%ad%ec%9d%b4-%eb%8a%90%eb%a0%a4%ec%a7%80%eb%a9%b4-%eb%a7%88%ec%8a%a4%ed%84%b0api-%ec%84%9c%eb%b2%84-%eb%b6%80%ed%95%98%ea%b0%80-%ec%9b%90%ec%9d%b8%ec%9d%b8%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;대부분 아닙니다. 일반 서비스 트래픽은 인그레스 → Service → Pod 경로로 흐르며 마스터를 거치지 않습니다. 마스터는 관리(컨트롤 플레인) 트래픽만 처리합니다.&lt;/p&gt;
&lt;h3 id="q-nginx-contour-haproxy-인그레스-컨트롤러를-동시에-써야-하나요"&gt;
 Q. nginx, Contour, HAProxy 인그레스 컨트롤러를 동시에 써야 하나요?
 &lt;a class="heading-anchor" href="#q-nginx-contour-haproxy-%ec%9d%b8%ea%b7%b8%eb%a0%88%ec%8a%a4-%ec%bb%a8%ed%8a%b8%eb%a1%a4%eb%9f%ac%eb%a5%bc-%eb%8f%99%ec%8b%9c%ec%97%90-%ec%8d%a8%ec%95%bc-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;아닙니다. 같은 자리(앱 앞)를 놓고 경쟁하는 대안이라 하나만 고르면 됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📚 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/overview/components/"&gt;Kubernetes Docs - Kubernetes Components(Control Plane / Node)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/"&gt;Kubernetes Docs - Creating Highly Available Clusters with kubeadm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/services-networking/ingress/"&gt;Kubernetes Docs - Ingress&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kube-vip.io/"&gt;kube-vip - Kubernetes Control Plane LB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-l4-l7-load-balancing/"&gt;관련 글: L4 vs L7 로드밸런서 (3편)&lt;/a&gt; · &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-http2-vs-h2c-tls/"&gt;HTTP/2는 TLS가 아니다 (2편)&lt;/a&gt;
&lt;/content&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] ⚖️ L4 vs L7 로드밸런서와 gRPC 로드밸런싱의 함정</title><link>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-l4-l7-load-balancing/</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-l4-l7-load-balancing/</guid><description>&lt;p&gt;쿠버네티스에서 gRPC를 운영하다 보면 &amp;ldquo;L7 지원 되냐&amp;quot;는 질문을 반복해서 듣게 됩니다. 이 글에서는 L4와 L7 로드밸런서의 차이를 편지 비유로 정리하고, &lt;strong&gt;gRPC가 HTTP/2 연결 다중화 때문에 L4 로드밸런서에서 한 Pod로만 트래픽이 쏠리는 함정&lt;/strong&gt;과 그래서 L7이 사실상 필수인 이유를 다룹니다. 또한 L4/L7이 버전도 하드웨어도 아닌 소프트웨어 동작 방식이라는 점도 짚습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;이 시리즈는&lt;/strong&gt; 쿠버네티스에 gRPC를 올리다 막힌 삽질에서 출발해 HTTP/2·TLS·로드밸런서·Gateway API·인증서까지 풀어가는 기록입니다. 이번 3편은 &lt;strong&gt;L4 vs L7과 로드밸런서&lt;/strong&gt; 편입니다. 앞선 &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-dotnet-http2-tls-troubleshooting/"&gt;1편(문제와 해결)&lt;/a&gt;, &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-http2-vs-h2c-tls/"&gt;2편(h2 vs h2c)&lt;/a&gt;을 먼저 보면 이해가 빠릅니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-l4-vs-l7--편지를-여느냐-안-여느냐"&gt;
 ✉️ L4 vs L7 — 편지를 여느냐, 안 여느냐
 &lt;a class="heading-anchor" href="#-l4-vs-l7--%ed%8e%b8%ec%a7%80%eb%a5%bc-%ec%97%ac%eb%8a%90%eb%83%90-%ec%95%88-%ec%97%ac%eb%8a%90%eb%83%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;L4는 편지를 안 뜯고 겉봉의 주소(IP:포트)만 보고 전달하고, L7은 편지를 열어 내용까지 읽고 판단합니다.&lt;/strong&gt; 2편의 편지 비유를 그대로 이어가면 깔끔합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;L4&lt;/strong&gt; = 편지를 &lt;strong&gt;안 뜯고&lt;/strong&gt;, 겉봉의 &lt;strong&gt;주소(IP:포트)만 보고&lt;/strong&gt; 전달합니다. 안에 뭐가 들었는지는 신경 쓰지 않습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;L7&lt;/strong&gt; = 편지를 &lt;strong&gt;열어서&lt;/strong&gt; 내용까지 읽고 판단합니다. 경로·호스트·헤더·gRPC 메서드를 보고 라우팅하고, TLS를 풀고, 헤더를 고치기도 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;용어로 풀면 L4는 전송 계층(TCP/포트), L7은 애플리케이션 계층(HTTP)입니다. 하지만 &amp;ldquo;겉봉만 보냐 / 내용까지 보냐&amp;quot;로 기억하는 게 훨씬 쓸모 있습니다.&lt;/p&gt;
&lt;p&gt;이 구분은 1편과도 연결됩니다. 게이트웨이가 했던 일(TLS 풀기, &lt;code&gt;:scheme&lt;/code&gt; 헤더 확인·수정, gRPC 라우팅)은 전부 &amp;ldquo;내용을 읽어야 가능한 일&amp;rdquo; = &lt;strong&gt;L7&lt;/strong&gt;이었습니다. h2c 미스매치 같은 문제도 L7이라서 생긴 것입니다. 순수 L4였다면 내용을 안 읽으니 그런 문제 자체가 없습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-각각의-장단점"&gt;
 ⚙️ 각각의 장단점
 &lt;a class="heading-anchor" href="#-%ea%b0%81%ea%b0%81%ec%9d%98-%ec%9e%a5%eb%8b%a8%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;구분&lt;/th&gt;
					&lt;th&gt;장점&lt;/th&gt;
					&lt;th&gt;단점&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;L4&lt;/strong&gt; (전송 계층)&lt;/td&gt;
					&lt;td&gt;단순·고속, 프로토콜 무관(바이트로 전달), TLS 패스스루로 종단 암호화 쉬움&lt;/td&gt;
					&lt;td&gt;경로/호스트/gRPC 메서드별 라우팅·중앙 TLS 종료·헤더 조작 불가&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;L7&lt;/strong&gt; (애플리케이션 계층)&lt;/td&gt;
					&lt;td&gt;세밀한 라우팅, 중앙 TLS 종료, 헤더 조작, gRPC 요청 단위 분산&lt;/td&gt;
					&lt;td&gt;무겁고, 프로토콜을 이해해야 함(&amp;ldquo;h2c 지원하냐&amp;rdquo; 문제 발생)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;L4는 프로토콜을 안 가리니(HTTP/1.1이든 HTTP/2든 그냥 바이트로 전달) 미스매치가 없습니다. 대신 똑똑한 처리는 못 합니다. L7은 그 똑똑한 걸 다 하는 대신, 1편에서 겪은 h2c 지원 같은 문제가 따라옵니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-grpc-로드밸런싱의-함정-여기가-핵심"&gt;
 🪤 gRPC 로드밸런싱의 함정 (여기가 핵심)
 &lt;a class="heading-anchor" href="#-grpc-%eb%a1%9c%eb%93%9c%eb%b0%b8%eb%9f%b0%ec%8b%b1%ec%9d%98-%ed%95%a8%ec%a0%95-%ec%97%ac%ea%b8%b0%ea%b0%80-%ed%95%b5%ec%8b%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;gRPC는 연결 하나에 요청 여러 개를 실어 보내기 때문에(HTTP/2 다중화), L4 로드밸런서로는 트래픽이 한 Pod로 쏠립니다.&lt;/strong&gt; gRPC를 쓴다면 L4/L7 구분이 결정적으로 중요해지는 지점입니다.&lt;/p&gt;
&lt;h3 id="l4-로드밸런서는-연결-단위로-분산한다"&gt;
 L4 로드밸런서는 &amp;ldquo;연결 단위&amp;quot;로 분산한다
 &lt;a class="heading-anchor" href="#l4-%eb%a1%9c%eb%93%9c%eb%b0%b8%eb%9f%b0%ec%84%9c%eb%8a%94-%ec%97%b0%ea%b2%b0-%eb%8b%a8%ec%9c%84%eb%a1%9c-%eb%b6%84%ec%82%b0%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;한 클라이언트가 연결 하나를 열면, 그 안의 모든 요청이 &lt;strong&gt;한 Pod에만 몰립니다.&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;[L4 — 연결 단위]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;클라이언트 ──(연결 1개, 요청 100개)──▶ [LB] ──▶ Pod A (몰림 😵)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; Pod B (놀고 있음)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; Pod C (놀고 있음)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pod를 3개로 늘려도 한 곳만 바쁘고 나머지는 놉니다. 스케일아웃이 무력화됩니다.&lt;/p&gt;
&lt;h3 id="l7-로드밸런서는-요청-단위로-분산한다"&gt;
 L7 로드밸런서는 &amp;ldquo;요청 단위&amp;quot;로 분산한다
 &lt;a class="heading-anchor" href="#l7-%eb%a1%9c%eb%93%9c%eb%b0%b8%eb%9f%b0%ec%84%9c%eb%8a%94-%ec%9a%94%ec%b2%ad-%eb%8b%a8%ec%9c%84%eb%a1%9c-%eb%b6%84%ec%82%b0%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;같은 연결이라도 개별 RPC를 여러 Pod에 골고루 보냅니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;[L7 — 요청 단위]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;클라이언트 ──(연결 1개, 요청 100개)──▶ [LB] ──▶ Pod A (33개)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; Pod B (33개)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; Pod C (34개)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;그래서 &lt;strong&gt;gRPC 로드밸런싱은 사실상 L7이 필요합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 회의에서 듣던 &amp;ldquo;L7 지원 되냐&amp;quot;의 정체는 &amp;ldquo;이 장비가 편지를 열어 내용을 읽고, 특히 &lt;strong&gt;gRPC를 요청 단위로&lt;/strong&gt; 똑똑하게 분산할 수 있냐&amp;quot;는 질문이었습니다. &amp;ldquo;L7 지원 안 되면 gRPC가 곤란하다&amp;quot;는 말이 나오면 십중팔구 이 분산 문제입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-로드밸런서는-버전이-아니라-종류"&gt;
 🔀 로드밸런서는 &amp;ldquo;버전&amp;quot;이 아니라 &amp;ldquo;종류&amp;rdquo;
 &lt;a class="heading-anchor" href="#-%eb%a1%9c%eb%93%9c%eb%b0%b8%eb%9f%b0%ec%84%9c%eb%8a%94-%eb%b2%84%ec%a0%84%ec%9d%b4-%ec%95%84%eb%8b%88%eb%9d%bc-%ec%a2%85%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;L7은 L4의 신형 업그레이드가 아닙니다.&lt;/strong&gt; 흔한 오해입니다.&lt;/p&gt;
&lt;p&gt;L4/L7은 &amp;ldquo;어느 층에서 일하느냐에 따른 분류&amp;quot;일 뿐, 둘 다 현역이고 목적에 따라 고릅니다. L7이 항상 더 좋은 게 아니라 — 똑똑한 대신 무겁고 프로토콜을 가립니다. 단순·고속·프로토콜 무관이 필요하면 L4가 정답일 때도 많습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-전용-장비가-아니라-소프트웨어의-동작-방식"&gt;
 🖥️ 전용 장비가 아니라 소프트웨어의 동작 방식
 &lt;a class="heading-anchor" href="#-%ec%a0%84%ec%9a%a9-%ec%9e%a5%eb%b9%84%ea%b0%80-%ec%95%84%eb%8b%88%eb%9d%bc-%ec%86%8c%ed%94%84%ed%8a%b8%ec%9b%a8%ec%96%b4%ec%9d%98-%eb%8f%99%ec%9e%91-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;오늘날 L4/L7은 전용 하드웨어가 아니라 소프트웨어의 동작 방식입니다.&lt;/strong&gt; 예전엔 로드밸런서가 물리 박스(어플라이언스)였던 탓에 전용 장비가 필요하다는 인상이 남아 있지만, 지금은 일반 머신에서 돌리는 소프트웨어 하나면 됩니다.&lt;/p&gt;
&lt;p&gt;대표적으로 &lt;strong&gt;HAProxy는 설정 한 줄로 모드를 고릅니다.&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-haproxy" data-lang="haproxy"&gt;# L4 — 편지 안 열고 그냥 전달
frontend grpc_l4
 bind *:8080
 mode tcp
 default_backend grpc_servers

# L7 — 편지 열어서 내용 보고 처리 (gRPC 요청 단위 분산)
frontend grpc_l7
 bind *:8443 ssl crt /etc/haproxy/certs/server.pem alpn h2
 mode http
 default_backend grpc_servers&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mode tcp&lt;/code&gt; → &lt;strong&gt;L4&lt;/strong&gt; (편지 안 열고 그냥 전달)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mode http&lt;/code&gt; → &lt;strong&gt;L7&lt;/strong&gt; (편지 열어서 내용 보고 처리)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;클라우드는 이름부터 층을 드러내기도 합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;클라우드 LB&lt;/th&gt;
					&lt;th&gt;계층&lt;/th&gt;
					&lt;th&gt;특징&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;AWS &lt;strong&gt;NLB&lt;/strong&gt; (Network LB)&lt;/td&gt;
					&lt;td&gt;L4&lt;/td&gt;
					&lt;td&gt;초고속, 연결 단위&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;AWS &lt;strong&gt;ALB&lt;/strong&gt; (Application LB)&lt;/td&gt;
					&lt;td&gt;L7&lt;/td&gt;
					&lt;td&gt;HTTP/gRPC 라우팅, 요청 단위&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-한-줄-요약"&gt;
 📝 한 줄 요약
 &lt;a class="heading-anchor" href="#-%ed%95%9c-%ec%a4%84-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;L4는 겉봉(IP:포트)만 보고 빠르게 전달, L7은 편지를 열어 똑똑하게 처리합니다.&lt;/li&gt;
&lt;li&gt;gRPC는 연결 하나에 요청을 몰아 보내기 때문에, &lt;strong&gt;요청 단위로 분산하는 L7이 사실상 필수&lt;/strong&gt;입니다.&lt;/li&gt;
&lt;li&gt;L4/L7은 버전도 하드웨어도 아니라, 소프트웨어의 동작 방식(종류)입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-grpc를-l4-로드밸런서-뒤에-두면-왜-문제가-되나요"&gt;
 Q. gRPC를 L4 로드밸런서 뒤에 두면 왜 문제가 되나요?
 &lt;a class="heading-anchor" href="#q-grpc%eb%a5%bc-l4-%eb%a1%9c%eb%93%9c%eb%b0%b8%eb%9f%b0%ec%84%9c-%eb%92%a4%ec%97%90-%eb%91%90%eb%a9%b4-%ec%99%9c-%eb%ac%b8%ec%a0%9c%ea%b0%80-%eb%90%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;gRPC는 HTTP/2의 다중화로 연결 하나에 여러 요청을 싣습니다. L4는 연결 단위로 분산하므로, 한 클라이언트의 모든 요청이 한 Pod로만 가서 다른 Pod가 놀게 됩니다. 스케일아웃 효과가 사라집니다.&lt;/p&gt;
&lt;h3 id="q-그럼-grpc는-항상-l7을-써야-하나요"&gt;
 Q. 그럼 gRPC는 항상 L7을 써야 하나요?
 &lt;a class="heading-anchor" href="#q-%ea%b7%b8%eb%9f%bc-grpc%eb%8a%94-%ed%95%ad%ec%83%81-l7%ec%9d%84-%ec%8d%a8%ec%95%bc-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;요청 단위 분산이 필요하면 L7(또는 클라이언트 사이드 LB, 서비스 메시)이 필요합니다. 다만 단일 백엔드이거나 클라이언트가 직접 분산하는 구조라면 L4도 가능합니다.&lt;/p&gt;
&lt;h3 id="q-l7이-l4보다-항상-좋은가요"&gt;
 Q. L7이 L4보다 항상 좋은가요?
 &lt;a class="heading-anchor" href="#q-l7%ec%9d%b4-l4%eb%b3%b4%eb%8b%a4-%ed%95%ad%ec%83%81-%ec%a2%8b%ec%9d%80%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;아닙니다. L7은 똑똑한 대신 무겁고 프로토콜을 이해해야 합니다. 단순·고속·프로토콜 무관 처리가 필요하면 L4가 더 적합합니다. 둘은 버전 관계가 아니라 용도에 따른 선택입니다.&lt;/p&gt;
&lt;h3 id="q-haproxy에서-l4와-l7은-어떻게-구분하나요"&gt;
 Q. HAProxy에서 L4와 L7은 어떻게 구분하나요?
 &lt;a class="heading-anchor" href="#q-haproxy%ec%97%90%ec%84%9c-l4%ec%99%80-l7%ec%9d%80-%ec%96%b4%eb%96%bb%ea%b2%8c-%ea%b5%ac%eb%b6%84%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;mode tcp&lt;/code&gt;는 L4(내용을 안 보고 전달), &lt;code&gt;mode http&lt;/code&gt;는 L7(HTTP를 해석해 처리)입니다. gRPC를 요청 단위로 분산하려면 &lt;code&gt;mode http&lt;/code&gt;가 필요합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📚 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grpc.io/blog/grpc-load-balancing/"&gt;gRPC Blog - gRPC Load Balancing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/blog/2018/11/07/grpc-load-balancing-on-kubernetes-without-tears/"&gt;Kubernetes Blog - gRPC Load Balancing on Kubernetes without Tears&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.haproxy.org/2.8/configuration.html#4.2-mode"&gt;HAProxy Documentation - mode (tcp / http)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/elasticloadbalancing/features/"&gt;AWS - Elastic Load Balancing(NLB vs ALB)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-dotnet-http2-tls-troubleshooting/"&gt;관련 글: gRPC가 .NET에서만 안 됐다 (1편)&lt;/a&gt; · &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-http2-vs-h2c-tls/"&gt;HTTP/2는 TLS가 아니다 (2편)&lt;/a&gt;
&lt;/content&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] 🔐 HTTP/2는 TLS가 아니다: h2 vs h2c 완벽 정리</title><link>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-http2-vs-h2c-tls/</link><pubDate>Mon, 01 Jun 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-http2-vs-h2c-tls/</guid><description>&lt;p&gt;쿠버네티스에서 gRPC를 다루다 보면 &amp;ldquo;평문 HTTP/2(h2c)&amp;rdquo;, &amp;ldquo;scheme이 https인데 평문&amp;rdquo; 같은 모순처럼 들리는 말들과 마주칩니다. 이 글에서는 그 혼란의 근원인 &lt;strong&gt;&amp;ldquo;HTTP/2 = TLS&amp;quot;라는 오해&lt;/strong&gt;를 봉투·엽서 비유로 깨고, &lt;code&gt;h2&lt;/code&gt;와 &lt;code&gt;h2c&lt;/code&gt;의 차이, ALPN 협상, TLS termination을 정리합니다. 이 개념만 잡으면 게이트웨이 뒤 gRPC 통신이 왜 그렇게 동작하는지 전부 설명됩니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;이 시리즈는&lt;/strong&gt; 쿠버네티스에 gRPC 서비스를 올리다 막힌 삽질에서 출발해 HTTP/2·TLS·로드밸런서·Gateway API·인증서까지 풀어가는 기록입니다. 이번 2편은 &lt;strong&gt;기초 개념(h2 vs h2c)&lt;/strong&gt; 편입니다. 1편을 아직 안 읽었다면 &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-dotnet-http2-tls-troubleshooting/"&gt;.NET gRPC가 게이트웨이 뒤에서 안 됐던 문제와 해결&lt;/a&gt;을 먼저 보면 좋습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-모든-혼란의-근원-http2--tls라는-오해"&gt;
 🧱 모든 혼란의 근원: &amp;ldquo;HTTP/2 = TLS&amp;quot;라는 오해
 &lt;a class="heading-anchor" href="#-%eb%aa%a8%eb%93%a0-%ed%98%bc%eb%9e%80%ec%9d%98-%ea%b7%bc%ec%9b%90-http2--tls%eb%9d%bc%eb%8a%94-%ec%98%a4%ed%95%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2와 TLS는 별개입니다.&lt;/strong&gt; 가장 먼저 깨야 할 오해입니다. 둘은 서로 다른 축에 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TLS&lt;/strong&gt; = 암호화. 데이터를 봉투에 넣어 봉하느냐의 문제입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTP/2&lt;/strong&gt; = 통신 프로토콜. 편지를 어떤 &amp;ldquo;언어&amp;quot;로 쓰느냐의 문제입니다(HTTP/1.1이냐 HTTP/2냐).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;비유하면 이렇습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;암호화(TLS) = 봉투&lt;/strong&gt; / &lt;strong&gt;평문 = 엽서&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;통신 방식(HTTP 버전) = 편지를 쓴 언어&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;편지를 HTTP/2라는 언어로 쓰되, 봉투에 담아 보낼 수도 있고(암호화), 엽서로 보낼 수도 있습니다(평문). 이 둘은 독립적입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-네-가지-조합"&gt;
 🔢 네 가지 조합
 &lt;a class="heading-anchor" href="#-%eb%84%a4-%ea%b0%80%ec%a7%80-%ec%a1%b0%ed%95%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;포장(암호화)과 언어(HTTP 버전)가 독립이라, 네 가지 조합이 모두 가능합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;/th&gt;
					&lt;th&gt;평문 (엽서)&lt;/th&gt;
					&lt;th&gt;TLS (봉투)&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;HTTP/1.1&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;그냥 HTTP (&lt;code&gt;http://&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;HTTPS (&lt;code&gt;https://&lt;/code&gt;)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;HTTP/2&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;h2c&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;h2&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;여기서 &lt;code&gt;h2c&lt;/code&gt;의 &lt;strong&gt;&lt;code&gt;c&lt;/code&gt;는 cleartext(평문)&lt;/strong&gt;, 즉 &amp;ldquo;암호화하지 않은 HTTP/2&amp;quot;입니다.&lt;/p&gt;
&lt;h3 id="왜-평문-http2가-모순처럼-들릴까"&gt;
 왜 &amp;ldquo;평문 HTTP/2&amp;quot;가 모순처럼 들릴까?
 &lt;a class="heading-anchor" href="#%ec%99%9c-%ed%8f%89%eb%ac%b8-http2%ea%b0%80-%eb%aa%a8%ec%88%9c%ec%b2%98%eb%9f%bc-%eb%93%a4%eb%a6%b4%ea%b9%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;브라우저 때문입니다.&lt;/strong&gt; 브라우저는 보안상 HTTP/2를 TLS 위에서만(h2) 허용하고, 평문 HTTP/2(h2c)는 쓰지 않습니다. 그래서 일상에서 &amp;ldquo;HTTP/2 = HTTPS&amp;quot;처럼 느껴집니다. 하지만 그건 브라우저의 정책일 뿐, &lt;strong&gt;프로토콜 자체의 규칙이 아닙니다.&lt;/strong&gt; 서버끼리 통신할 땐 평문 HTTP/2(h2c)를 흔히 쓰며, 쿠버네티스 클러스터 내부가 대표적입니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;🧠 흔한 오해: &amp;ldquo;HTTP/2면 당연히 https니까 인증서가 필요하겠지.&amp;rdquo; 실제로는 클러스터 내부 통신은 평문 HTTP/2(h2c)인 경우가 많고, 암호화는 별개 문제입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-h2--h2c는-누가-지어낸-말이-아니다"&gt;
 📜 h2 / h2c는 누가 지어낸 말이 아니다
 &lt;a class="heading-anchor" href="#-h2--h2c%eb%8a%94-%eb%88%84%ea%b0%80-%ec%a7%80%ec%96%b4%eb%82%b8-%eb%a7%90%ec%9d%b4-%ec%95%84%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;h2&lt;/code&gt;와 &lt;code&gt;h2c&lt;/code&gt;는 특정 도구의 용어가 아니라 &lt;strong&gt;HTTP/2 표준(RFC 7540)에 정의되고 IANA에 등록된 공식 식별자&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;원래 &lt;code&gt;h2&lt;/code&gt;는 TLS 핸드셰이크 때 &amp;ldquo;우리 HTTP/2로 말하자&amp;quot;를 짧게 주고받기 위한 &lt;strong&gt;ALPN 토큰&lt;/strong&gt;입니다. 그래서 &lt;code&gt;http2&lt;/code&gt;처럼 길게 쓰지 않고 &lt;code&gt;h2&lt;/code&gt;라는 짧은 형태로 정했습니다. &lt;code&gt;h2c&lt;/code&gt;는 평문 연결에서 HTTP/1.1 → HTTP/2 업그레이드를 요청할 때 쓰던 토큰이었습니다.&lt;/p&gt;
&lt;p&gt;이게 중요한 이유는 &lt;strong&gt;도구가 바뀌어도 의미가 같기 때문&lt;/strong&gt;입니다. Envoy·Kestrel·gRPC·Contour HTTPProxy 어디서 보든 &lt;code&gt;h2c&lt;/code&gt;는 전부 &amp;ldquo;평문 HTTP/2&amp;quot;라는 같은 뜻입니다. 각 도구가 제멋대로 지은 게 아니라 같은 표준을 따르므로, 한 번 익히면 그대로 통합니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;: 이후 HTTP/2 표준이 RFC 9113으로 정리되며 평문 업그레이드(&lt;code&gt;Upgrade: h2c&lt;/code&gt;) 메커니즘 등 세부 규칙은 일부 바뀌었지만, &lt;code&gt;h2&lt;/code&gt;=TLS HTTP/2, &lt;code&gt;h2c&lt;/code&gt;=평문 HTTP/2라는 기본 의미는 그대로입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-alpn--봉투를-열기-전에-언어를-합의하는-과정"&gt;
 🤝 ALPN — 봉투를 열기 전에 &amp;ldquo;언어&amp;quot;를 합의하는 과정
 &lt;a class="heading-anchor" href="#-alpn--%eb%b4%89%ed%88%ac%eb%a5%bc-%ec%97%b4%ea%b8%b0-%ec%a0%84%ec%97%90-%ec%96%b8%ec%96%b4%eb%a5%bc-%ed%95%a9%ec%9d%98%ed%95%98%eb%8a%94-%ea%b3%bc%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;ALPN(Application-Layer Protocol Negotiation)은 TLS 핸드셰이크 단계에서 클라이언트와 서버가 어떤 프로토콜로 통신할지 미리 합의하는 과정입니다.&lt;/strong&gt; 봉투(TLS)를 봉하기 전에 &amp;ldquo;우리 무슨 언어로 말할까?&amp;ldquo;를 정하는 셈이고, 여기서 &lt;code&gt;h2&lt;/code&gt;로 합의되면 HTTP/2로 통신합니다.&lt;/p&gt;
&lt;p&gt;핵심 포인트는 &lt;strong&gt;평문(엽서)에는 이 ALPN 단계가 없다&lt;/strong&gt;는 것입니다.&lt;/p&gt;
&lt;p&gt;그래서 1편에서 Kestrel을 &lt;code&gt;Http1AndHttp2&lt;/code&gt;로 두면 안 됐던 것입니다. 평문 포트에는 &amp;ldquo;무슨 언어냐&amp;quot;를 협상할 ALPN이 없으니, Kestrel이 안전하게 HTTP/1.1로 떨어뜨립니다. 평문에서 HTTP/2를 받으려면 &lt;strong&gt;&lt;code&gt;Http2&lt;/code&gt; 전용&lt;/strong&gt;으로 못 박아야 합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsonc" data-lang="jsonc"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// appsettings.json — 평문 포트에서 HTTP/2를 강제
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Kestrel&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;EndpointDefaults&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Protocols&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Http2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-tls-termination--봉투를-어디서-뜯느냐"&gt;
 ✂️ TLS termination — 봉투를 어디서 뜯느냐
 &lt;a class="heading-anchor" href="#-tls-termination--%eb%b4%89%ed%88%ac%eb%a5%bc-%ec%96%b4%eb%94%94%ec%84%9c-%eb%9c%af%eb%8a%90%eb%83%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;TLS termination(TLS 종료)은 게이트웨이가 들어오는 암호화 연결의 봉투(TLS)를 뜯어 평문으로 바꾸는 지점입니다.&lt;/strong&gt; 내용을 읽어 라우팅하려면 봉투를 먼저 열어야 하기 때문입니다. 그리고 클러스터 안쪽(게이트웨이 → Pod)으로는 다시 엽서(평문 h2c)로 전달합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;클라이언트 ──(봉투, h2)──▶ 게이트웨이[봉투 뜯음] ──(엽서, h2c)──▶ Pod&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;여기서 1편의 원인 ②가 나옵니다. 게이트웨이는 봉투를 뜯어 엽서로 바꾸면서도, 편지에 붙은 &lt;strong&gt;&lt;code&gt;:scheme&lt;/code&gt; 라벨&lt;/strong&gt;은 원래대로 &amp;ldquo;https(봉투)&amp;ldquo;라고 남겨 둡니다. 그러니 엽서를 받은 Kestrel이 &amp;ldquo;라벨엔 봉투라는데 넌 엽서네?&amp;rdquo; 하고 거부한 것입니다. &lt;code&gt;AllowAlternateSchemes&lt;/code&gt;는 &amp;ldquo;그 라벨은 무시하고 받아라&amp;quot;라는 허락이었습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WebHost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConfigureKestrel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowAlternateSchemes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// :scheme=https + 평문 전송 허용&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-정리-세-가지만-구분하면-된다"&gt;
 🧩 정리: 세 가지만 구분하면 된다
 &lt;a class="heading-anchor" href="#-%ec%a0%95%eb%a6%ac-%ec%84%b8-%ea%b0%80%ec%a7%80%eb%a7%8c-%ea%b5%ac%eb%b6%84%ed%95%98%eb%a9%b4-%eb%90%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;1편의 모든 증상이 이 세 가지의 조합으로 설명됩니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;구분&lt;/th&gt;
					&lt;th&gt;의미&lt;/th&gt;
					&lt;th&gt;예시&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;봉투 / 엽서&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;암호화 여부&lt;/td&gt;
					&lt;td&gt;TLS / 평문&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;언어&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;통신 방식&lt;/td&gt;
					&lt;td&gt;HTTP/1.1 / HTTP/2&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;라벨&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;요청 헤더&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;:scheme&lt;/code&gt;, &lt;code&gt;:authority&lt;/code&gt; 등&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;외울 한 문장:&lt;/strong&gt; 통신 방식(HTTP/1.1·HTTP/2)과 암호화(TLS를 쓰냐 마냐)는 &lt;strong&gt;완전히 별개다.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;이 한 문장이 몸에 배면, &amp;ldquo;평문 HTTP/2&amp;quot;도 &amp;ldquo;scheme이 https인데 평문&amp;quot;도 더 이상 모순으로 들리지 않습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-h2와-h2c의-차이는-무엇인가요"&gt;
 Q. h2와 h2c의 차이는 무엇인가요?
 &lt;a class="heading-anchor" href="#q-h2%ec%99%80-h2c%ec%9d%98-%ec%b0%a8%ec%9d%b4%eb%8a%94-%eb%ac%b4%ec%97%87%ec%9d%b8%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;둘 다 HTTP/2입니다. &lt;code&gt;h2&lt;/code&gt;는 TLS 위에서(암호화) 동작하는 HTTP/2, &lt;code&gt;h2c&lt;/code&gt;는 평문(cleartext)에서 동작하는 HTTP/2입니다. &lt;code&gt;c&lt;/code&gt;는 cleartext를 뜻합니다.&lt;/p&gt;
&lt;h3 id="q-http2를-쓰려면-반드시-인증서tls가-필요한가요"&gt;
 Q. HTTP/2를 쓰려면 반드시 인증서(TLS)가 필요한가요?
 &lt;a class="heading-anchor" href="#q-http2%eb%a5%bc-%ec%93%b0%eb%a0%a4%eb%a9%b4-%eb%b0%98%eb%93%9c%ec%8b%9c-%ec%9d%b8%ec%a6%9d%ec%84%9ctls%ea%b0%80-%ed%95%84%ec%9a%94%ed%95%9c%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;아닙니다. 그건 브라우저의 정책일 뿐 프로토콜 규칙이 아닙니다. 서버 간 통신, 특히 쿠버네티스 클러스터 내부에서는 평문 HTTP/2(h2c)를 흔히 사용합니다.&lt;/p&gt;
&lt;h3 id="q-alpn이-없으면-왜-http2로-통신할-수-없나요"&gt;
 Q. ALPN이 없으면 왜 HTTP/2로 통신할 수 없나요?
 &lt;a class="heading-anchor" href="#q-alpn%ec%9d%b4-%ec%97%86%ec%9c%bc%eb%a9%b4-%ec%99%9c-http2%eb%a1%9c-%ed%86%b5%ec%8b%a0%ed%95%a0-%ec%88%98-%ec%97%86%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;평문 연결에는 TLS 핸드셰이크 자체가 없어 ALPN 협상 단계가 없습니다. 따라서 &amp;ldquo;HTTP/2로 말하자&amp;quot;를 합의할 방법이 없어, 서버는 안전하게 HTTP/1.1로 처리하거나 HTTP/2 전용으로 명시되어 있어야 합니다.&lt;/p&gt;
&lt;h3 id="q-tls-termination-이후-백엔드는-어떤-프로토콜을-받나요"&gt;
 Q. TLS termination 이후 백엔드는 어떤 프로토콜을 받나요?
 &lt;a class="heading-anchor" href="#q-tls-termination-%ec%9d%b4%ed%9b%84-%eb%b0%b1%ec%97%94%eb%93%9c%eb%8a%94-%ec%96%b4%eb%96%a4-%ed%94%84%eb%a1%9c%ed%86%a0%ec%bd%9c%ec%9d%84-%eb%b0%9b%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;게이트웨이가 TLS를 종료하면 백엔드(Pod)로는 평문이 전달됩니다. gRPC라면 이때 평문 HTTP/2, 즉 &lt;code&gt;h2c&lt;/code&gt;로 전달되어야 합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📚 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://datatracker.ietf.org/doc/html/rfc7540"&gt;RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://datatracker.ietf.org/doc/html/rfc9113"&gt;RFC 9113 - HTTP/2 (RFC 7540 개정판)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids"&gt;IANA TLS Application-Layer Protocol Negotiation (ALPN) Protocol IDs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/ALPN"&gt;MDN - Application-Layer Protocol Negotiation (ALPN)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-dotnet-http2-tls-troubleshooting/"&gt;관련 글: gRPC가 .NET에서만 안 됐다 (시리즈 1편)&lt;/a&gt;
&lt;/content&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] 🔌 gRPC가 .NET에서만 안 됐다: HTTP/2·TLS·scheme 문제 해결</title><link>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-dotnet-http2-tls-troubleshooting/</link><pubDate>Sat, 30 May 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-grpc-dotnet-http2-tls-troubleshooting/</guid><description>&lt;p&gt;쿠버네티스에 gRPC 서비스를 올렸는데 &lt;strong&gt;Python 서버는 붙고 .NET(Kestrel) 서버만 계속 끊기는&lt;/strong&gt; 문제를 겪었습니다. 이 글에서는 그 원인이 ① 게이트웨이가 백엔드로 HTTP/1.1을 보내는 문제와 ② TLS 종료 후에도 &lt;code&gt;:scheme=https&lt;/code&gt; 라벨이 남아 Kestrel이 거부하는 문제, &lt;strong&gt;두 개의 서로 다른 계층&lt;/strong&gt;에 있었음을 추적하고 &lt;code&gt;h2c&lt;/code&gt; + &lt;code&gt;AllowAlternateSchemes&lt;/code&gt;로 해결하는 과정을 단계별로 다룹니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;이 시리즈는&lt;/strong&gt; 쿠버네티스에 gRPC 서비스를 올리다 막힌 삽질에서 출발해, HTTP/2·TLS·로드밸런서·Gateway API·인증서까지 하나씩 풀어가는 기록입니다. 1편(이 글)은 &lt;strong&gt;문제와 해결&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-증상-같은-grpc인데-한쪽만-안-된다"&gt;
 🚨 증상: 같은 gRPC인데 한쪽만 안 된다
 &lt;a class="heading-anchor" href="#-%ec%a6%9d%ec%83%81-%ea%b0%99%ec%9d%80-grpc%ec%9d%b8%eb%8d%b0-%ed%95%9c%ec%aa%bd%eb%a7%8c-%ec%95%88-%eb%90%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;쿠버네티스에 gRPC 서비스를 올렸습니다. 게이트웨이 설정은 동일한데 결과가 갈렸습니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;백엔드&lt;/th&gt;
					&lt;th&gt;포트 80 (평문)&lt;/th&gt;
					&lt;th&gt;포트 443 (TLS)&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Python gRPC 서버&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;✅ 정상&lt;/td&gt;
					&lt;td&gt;✅ 정상&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;.NET(Kestrel) gRPC 서버&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;✅ 정상&lt;/td&gt;
					&lt;td&gt;❌ 연결 끊김&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Kestrel 로그에는 다음과 같은 에러가 찍혔습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;The request :scheme header &amp;#39;https&amp;#39; does not match the transport scheme &amp;#39;http&amp;#39;.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;처음 든 생각은 &amp;ldquo;HTTP/2가 문제니까 HTTP/2를 피해보자&amp;quot;였습니다. 결론부터 말하면 &lt;strong&gt;그건 불가능합니다.&lt;/strong&gt; gRPC는 HTTP/2 위에서만 동작하기 때문입니다. HTTP/2를 빼는 순간 그건 더 이상 gRPC가 아닙니다.&lt;/p&gt;
&lt;p&gt;그래서 방향을 바꿨습니다. &amp;ldquo;피하자&amp;quot;가 아니라 &lt;strong&gt;&amp;ldquo;어디서, 왜 깨지는지&amp;quot;를 정확히 찾자&lt;/strong&gt;로요.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-핵심-전제-두-가지"&gt;
 📌 핵심 전제 두 가지
 &lt;a class="heading-anchor" href="#-%ed%95%b5%ec%8b%ac-%ec%a0%84%ec%a0%9c-%eb%91%90-%ea%b0%80%ec%a7%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;본격적으로 들어가기 전에 두 가지만 깔고 갑니다. (자세한 개념은 다음 편에서 다룹니다.)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;gRPC = HTTP/2.&lt;/strong&gt; 처음부터 끝까지 HTTP/2를 요구합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;ldquo;통신 방식(HTTP 버전)&amp;ldquo;과 &amp;ldquo;암호화(TLS)&amp;ldquo;는 별개입니다.&lt;/strong&gt; 이게 모든 혼란의 근원이었습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;특히 헷갈렸던 건 &lt;code&gt;h2c&lt;/code&gt;라는 단어였습니다.&lt;/p&gt;
&lt;h3 id="h2와-h2c는-무엇인가"&gt;
 h2와 h2c는 무엇인가?
 &lt;a class="heading-anchor" href="#h2%ec%99%80-h2c%eb%8a%94-%eb%ac%b4%ec%97%87%ec%9d%b8%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;h2&lt;/code&gt;는 &lt;strong&gt;TLS 위에서 동작하는 HTTP/2&lt;/strong&gt;, &lt;code&gt;h2c&lt;/code&gt;는 &lt;strong&gt;암호화 없이(평문) 동작하는 HTTP/2&lt;/strong&gt;를 가리킵니다(&lt;code&gt;c&lt;/code&gt; = cleartext). &amp;ldquo;HTTP/2인데 평문&amp;quot;이라는 말이 모순처럼 들리지만, HTTP/2와 TLS가 별개의 계층이라는 것을 알고 나면 자연스럽습니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;표기&lt;/th&gt;
					&lt;th&gt;프로토콜&lt;/th&gt;
					&lt;th&gt;암호화&lt;/th&gt;
					&lt;th&gt;일반적인 포트&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;h2&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;HTTP/2&lt;/td&gt;
					&lt;td&gt;TLS 있음&lt;/td&gt;
					&lt;td&gt;443&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;h2c&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;HTTP/2&lt;/td&gt;
					&lt;td&gt;평문&lt;/td&gt;
					&lt;td&gt;80&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-원인---게이트웨이가-http11로-말을-걸고-있었다"&gt;
 🔍 원인 ① — 게이트웨이가 HTTP/1.1로 말을 걸고 있었다
 &lt;a class="heading-anchor" href="#-%ec%9b%90%ec%9d%b8---%ea%b2%8c%ec%9d%b4%ed%8a%b8%ec%9b%a8%ec%9d%b4%ea%b0%80-http11%eb%a1%9c-%eb%a7%90%ec%9d%84-%ea%b1%b8%ea%b3%a0-%ec%9e%88%ec%97%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;첫 번째 원인은 게이트웨이가 백엔드로 HTTP/1.1을 보내고 있었던 것입니다.&lt;/strong&gt; Kestrel을 HTTP/2 전용으로 설정해 두면 그 포트는 HTTP/2만 알아듣습니다. 그런데 게이트웨이는 별도 지정이 없으면 백엔드로 &lt;strong&gt;HTTP/1.1&lt;/strong&gt;을 보냅니다. &amp;ldquo;언어&amp;quot;가 안 맞으니 Kestrel이 거부합니다.&lt;/p&gt;
&lt;h3 id="해결--a-게이트웨이가-h2c로-보내게-한다"&gt;
 해결 ①-a: 게이트웨이가 h2c로 보내게 한다
 &lt;a class="heading-anchor" href="#%ed%95%b4%ea%b2%b0--a-%ea%b2%8c%ec%9d%b4%ed%8a%b8%ec%9b%a8%ec%9d%b4%ea%b0%80-h2c%eb%a1%9c-%eb%b3%b4%eb%82%b4%ea%b2%8c-%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Service에 &lt;code&gt;appProtocol&lt;/code&gt;을 명시하면, 게이트웨이가 백엔드로 평문 HTTP/2를 보내야 한다는 것을 알게 됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-grpc-svc&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;grpc&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;targetPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;appProtocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes.io/h2c &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 평문 HTTP/2로 전달하라&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Contour를 사용한다면 HTTPProxy에서 백엔드 프로토콜을 직접 지정할 수도 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Contour HTTPProxy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-grpc-svc&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;h2c&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="해결--b-kestrel을-http2-전용으로-둔다"&gt;
 해결 ①-b: Kestrel을 HTTP/2 전용으로 둔다
 &lt;a class="heading-anchor" href="#%ed%95%b4%ea%b2%b0--b-kestrel%ec%9d%84-http2-%ec%a0%84%ec%9a%a9%ec%9c%bc%eb%a1%9c-%eb%91%94%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;평문 포트에는 프로토콜 자동 협상(ALPN)이 없어서, &lt;code&gt;Http1AndHttp2&lt;/code&gt;로 두면 협상 단계 없이 &lt;strong&gt;HTTP/1.1로 떨어집니다.&lt;/strong&gt; 따라서 평문 gRPC 포트는 &lt;code&gt;Http2&lt;/code&gt;로 고정해야 합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsonc" data-lang="jsonc"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// appsettings.json
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Kestrel&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;EndpointDefaults&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Protocols&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Http2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;code&gt;Http1AndHttp2&lt;/code&gt;는 TLS(ALPN)가 있을 때만 HTTP/2로 협상됩니다. TLS 종료가 게이트웨이에서 일어나는 쿠버네티스 환경에서는 평문 포트이므로 &lt;code&gt;Http2&lt;/code&gt;로 명시해야 합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-원인---scheme-라벨-불일치-net만-막혔던-진짜-이유"&gt;
 🔍 원인 ② — scheme 라벨 불일치 (.NET만 막혔던 진짜 이유)
 &lt;a class="heading-anchor" href="#-%ec%9b%90%ec%9d%b8---scheme-%eb%9d%bc%eb%b2%a8-%eb%b6%88%ec%9d%bc%ec%b9%98-net%eb%a7%8c-%eb%a7%89%ed%98%94%eb%8d%98-%ec%a7%84%ec%a7%9c-%ec%9d%b4%ec%9c%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;두 번째 원인이자 .NET만 막힌 진짜 이유는 &lt;code&gt;:scheme&lt;/code&gt; 라벨과 실제 전송 방식의 불일치입니다.&lt;/strong&gt; 게이트웨이가 TLS를 종료(복호화)해 평문으로 바꿔 보내면서도, 요청에 붙은 &lt;code&gt;:scheme&lt;/code&gt; 값은 원래대로 &lt;strong&gt;&lt;code&gt;https&lt;/code&gt;&lt;/strong&gt; 로 남겨 둡니다. 그런데 Kestrel에 도착한 연결은 평문입니다. Kestrel은 &amp;ldquo;scheme은 https라는데 연결은 평문이네? 안 맞잖아&amp;quot;라며 거부합니다. 이게 로그에 찍힌 그 에러의 정체였습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;The request :scheme header &amp;#39;https&amp;#39; does not match the transport scheme &amp;#39;http&amp;#39;.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Python gRPC 서버는 이 scheme 검증을 하지 않아서 그냥 통과했고, Kestrel만 엄격하게 검사했던 것입니다.&lt;/p&gt;
&lt;h3 id="해결--kestrel에게-그-scheme을-허용하라고-알려준다"&gt;
 해결 ②: Kestrel에게 그 scheme을 허용하라고 알려준다
 &lt;a class="heading-anchor" href="#%ed%95%b4%ea%b2%b0--kestrel%ec%97%90%ea%b2%8c-%ea%b7%b8-scheme%ec%9d%84-%ed%97%88%ec%9a%a9%ed%95%98%eb%9d%bc%ea%b3%a0-%ec%95%8c%eb%a0%a4%ec%a4%80%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;AllowAlternateSchemes&lt;/code&gt; 옵션을 켜면 Kestrel이 &lt;code&gt;:scheme&lt;/code&gt;과 전송 방식이 달라도 허용합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WebHost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConfigureKestrel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowAlternateSchemes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;덤으로 이 옵션을 켜면 &lt;code&gt;HttpRequest.Scheme&lt;/code&gt;이 원래 값(&lt;code&gt;https&lt;/code&gt;)으로 잡혀, 앱이 리다이렉트·절대경로 URL을 만들 때도 올바르게 동작합니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: &lt;code&gt;AllowAlternateSchemes&lt;/code&gt;는 .NET 6 이상에서 사용할 수 있습니다. scheme 값 자체는 여전히 유효한 형식이어야 합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-두-설정은-중복이-아니라-서로-다른-층"&gt;
 🧩 두 설정은 &amp;ldquo;중복&amp;quot;이 아니라 &amp;ldquo;서로 다른 층&amp;rdquo;
 &lt;a class="heading-anchor" href="#-%eb%91%90-%ec%84%a4%ec%a0%95%ec%9d%80-%ec%a4%91%eb%b3%b5%ec%9d%b4-%ec%95%84%eb%8b%88%eb%9d%bc-%ec%84%9c%eb%a1%9c-%eb%8b%a4%eb%a5%b8-%ec%b8%b5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;처음엔 &amp;ldquo;둘 다 h2c 관련 아닌가?&amp;rdquo; 싶었는데, 역할이 완전히 다릅니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;설정&lt;/th&gt;
					&lt;th&gt;담당하는 계층&lt;/th&gt;
					&lt;th&gt;의미&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Service의 &lt;code&gt;appProtocol: h2c&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;통신 방식(언어)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;HTTP/2로 보내라&amp;rdquo;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Kestrel &lt;code&gt;AllowAlternateSchemes&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;헤더(라벨) 검증&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;https 라벨을 평문 위에서도 허용해라&amp;rdquo;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;그래서 하나만 빼도, 둘 다 빼도 통신이 안 됩니다. &lt;strong&gt;둘 다 맞춰야&lt;/strong&gt; 합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-증상이-전부-설명된다"&gt;
 ✅ 증상이 전부 설명된다
 &lt;a class="heading-anchor" href="#-%ec%a6%9d%ec%83%81%ec%9d%b4-%ec%a0%84%eb%b6%80-%ec%84%a4%eb%aa%85%eb%90%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;두 원인을 알고 나면 처음의 증상 표가 모두 설명됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;왜 80은 되고 443은 안 됐나?&lt;/strong&gt;
80(평문)으로 들어오면 게이트웨이가 scheme &lt;code&gt;http&lt;/code&gt;로 전달 → 실제도 평문 → 일치 → OK.
443(TLS)은 scheme &lt;code&gt;https&lt;/code&gt;를 평문 위로 전달 → 불일치 → 실패.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;왜 Python은 되고 .NET은 안 됐나?&lt;/strong&gt;
Python 서버는 scheme 라벨을 검증하지 않았고, Kestrel만 엄격하게 검사했기 때문입니다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-한-줄-요약"&gt;
 📝 한 줄 요약
 &lt;a class="heading-anchor" href="#-%ed%95%9c-%ec%a4%84-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;.NET gRPC가 게이트웨이 뒤에서 안 됐던 건 &lt;strong&gt;두 가지&lt;/strong&gt;였습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;게이트웨이가 HTTP/1.1로 말을 걸어서 → Service &lt;code&gt;appProtocol: h2c&lt;/code&gt; + Kestrel &lt;code&gt;Protocols: Http2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;TLS를 푼 뒤에도 &lt;code&gt;:scheme=https&lt;/code&gt; 라벨이 남아 Kestrel이 거부해서 → &lt;code&gt;AllowAlternateSchemes = true&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;둘은 다른 층의 문제라 &lt;strong&gt;둘 다&lt;/strong&gt; 맞춰야 합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-grpc를-http11로-쓸-수는-없나요"&gt;
 Q. gRPC를 HTTP/1.1로 쓸 수는 없나요?
 &lt;a class="heading-anchor" href="#q-grpc%eb%a5%bc-http11%eb%a1%9c-%ec%93%b8-%ec%88%98%eb%8a%94-%ec%97%86%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;없습니다. gRPC는 스트리밍과 멀티플렉싱을 위해 HTTP/2를 전제로 설계되어, HTTP/2를 빼면 더 이상 gRPC가 아닙니다.&lt;/p&gt;
&lt;h3 id="q-h2와-h2c의-차이는-무엇인가요"&gt;
 Q. h2와 h2c의 차이는 무엇인가요?
 &lt;a class="heading-anchor" href="#q-h2%ec%99%80-h2c%ec%9d%98-%ec%b0%a8%ec%9d%b4%eb%8a%94-%eb%ac%b4%ec%97%87%ec%9d%b8%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;둘 다 HTTP/2입니다. &lt;code&gt;h2&lt;/code&gt;는 TLS 위에서(암호화), &lt;code&gt;h2c&lt;/code&gt;는 평문에서 동작합니다. 쿠버네티스에서 게이트웨이가 TLS를 종료하면 백엔드로는 &lt;code&gt;h2c&lt;/code&gt;(평문 HTTP/2)가 전달됩니다.&lt;/p&gt;
&lt;h3 id="q-kestrel을-http1andhttp2로-두면-안-되나요"&gt;
 Q. Kestrel을 &lt;code&gt;Http1AndHttp2&lt;/code&gt;로 두면 안 되나요?
 &lt;a class="heading-anchor" href="#q-kestrel%ec%9d%84-http1andhttp2%eb%a1%9c-%eb%91%90%eb%a9%b4-%ec%95%88-%eb%90%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;평문 포트에서는 ALPN 협상이 없어 HTTP/1.1로 떨어집니다. TLS 종료가 게이트웨이에서 일어나는 환경에서는 평문 gRPC 포트를 &lt;code&gt;Http2&lt;/code&gt;로 고정해야 합니다.&lt;/p&gt;
&lt;h3 id="q-allowalternateschemes는-어떤-상황에서-필요한가요"&gt;
 Q. &lt;code&gt;AllowAlternateSchemes&lt;/code&gt;는 어떤 상황에서 필요한가요?
 &lt;a class="heading-anchor" href="#q-allowalternateschemes%eb%8a%94-%ec%96%b4%eb%96%a4-%ec%83%81%ed%99%a9%ec%97%90%ec%84%9c-%ed%95%84%ec%9a%94%ed%95%9c%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;게이트웨이/로드밸런서가 TLS를 종료한 뒤 &lt;code&gt;:scheme&lt;/code&gt;을 원래 값(&lt;code&gt;https&lt;/code&gt;)으로 유지한 채 평문으로 백엔드에 전달할 때 필요합니다. 이 옵션이 없으면 Kestrel이 scheme과 전송 방식 불일치로 연결을 거부합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📚 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/aspnetcore/pull/34013"&gt;Allow alternate schemes in Kestrel requests · PR #34013 (dotnet/aspnetcore)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/aspnetcore/issues/30532"&gt;GRPC :scheme pseudo-header causes ConnectionAbortedException · Issue #30532 (dotnet/aspnetcore)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/grpc/grpc-dotnet/issues/979"&gt;gRPC issue when Kestrel set to Http1AndHttp2 with unsecure urls · Issue #979 (grpc/grpc-dotnet)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/services-networking/service/#application-protocol"&gt;Kubernetes Service appProtocol 문서&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://projectcontour.io/docs/main/config/upstream-tls/"&gt;Contour HTTPProxy: gRPC / h2c upstream&lt;/a&gt;
&lt;/content&gt;
&lt;/invoke&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] 🔐 kubeadm 인증서 자동 갱신: systemd 타이머로 만료 방지하기</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubernetes-certs-auto-renewal-systemd/</link><pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubernetes-certs-auto-renewal-systemd/</guid><description>&lt;p&gt;kubeadm으로 설치한 Kubernetes 클러스터의 컨트롤 플레인 인증서는 기본 유효기간이 &lt;strong&gt;1년&lt;/strong&gt;입니다.
운영 중인 클러스터에서 인증서가 만료되면 API 서버, 컨트롤러 매니저, 스케줄러가 통신을 멈추면서 클러스터 전체가 마비됩니다.
이 글에서는 &lt;strong&gt;systemd 타이머&lt;/strong&gt;로 만료 30일 전에 자동으로 &lt;code&gt;kubeadm certs renew all&lt;/code&gt;을 실행하여 인증서를 무중단으로 갱신하는 방법을 정리합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-kubeadm-인증서란"&gt;
 🔑 kubeadm 인증서란?
 &lt;a class="heading-anchor" href="#-kubeadm-%ec%9d%b8%ec%a6%9d%ec%84%9c%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;kubeadm은 클러스터 부트스트랩 시 컨트롤 플레인 구성요소가 사용하는 TLS 인증서를 자동으로 생성합니다.
모든 인증서는 &lt;code&gt;/etc/kubernetes/pki/&lt;/code&gt; 경로에 저장됩니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;구분&lt;/th&gt;
					&lt;th&gt;인증서&lt;/th&gt;
					&lt;th&gt;용도&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;CA&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;ca.crt&lt;/code&gt;, &lt;code&gt;ca.key&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;클러스터 루트 CA (유효기간 10년)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;API Server&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;apiserver.crt&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;kube-apiserver HTTPS&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;API Server (kubelet)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;apiserver-kubelet-client.crt&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;apiserver → kubelet 통신&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Front Proxy&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;front-proxy-*.crt&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Aggregation Layer&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;etcd&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;etcd/*.crt&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;etcd 멤버 간 + 클라이언트 통신&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;kubeconfig 내 인증서&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;admin.conf&lt;/code&gt;, &lt;code&gt;controller-manager.conf&lt;/code&gt;, &lt;code&gt;scheduler.conf&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;컨트롤 플레인 컴포넌트 인증&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: CA 인증서는 10년이지만 그 외 leaf 인증서는 모두 &lt;strong&gt;1년&lt;/strong&gt;입니다. CA가 만료되면 클러스터 재설치 수준의 작업이 필요하니, leaf 인증서 갱신 시 CA 만료일도 함께 확인해야 합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-인증서-만료일-확인하기"&gt;
 🔍 인증서 만료일 확인하기
 &lt;a class="heading-anchor" href="#-%ec%9d%b8%ec%a6%9d%ec%84%9c-%eb%a7%8c%eb%a3%8c%ec%9d%bc-%ed%99%95%ec%9d%b8%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="kubeadm으로-확인"&gt;
 kubeadm으로 확인
 &lt;a class="heading-anchor" href="#kubeadm%ec%9c%bc%eb%a1%9c-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;kubeadm certs check-expiration&lt;/code&gt; 명령으로 모든 인증서의 만료일을 한 번에 확인할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm certs check-expiration&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;출력 예시:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;admin.conf May 26, 2027 03:00 UTC 364d ca no
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;apiserver May 26, 2027 03:00 UTC 364d ca no
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;apiserver-kubelet-client May 26, 2027 03:00 UTC 364d ca no
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;controller-manager.conf May 26, 2027 03:00 UTC 364d ca no
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;etcd-server May 26, 2027 03:00 UTC 364d etcd-ca no
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;front-proxy-client May 26, 2027 03:00 UTC 364d front-proxy-ca no
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;scheduler.conf May 26, 2027 03:00 UTC 364d ca no
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;ca May 24, 2036 03:00 UTC 9y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;etcd-ca May 24, 2036 03:00 UTC 9y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;front-proxy-ca May 24, 2036 03:00 UTC 9y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="openssl로-개별-확인"&gt;
 openssl로 개별 확인
 &lt;a class="heading-anchor" href="#openssl%eb%a1%9c-%ea%b0%9c%eb%b3%84-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;특정 인증서만 빠르게 확인하고 싶다면 &lt;code&gt;openssl&lt;/code&gt;을 사용합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -enddate
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# notAfter=May 26 03:00:00 2027 GMT&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-수동-갱신-방법"&gt;
 🛠️ 수동 갱신 방법
 &lt;a class="heading-anchor" href="#-%ec%88%98%eb%8f%99-%ea%b0%b1%ec%8b%a0-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;긴급 상황에서는 &lt;code&gt;kubeadm certs renew all&lt;/code&gt;로 즉시 갱신할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 모든 인증서 갱신 (남은 기간과 무관하게 1년 연장)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm certs renew all
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 컨트롤 플레인 Pod 재시작 (정적 Pod이므로 컨테이너만 재기동)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;sudo crictl pods --namespace kube-system &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; --name &lt;span class="s1"&gt;&amp;#39;kube-apiserver-*|kube-controller-manager-*|kube-scheduler-*|etcd-*&amp;#39;&lt;/span&gt; -q &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; xargs sudo crictl rmp -f
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. admin.conf 백업 후 .kube/config 갱신&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;sudo cp /etc/kubernetes/admin.conf /root/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ kubelet 인증서(&lt;code&gt;/var/lib/kubelet/pki/kubelet-client-current.pem&lt;/code&gt;)는 별도로 자동 회전됩니다. &lt;code&gt;kubelet.conf&lt;/code&gt;에 &lt;code&gt;rotateCertificates: true&lt;/code&gt;가 설정되어 있는지 확인하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-systemd-타이머로-자동-갱신-구성하기"&gt;
 ⏰ systemd 타이머로 자동 갱신 구성하기
 &lt;a class="heading-anchor" href="#-systemd-%ed%83%80%ec%9d%b4%eb%a8%b8%eb%a1%9c-%ec%9e%90%eb%8f%99-%ea%b0%b1%ec%8b%a0-%ea%b5%ac%ec%84%b1%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;수동 갱신은 휴먼 에러로 누락되기 쉽습니다.
&lt;strong&gt;매주 월요일 새벽 3시에 만료일을 점검하고, 30일 미만이면 자동으로 갱신&lt;/strong&gt;하는 systemd 타이머를 구성합니다.&lt;/p&gt;
&lt;h3 id="동작-흐름"&gt;
 동작 흐름
 &lt;a class="heading-anchor" href="#%eb%8f%99%ec%9e%91-%ed%9d%90%eb%a6%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;k8s-certs-renew.timer (매주 월 03:00)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; │ 트리거
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;k8s-certs-renew.service (oneshot)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; │ ExecStart
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;/usr/local/bin/kube-scripts/k8s-certs-renew.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; ├─ kubeadm certs check-expiration
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; ├─ 만료까지 30일 미만이면:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; │ ├─ kubeadm certs renew all
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; │ ├─ crictl로 컨트롤 플레인 Pod 재기동
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; │ └─ admin.conf → /root/.kube/config 복사
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; └─ apiserver 기동 대기 (6443 포트)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="1-갱신-스크립트-작성"&gt;
 1️⃣ 갱신 스크립트 작성
 &lt;a class="heading-anchor" href="#1-%ea%b0%b1%ec%8b%a0-%ec%8a%a4%ed%81%ac%eb%a6%bd%ed%8a%b8-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/usr/local/bin/kube-scripts/k8s-certs-renew.sh&lt;/code&gt; 파일을 생성합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;sudo mkdir -p /usr/local/bin/kube-scripts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;sudo tee /usr/local/bin/kube-scripts/k8s-certs-renew.sh &amp;gt; /dev/null &lt;span class="s"&gt;&amp;lt;&amp;lt;&amp;#39;EOF&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;kubeadmCerts=&amp;#39;/usr/local/bin/kubeadm certs&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;getCertValidDays() {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; local earliestExpireDate
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; earliestExpireDate=$(${kubeadmCerts} check-expiration \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; | grep -o &amp;#34;[A-Za-z]\{3,4\}\s\w\w,\s[0-9]\{4,\}\s\w*:\w*\s\w*\s*&amp;#34; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; | xargs -I {} date -d {} +%s | sort | head -n 1)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; local today
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; today=&amp;#34;$(date +%s)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; echo -n $(( (earliestExpireDate - today) / (24 * 60 * 60) ))
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;echo &amp;#34;## Expiration before renewal ##&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;${kubeadmCerts} check-expiration
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;if [ &amp;#34;$(getCertValidDays)&amp;#34; -lt 30 ]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; echo &amp;#34;## Renewing certificates managed by kubeadm ##&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; ${kubeadmCerts} renew all
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; echo &amp;#34;## Restarting control plane pods managed by kubeadm ##&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; crictl pods --namespace kube-system \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; --name &amp;#39;kube-scheduler-*|kube-controller-manager-*|kube-apiserver-*|etcd-*&amp;#39; -q \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; | xargs crictl rmp -f
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; echo &amp;#34;## Updating /root/.kube/config ##&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; cp /etc/kubernetes/admin.conf /root/.kube/config
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;echo &amp;#34;## Waiting for apiserver to be up again ##&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;until printf &amp;#34;&amp;#34; 2&amp;gt;&amp;gt;/dev/null &amp;gt;&amp;gt;/dev/tcp/127.0.0.1/6443; do sleep 1; done
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;echo &amp;#34;## Expiration after renewal ##&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;${kubeadmCerts} check-expiration
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;sudo chmod +x /usr/local/bin/kube-scripts/k8s-certs-renew.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: &lt;code&gt;kubeadm&lt;/code&gt; 바이너리 경로는 환경마다 다릅니다. &lt;code&gt;which kubeadm&lt;/code&gt;으로 확인 후 스크립트의 &lt;code&gt;kubeadmCerts&lt;/code&gt; 변수를 조정하세요. (&lt;code&gt;/usr/bin/kubeadm&lt;/code&gt; 또는 &lt;code&gt;/usr/local/bin/kubeadm&lt;/code&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="2-systemd-서비스-작성"&gt;
 2️⃣ systemd 서비스 작성
 &lt;a class="heading-anchor" href="#2-systemd-%ec%84%9c%eb%b9%84%ec%8a%a4-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/etc/systemd/system/k8s-certs-renew.service&lt;/code&gt; 파일을 생성합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo tee /etc/systemd/system/k8s-certs-renew.service &amp;gt; /dev/null &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;[Unit]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;Description=Renew K8S control plane certificates
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;[Service]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;Type=oneshot
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;ExecStart=/usr/local/bin/kube-scripts/k8s-certs-renew.sh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="3-systemd-타이머-작성"&gt;
 3️⃣ systemd 타이머 작성
 &lt;a class="heading-anchor" href="#3-systemd-%ed%83%80%ec%9d%b4%eb%a8%b8-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/etc/systemd/system/k8s-certs-renew.timer&lt;/code&gt; 파일을 생성합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;sudo tee /etc/systemd/system/k8s-certs-renew.timer &amp;gt; /dev/null &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;[Unit]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;Description=Timer to renew K8S control plane certificates
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;[Timer]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;OnCalendar=Mon *-*-* 03:00:00
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;Unit=k8s-certs-renew.service
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;[Install]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;WantedBy=multi-user.target
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="4-타이머-활성화"&gt;
 4️⃣ 타이머 활성화
 &lt;a class="heading-anchor" href="#4-%ed%83%80%ec%9d%b4%eb%a8%b8-%ed%99%9c%ec%84%b1%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now k8s-certs-renew.timer&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="5-타이머-상태-확인"&gt;
 5️⃣ 타이머 상태 확인
 &lt;a class="heading-anchor" href="#5-%ed%83%80%ec%9d%b4%eb%a8%b8-%ec%83%81%ed%83%9c-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 다음 실행 시각 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;systemctl list-timers k8s-certs-renew.timer
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 서비스 로그 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;journalctl -u k8s-certs-renew.service --no-pager&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;출력 예시:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;NEXT LEFT LAST PASSED UNIT ACTIVATES
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;Mon 2026-06-01 03:00:00 UTC 5d 10h - - k8s-certs-renew.timer k8s-certs-renew.service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-동작-테스트"&gt;
 🧪 동작 테스트
 &lt;a class="heading-anchor" href="#-%eb%8f%99%ec%9e%91-%ed%85%8c%ec%8a%a4%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;실제 만료가 임박하지 않아도 수동으로 서비스를 실행해 동작을 검증할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 수동 실행 (renew 분기는 타지 않고 check-expiration만 출력됨)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl start k8s-certs-renew.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 결과 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;journalctl -u k8s-certs-renew.service -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;만료 30일 미만 조건을 강제로 만들고 싶다면 스크립트의 &lt;code&gt;if [ &amp;quot;$(getCertValidDays)&amp;quot; -lt 30 ]&lt;/code&gt; 부분을 임시로 &lt;code&gt;-lt 9999&lt;/code&gt;로 변경한 뒤 실행 → 동작 확인 후 원복합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-운영-시-주의사항"&gt;
 ⚠️ 운영 시 주의사항
 &lt;a class="heading-anchor" href="#-%ec%9a%b4%ec%98%81-%ec%8b%9c-%ec%a3%bc%ec%9d%98%ec%82%ac%ed%95%ad" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;내용&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;HA 클러스터&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;모든 컨트롤 플레인 노드에 동일한 타이머를 설치해야 합니다. 노드별로 인증서가 따로 발급되어 있습니다.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;CA 만료&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;CA 인증서는 &lt;code&gt;kubeadm certs renew all&lt;/code&gt;로 갱신되지 않습니다. 10년 만료가 가까워지면 별도 절차가 필요합니다.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;kubeconfig 사용자&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/root/.kube/config&lt;/code&gt;만 갱신됩니다. 다른 사용자가 사용하는 kubeconfig도 별도로 업데이트해야 합니다.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;외부 관리 인증서&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;EXTERNALLY MANAGED=yes&lt;/code&gt;로 표시되는 인증서는 갱신되지 않습니다. (예: Vault, cert-manager 발급)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;etcd 백업&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;갱신 작업 전 반드시 etcd 스냅샷을 확보합니다.&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-kubeadm으로-설치하지-않은-클러스터에도-적용-가능한가요"&gt;
 Q. kubeadm으로 설치하지 않은 클러스터에도 적용 가능한가요?
 &lt;a class="heading-anchor" href="#q-kubeadm%ec%9c%bc%eb%a1%9c-%ec%84%a4%ec%b9%98%ed%95%98%ec%a7%80-%ec%95%8a%ec%9d%80-%ed%81%b4%eb%9f%ac%ec%8a%a4%ed%84%b0%ec%97%90%eb%8f%84-%ec%a0%81%ec%9a%a9-%ea%b0%80%eb%8a%a5%ed%95%9c%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;아니요.&lt;/strong&gt; 이 스크립트는 &lt;code&gt;kubeadm certs renew&lt;/code&gt; 명령에 의존합니다. kubespray로 설치한 클러스터는 kubeadm 기반이라 적용 가능하지만, k3s나 RKE2처럼 자체 인증서 관리 메커니즘이 있는 배포판은 각 도구가 제공하는 회전 방식을 사용해야 합니다.&lt;/p&gt;
&lt;h3 id="q-인증서-유효기간을-1년보다-길게-설정할-수-있나요"&gt;
 Q. 인증서 유효기간을 1년보다 길게 설정할 수 있나요?
 &lt;a class="heading-anchor" href="#q-%ec%9d%b8%ec%a6%9d%ec%84%9c-%ec%9c%a0%ed%9a%a8%ea%b8%b0%ea%b0%84%ec%9d%84-1%eb%85%84%eb%b3%b4%eb%8b%a4-%ea%b8%b8%ea%b2%8c-%ec%84%a4%ec%a0%95%ed%95%a0-%ec%88%98-%ec%9e%88%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;가능합니다.&lt;/strong&gt; &lt;code&gt;kubeadm init&lt;/code&gt; 시 &lt;code&gt;--cert-validity-period&lt;/code&gt; 플래그(v1.31+)를 사용하거나 &lt;code&gt;ClusterConfiguration&lt;/code&gt;에서 &lt;code&gt;certificateValidityPeriod&lt;/code&gt;를 설정합니다. 다만 보안 모범 사례는 짧은 주기로 자주 갱신하는 것이라, 1년을 유지하고 자동화를 도입하는 편이 권장됩니다.&lt;/p&gt;
&lt;h3 id="q-갱신-시-클러스터가-중단되나요"&gt;
 Q. 갱신 시 클러스터가 중단되나요?
 &lt;a class="heading-anchor" href="#q-%ea%b0%b1%ec%8b%a0-%ec%8b%9c-%ed%81%b4%eb%9f%ac%ec%8a%a4%ed%84%b0%ea%b0%80-%ec%a4%91%eb%8b%a8%eb%90%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;컨트롤 플레인 Pod 재기동 시 수 초간 API 응답이 지연&lt;/strong&gt;될 수 있지만, 워크로드(Pod)에는 영향이 없습니다. HA 클러스터라면 노드별 타이머를 동일 시각으로 설정하지 말고 5~10분 간격으로 분산하는 것이 안전합니다.&lt;/p&gt;
&lt;h3 id="q-kubelet-인증서는-어떻게-갱신되나요"&gt;
 Q. &lt;code&gt;kubelet&lt;/code&gt; 인증서는 어떻게 갱신되나요?
 &lt;a class="heading-anchor" href="#q-kubelet-%ec%9d%b8%ec%a6%9d%ec%84%9c%eb%8a%94-%ec%96%b4%eb%96%bb%ea%b2%8c-%ea%b0%b1%ec%8b%a0%eb%90%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;kubelet 인증서는 &lt;code&gt;RotateKubeletClientCertificate&lt;/code&gt; 기능 게이트(기본 활성화)에 의해 &lt;strong&gt;자동 회전&lt;/strong&gt;됩니다. &lt;code&gt;kubeadm certs renew&lt;/code&gt;가 관여하지 않습니다. &lt;code&gt;/var/lib/kubelet/pki/&lt;/code&gt; 아래의 &lt;code&gt;kubelet-client-current.pem&lt;/code&gt; 심볼릭 링크가 주기적으로 갱신됩니다.&lt;/p&gt;
&lt;h3 id="q-갱신-후-kubectl-명령이-실패합니다"&gt;
 Q. 갱신 후 &lt;code&gt;kubectl&lt;/code&gt; 명령이 실패합니다.
 &lt;a class="heading-anchor" href="#q-%ea%b0%b1%ec%8b%a0-%ed%9b%84-kubectl-%eb%aa%85%eb%a0%b9%ec%9d%b4-%ec%8b%a4%ed%8c%a8%ed%95%a9%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/etc/kubernetes/admin.conf&lt;/code&gt;의 인증서는 갱신됐지만 사용자 홈의 &lt;code&gt;~/.kube/config&lt;/code&gt;가 갱신되지 않은 경우입니다. 다음 명령으로 동기화합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo cp /etc/kubernetes/admin.conf &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo chown &lt;span class="k"&gt;$(&lt;/span&gt;id -u&lt;span class="k"&gt;)&lt;/span&gt;:&lt;span class="k"&gt;$(&lt;/span&gt;id -g&lt;span class="k"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📚 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/"&gt;Kubernetes 공식 문서: Certificate Management with kubeadm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/setup/best-practices/certificates/"&gt;Kubernetes 공식 문서: PKI certificates and requirements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-certs/"&gt;kubeadm reference: certs renew&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freedesktop.org/software/systemd/man/systemd.timer.html"&gt;systemd.timer 매뉴얼&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] 🔐 OpenSSL로 PFX 인증서 변환 후 Kubernetes TLS Secret 만들기</title><link>https://kyungryeol-yoon.github.io/linux/system/openssl-pfx-to-pem-kubernetes-tls-secret/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/system/openssl-pfx-to-pem-kubernetes-tls-secret/</guid><description>&lt;p&gt;이 글에서는 Windows IIS나 CA에서 발급한 PFX(PKCS#12) 인증서 파일을 OpenSSL 명령으로 개인키(.key)와 인증서 체인(.crt) PEM 파일로 분리하고, 이를 &lt;code&gt;kubectl create secret tls&lt;/code&gt;로 Kubernetes TLS Secret 매니페스트로 변환하는 워크플로우를 단계별로 다룹니다. Ingress·Argo CD 등에서 사용할 TLS Secret을 만들 때 그대로 활용할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-pfxpkcs12-파일이란"&gt;
 📦 PFX(PKCS#12) 파일이란?
 &lt;a class="heading-anchor" href="#-pfxpkcs12-%ed%8c%8c%ec%9d%bc%ec%9d%b4%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;PFX는 PKCS#12 표준을 따르는 바이너리 형식의 인증서 컨테이너입니다. 하나의 파일 안에 &lt;strong&gt;개인키 + 인증서 + 중간 CA 체인&lt;/strong&gt;이 모두 패스워드로 암호화되어 들어 있어, Windows 환경에서 인증서를 백업하거나 이관할 때 주로 사용됩니다.&lt;/p&gt;
&lt;p&gt;반면 Linux 진영(Nginx, HAProxy, Kubernetes Ingress 등)은 일반적으로 PEM 형식의 별도 파일(&lt;code&gt;.key&lt;/code&gt;, &lt;code&gt;.crt&lt;/code&gt;)을 요구합니다. 따라서 PFX를 그대로 사용할 수 없고 OpenSSL로 변환해야 합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;PFX (PKCS#12)&lt;/th&gt;
					&lt;th&gt;PEM&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;형식&lt;/td&gt;
					&lt;td&gt;바이너리&lt;/td&gt;
					&lt;td&gt;Base64 텍스트&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;확장자&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;.pfx&lt;/code&gt;, &lt;code&gt;.p12&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;.key&lt;/code&gt;, &lt;code&gt;.crt&lt;/code&gt;, &lt;code&gt;.pem&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;구성&lt;/td&gt;
					&lt;td&gt;키 + 인증서 + 체인 통합&lt;/td&gt;
					&lt;td&gt;파일별 분리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;암호화&lt;/td&gt;
					&lt;td&gt;항상 패스워드 보호&lt;/td&gt;
					&lt;td&gt;선택적 (키만 암호화 가능)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;주 사용처&lt;/td&gt;
					&lt;td&gt;Windows, IIS&lt;/td&gt;
					&lt;td&gt;Linux, Nginx, Kubernetes&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-사전-준비"&gt;
 🛠️ 사전 준비
 &lt;a class="heading-anchor" href="#-%ec%82%ac%ec%a0%84-%ec%a4%80%eb%b9%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;OpenSSL과 kubectl이 설치되어 있어야 합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;openssl version
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# OpenSSL 3.0.x 이상 권장&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl version --client&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;작업할 PFX 파일과 그 파일의 패스워드를 미리 준비해 둡니다. 이 글에서는 다음과 같은 변수로 진행한다고 가정하겠습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;PFX_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;example.com.pfx&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;PFX_PASS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ChangeMeStrongPass&amp;#34;&lt;/span&gt; &lt;span class="c1"&gt;# PFX 원본 패스워드&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;TMP_PASS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ChangeMeTempPass&amp;#34;&lt;/span&gt; &lt;span class="c1"&gt;# 중간 작업용 임시 패스워드&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;KEY_OUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tls.key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;CRT_OUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;fullchain.crt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;NAMESPACE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;argocd&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;SECRET_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tls-example-com&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ 실제 운영 환경에서는 패스워드를 셸 히스토리에 남기지 않도록 &lt;code&gt;-passin file:...&lt;/code&gt; 또는 환경변수(&lt;code&gt;-passin env:VAR&lt;/code&gt;)를 사용하는 것이 안전합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="1-pfx에서-개인키-추출하기"&gt;
 1️⃣ PFX에서 개인키 추출하기
 &lt;a class="heading-anchor" href="#1-pfx%ec%97%90%ec%84%9c-%ea%b0%9c%ec%9d%b8%ed%82%a4-%ec%b6%94%ec%b6%9c%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;먼저 PFX에서 개인키만 분리합니다. 이 시점에서는 키가 여전히 임시 패스워드(&lt;code&gt;TMP_PASS&lt;/code&gt;)로 암호화된 PEM 형식으로 출력됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;openssl pkcs12 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; -passin pass:&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PFX_PASS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; -passout pass:&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TMP_PASS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; -in &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PFX_FILE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; -nocerts &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; -out tmp.key&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;옵션&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;pkcs12&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;PKCS#12 형식 처리 서브커맨드&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-passin pass:...&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;입력 PFX 파일의 패스워드&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-passout pass:...&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;출력 PEM 키에 적용할 패스워드&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-in&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;입력 PFX 파일 경로&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-nocerts&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;인증서는 제외하고 키만 추출&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-out&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;출력 파일 경로&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: &lt;code&gt;-passout&lt;/code&gt;을 빼면 OpenSSL이 대화형으로 패스워드를 물어봅니다. 자동화 스크립트에서는 명시적으로 지정하는 편이 안정적입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="2-개인키-패스워드-제거-복호화"&gt;
 2️⃣ 개인키 패스워드 제거 (복호화)
 &lt;a class="heading-anchor" href="#2-%ea%b0%9c%ec%9d%b8%ed%82%a4-%ed%8c%a8%ec%8a%a4%ec%9b%8c%eb%93%9c-%ec%a0%9c%ea%b1%b0-%eb%b3%b5%ed%98%b8%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes TLS Secret과 대부분의 Ingress 컨트롤러는 &lt;strong&gt;패스워드가 없는 PEM 키&lt;/strong&gt;를 요구합니다. 따라서 임시 패스워드로 암호화된 키를 평문 RSA 키로 변환합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;openssl rsa &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; -passin pass:&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TMP_PASS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; -in tmp.key &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; -out &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;KEY_OUT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;명령이 성공하면 다음과 같은 메시지가 출력됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;writing RSA key&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;생성된 &lt;code&gt;${KEY_OUT}&lt;/code&gt; 파일은 다음과 같이 시작합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;-----BEGIN RSA PRIVATE KEY-----
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;-----END RSA PRIVATE KEY-----&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ 평문 개인키는 노출 시 즉시 인증서 폐기 사유가 됩니다. 작업이 끝나면 임시 파일(&lt;code&gt;tmp.key&lt;/code&gt;)은 반드시 삭제하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="3-인증서-체인-추출하기"&gt;
 3️⃣ 인증서 체인 추출하기
 &lt;a class="heading-anchor" href="#3-%ec%9d%b8%ec%a6%9d%ec%84%9c-%ec%b2%b4%ec%9d%b8-%ec%b6%94%ec%b6%9c%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;이번에는 키를 제외한 클라이언트 인증서와 중간 CA 인증서를 한 파일로 묶어 추출합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;openssl pkcs12 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; -passin pass:&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PFX_PASS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; -in &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PFX_FILE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; -clcerts &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; -nokeys &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; -out &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CRT_OUT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;옵션&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-clcerts&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;클라이언트(서버) 인증서만 출력&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-nokeys&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;개인키는 제외&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;체인이 분리되어 있어 풀체인(fullchain)으로 묶고 싶다면 &lt;code&gt;-clcerts&lt;/code&gt; 옵션을 빼고, 출력된 인증서 블록 중 필요한 것을 확인해 정렬합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;openssl pkcs12 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; -passin pass:&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PFX_PASS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; -in &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PFX_FILE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; -nokeys &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; -out fullchain.crt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: Ingress에서 SSL Labs A+ 등급을 받으려면 서버 인증서 + 중간 CA 순서로 정렬된 풀체인이 필요합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="4-추출-결과-검증하기"&gt;
 4️⃣ 추출 결과 검증하기
 &lt;a class="heading-anchor" href="#4-%ec%b6%94%ec%b6%9c-%ea%b2%b0%ea%b3%bc-%ea%b2%80%ec%a6%9d%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;변환이 정상적으로 끝났는지 반드시 확인합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;인증서 정보 확인&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;openssl x509 -in &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CRT_OUT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; -noout -subject -issuer -dates&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;subject=CN=example.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;issuer=CN=Internal Issuing CA
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;notBefore=Jan 1 00:00:00 2026 GMT
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;notAfter=Dec 31 23:59:59 2026 GMT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;개인키와 인증서가 한 쌍인지 확인 (모듈러스 비교)&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;diff &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;openssl rsa -in &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;KEY_OUT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; -modulus -noout&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;openssl x509 -in &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CRT_OUT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; -modulus -noout&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;출력이 없으면 같은 쌍입니다. 다르면 잘못된 키/인증서 조합이므로 Secret을 만들어도 TLS 핸드셰이크가 실패합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="5-kubernetes-tls-secret-yaml-만들기"&gt;
 5️⃣ Kubernetes TLS Secret YAML 만들기
 &lt;a class="heading-anchor" href="#5-kubernetes-tls-secret-yaml-%eb%a7%8c%eb%93%a4%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;kubectl create secret tls&lt;/code&gt;에 &lt;code&gt;--dry-run=client -o yaml&lt;/code&gt;을 붙이면 클러스터에 반영하지 않고 매니페스트만 생성할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create secret tls &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SECRET_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; -n &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NAMESPACE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; --key &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;KEY_OUT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; --cert &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CRT_OUT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; --dry-run&lt;span class="o"&gt;=&lt;/span&gt;client -o yaml &amp;gt; tls-example-com.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;생성된 매니페스트는 다음과 같은 형태입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Secret&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tls-example-com&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;argocd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes.io/tls&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls.crt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZ...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls.key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpN...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: Git에 커밋한다면 평문 Secret 대신 &lt;a href="https://github.com/bitnami-labs/sealed-secrets"&gt;Sealed Secrets&lt;/a&gt;나 &lt;a href="https://external-secrets.io/"&gt;External Secrets Operator&lt;/a&gt;로 암호화하는 것이 좋습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="6-클러스터에-적용-및-ingress-연결"&gt;
 6️⃣ 클러스터에 적용 및 Ingress 연결
 &lt;a class="heading-anchor" href="#6-%ed%81%b4%eb%9f%ac%ec%8a%a4%ed%84%b0%ec%97%90-%ec%a0%81%ec%9a%a9-%eb%b0%8f-ingress-%ec%97%b0%ea%b2%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;생성한 매니페스트를 적용합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f tls-example-com.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;kubectl get secret &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SECRET_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; -n &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NAMESPACE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# NAME TYPE DATA AGE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# tls-example-com kubernetes.io/tls 2 5s&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이후 Ingress 리소스에서 &lt;code&gt;tls.secretName&lt;/code&gt;으로 참조합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;networking.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Ingress&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;argocd-server-ingress&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;argocd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ingressClassName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;example.com&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secretName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tls-example-com&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;example.com&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pathType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Prefix&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;backend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;argocd-server&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;443&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-마무리-정리"&gt;
 🧹 마무리 정리
 &lt;a class="heading-anchor" href="#-%eb%a7%88%eb%ac%b4%eb%a6%ac-%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;작업이 끝나면 민감 파일을 안전하게 정리합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;shred -u tmp.key &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;KEY_OUT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; rm -f tmp.key &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;KEY_OUT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;code&gt;shred&lt;/code&gt;는 ext4 등 일부 파일시스템에서만 효과적입니다. SSD·복사본 캐시·tmpfs에서는 완전 삭제가 보장되지 않으므로 작업 디렉터리 자체를 안전한 위치(예: &lt;code&gt;tmpfs&lt;/code&gt; 마운트)로 잡는 편이 좋습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-한-번에-처리하는-스크립트"&gt;
 🚀 한 번에 처리하는 스크립트
 &lt;a class="heading-anchor" href="#-%ed%95%9c-%eb%b2%88%ec%97%90-%ec%b2%98%eb%a6%ac%ed%95%98%eb%8a%94-%ec%8a%a4%ed%81%ac%eb%a6%bd%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;위 단계를 자동화한 예시 스크립트입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; -euo pipefail
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;PFX_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:?usage: &lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="p"&gt; &amp;lt;pfx&amp;gt; &amp;lt;pfx-pass&amp;gt; &amp;lt;namespace&amp;gt; &amp;lt;secret-name&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;PFX_PASS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;NAMESPACE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;SECRET_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;4&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;TMP_PASS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;openssl rand -hex 8&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;WORKDIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;mktemp -d&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;trap&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rm -rf &amp;#34;${WORKDIR}&amp;#34;&amp;#39;&lt;/span&gt; EXIT
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;openssl pkcs12 -passin &lt;span class="s2"&gt;&amp;#34;pass:&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PFX_PASS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -passout &lt;span class="s2"&gt;&amp;#34;pass:&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TMP_PASS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; -in &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PFX_FILE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -nocerts -out &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;WORKDIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/tmp.key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;openssl rsa -passin &lt;span class="s2"&gt;&amp;#34;pass:&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TMP_PASS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; -in &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;WORKDIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/tmp.key&amp;#34;&lt;/span&gt; -out &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;WORKDIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/tls.key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;openssl pkcs12 -passin &lt;span class="s2"&gt;&amp;#34;pass:&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PFX_PASS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; -in &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PFX_FILE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -nokeys -out &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;WORKDIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/tls.crt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;kubectl create secret tls &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SECRET_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; -n &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NAMESPACE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; --key &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;WORKDIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/tls.key&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; --cert &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;WORKDIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/tls.crt&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; --dry-run&lt;span class="o"&gt;=&lt;/span&gt;client -o yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q--nodes-옵션을-한-번에-쓰면-되지-않나요"&gt;
 Q. &lt;code&gt;-nodes&lt;/code&gt; 옵션을 한 번에 쓰면 되지 않나요?
 &lt;a class="heading-anchor" href="#q--nodes-%ec%98%b5%ec%85%98%ec%9d%84-%ed%95%9c-%eb%b2%88%ec%97%90-%ec%93%b0%eb%a9%b4-%eb%90%98%ec%a7%80-%ec%95%8a%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;가능합니다. &lt;code&gt;openssl pkcs12 -in file.pfx -nodes -out all.pem&lt;/code&gt; 한 줄로 키와 인증서를 평문으로 함께 추출할 수 있습니다. 다만 키/인증서를 한 파일에 섞으면 &lt;code&gt;kubectl create secret tls&lt;/code&gt;처럼 두 파일을 요구하는 도구에서 다시 분리해야 하므로, 단계별로 추출하는 편이 자동화에 유리합니다.&lt;/p&gt;
&lt;h3 id="q-mac-verify-error-invalid-password-오류가-납니다"&gt;
 Q. &amp;ldquo;Mac verify error: invalid password&amp;rdquo; 오류가 납니다.
 &lt;a class="heading-anchor" href="#q-mac-verify-error-invalid-password-%ec%98%a4%eb%a5%98%ea%b0%80-%eb%82%a9%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;PFX 파일의 패스워드가 틀린 경우입니다. 일부 환경에서는 OpenSSL 3.x에서 구버전 PFX의 해시 알고리즘을 거부하기도 합니다. 이 경우 &lt;code&gt;-legacy&lt;/code&gt; 옵션을 추가해 보세요.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;openssl pkcs12 -legacy -passin pass:... -in file.pfx -out out.pem&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="q-평문-rsa-키와-pkcs8-키-중-어느-쪽을-써야-하나요"&gt;
 Q. 평문 RSA 키와 PKCS#8 키 중 어느 쪽을 써야 하나요?
 &lt;a class="heading-anchor" href="#q-%ed%8f%89%eb%ac%b8-rsa-%ed%82%a4%ec%99%80-pkcs8-%ed%82%a4-%ec%a4%91-%ec%96%b4%eb%8a%90-%ec%aa%bd%ec%9d%84-%ec%8d%a8%ec%95%bc-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;대부분의 Kubernetes Ingress 컨트롤러는 두 형식을 모두 지원합니다. 다만 일부 신규 도구(예: Envoy 일부 빌드)는 PKCS#8을 선호합니다. 변환은 다음과 같이 합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;openssl pkcs8 -topk8 -nocrypt -in tls.key -out tls.pkcs8.key&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="q---dry-runclient와---dry-runserver의-차이는"&gt;
 Q. &lt;code&gt;--dry-run=client&lt;/code&gt;와 &lt;code&gt;--dry-run=server&lt;/code&gt;의 차이는?
 &lt;a class="heading-anchor" href="#q---dry-runclient%ec%99%80---dry-runserver%ec%9d%98-%ec%b0%a8%ec%9d%b4%eb%8a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;client&lt;/code&gt;는 클라이언트(kubectl) 측에서만 매니페스트를 생성하고 API 서버로 보내지 않습니다. &lt;code&gt;server&lt;/code&gt;는 API 서버까지 가서 어드미션 검증을 수행하지만 실제로 저장하지 않습니다. Secret YAML을 만들 때는 &lt;code&gt;client&lt;/code&gt;로 충분합니다.&lt;/p&gt;
&lt;h3 id="q-secret을-만든-뒤-인증서가-갱신되면-어떻게-하나요"&gt;
 Q. Secret을 만든 뒤 인증서가 갱신되면 어떻게 하나요?
 &lt;a class="heading-anchor" href="#q-secret%ec%9d%84-%eb%a7%8c%eb%93%a0-%eb%92%a4-%ec%9d%b8%ec%a6%9d%ec%84%9c%ea%b0%80-%ea%b0%b1%ec%8b%a0%eb%90%98%eb%a9%b4-%ec%96%b4%eb%96%bb%ea%b2%8c-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;같은 이름으로 &lt;code&gt;kubectl create secret tls ... --dry-run=client -o yaml | kubectl apply -f -&lt;/code&gt;를 다시 실행하면 됩니다. Ingress 컨트롤러는 Secret 변경을 감지해 자동으로 새 인증서를 로드합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📚 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.openssl.org/master/man1/openssl-pkcs12/"&gt;OpenSSL pkcs12 공식 문서&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.openssl.org/master/man1/openssl-rsa/"&gt;OpenSSL rsa 공식 문서&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/configuration/secret/#tls-secrets"&gt;Kubernetes TLS Secret 공식 문서&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#-em-secret-tls-em-"&gt;kubectl create secret tls 레퍼런스&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/services-networking/ingress/#tls"&gt;Ingress TLS 설정&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[macOS] 👻 Ghostty 터미널 완전 정복: 설치부터 커스터마이징까지</title><link>https://kyungryeol-yoon.github.io/environment/macos/ghostty-terminal-setup/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/environment/macos/ghostty-terminal-setup/</guid><description>&lt;p&gt;Ghostty는 GPU 가속을 통해 압도적인 속도를 제공하는 최신 터미널입니다.
Apple Silicon의 성능을 100% 활용하기 위한 필수 도구로, 설치부터 커스터마이징까지 핵심만 정리했습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-설치-및-폰트-세팅"&gt;
 🚀 설치 및 폰트 세팅
 &lt;a class="heading-anchor" href="#-%ec%84%a4%ec%b9%98-%eb%b0%8f-%ed%8f%b0%ed%8a%b8-%ec%84%b8%ed%8c%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew install --cask ghostty&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ 반드시 아이콘이 포함된 &lt;strong&gt;Nerd Font&lt;/strong&gt;를 사용해야 이모지 깨짐 현상을 방지할 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;추천 폰트는 &lt;strong&gt;JetBrainsMono Nerd Font&lt;/strong&gt;입니다.
내장된 수백 개의 테마 목록은 아래 명령어로 확인할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ghostty +list-themes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-node--npx-명령어를-찾을-수-없을-때-path-해결법"&gt;
 🛠️ Node / npx 명령어를 찾을 수 없을 때 (PATH 해결법)
 &lt;a class="heading-anchor" href="#-node--npx-%eb%aa%85%eb%a0%b9%ec%96%b4%eb%a5%bc-%ec%b0%be%ec%9d%84-%ec%88%98-%ec%97%86%ec%9d%84-%eb%95%8c-path-%ed%95%b4%ea%b2%b0%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;가장 빈번하게 발생하는 &lt;code&gt;command not found: node&lt;/code&gt; 오류는 환경 변수 설정과 물리적 파일 연결 문제입니다.&lt;/p&gt;
&lt;h3 id="step-1-zshrc-환경-변수-최적화"&gt;
 STEP 1: .zshrc 환경 변수 최적화
 &lt;a class="heading-anchor" href="#step-1-zshrc-%ed%99%98%ea%b2%bd-%eb%b3%80%ec%88%98-%ec%b5%9c%ec%a0%81%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Apple Silicon 기반 맥은 Homebrew 경로가 이전과 다릅니다.
&lt;code&gt;~/.zshrc&lt;/code&gt; 최상단에 아래 설정을 추가합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Homebrew 및 주요 경로를 최우선으로 설정 (중복 경로 방지)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/opt/homebrew/bin:/opt/homebrew/sbin:&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/bin:&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/bin:/usr/local/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Homebrew 환경변수 즉시 로드&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;/opt/homebrew/bin/brew shellenv&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="step-2-그래도-안-된다면-node-재설치"&gt;
 STEP 2: 그래도 안 된다면? Node 재설치
 &lt;a class="heading-anchor" href="#step-2-%ea%b7%b8%eb%9e%98%eb%8f%84-%ec%95%88-%eb%90%9c%eb%8b%a4%eb%a9%b4-node-%ec%9e%ac%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;경로 설정 후에도 문제가 해결되지 않는다면 설치 자체가 깨진 것입니다.
재설치가 가장 확실한 해결책입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew uninstall --ignore-dependencies node
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;brew install node
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;brew link --overwrite node&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: 설정 후에는 단순히 창을 닫지 말고 &lt;code&gt;Cmd + Q&lt;/code&gt;로 Ghostty를 완전히 종료한 뒤 다시 실행하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-단축키-및-설정-즉시-반영"&gt;
 ⌨️ 단축키 및 설정 즉시 반영
 &lt;a class="heading-anchor" href="#-%eb%8b%a8%ec%b6%95%ed%82%a4-%eb%b0%8f-%ec%84%a4%ec%a0%95-%ec%a6%89%ec%8b%9c-%eb%b0%98%ec%98%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Ghostty의 진가는 마우스 없이 모든 것을 제어하는 단축키에서 나옵니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;단축키&lt;/th&gt;
					&lt;th&gt;기능&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Cmd + Shift + ,&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;설정 파일 즉시 반영 (재시작 불필요)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Cmd + D&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;화면 세로 분할&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Cmd + Shift + D&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;화면 가로 분할&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Cmd + W&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;현재 분할 창 닫기&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Cmd + Option + 방향키&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;분할 창 간 이동&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: 설정 파일을 수정한 뒤 &lt;code&gt;Cmd + Shift + ,&lt;/code&gt;로 즉시 반영하는 습관을 들이면 생산성이 크게 향상됩니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-starship-및-디테일-커스터마이징"&gt;
 🎨 Starship 및 디테일 커스터마이징
 &lt;a class="heading-anchor" href="#-starship-%eb%b0%8f-%eb%94%94%ed%85%8c%ec%9d%bc-%ec%bb%a4%ec%8a%a4%ed%84%b0%eb%a7%88%ec%9d%b4%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;터미널 프롬프트의 가독성을 높이기 위한 세부 설정입니다.&lt;/p&gt;
&lt;h3 id="starship-개행빈-줄-제거"&gt;
 Starship 개행(빈 줄) 제거
 &lt;a class="heading-anchor" href="#starship-%ea%b0%9c%ed%96%89%eb%b9%88-%ec%a4%84-%ec%a0%9c%ea%b1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Starship은 기본적으로 명령어 사이에 여백을 둡니다.
&lt;code&gt;~/.config/starship.toml&lt;/code&gt;에서 아래 옵션으로 제거할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;add_newline&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="c"&gt;# 명령어 사이 빈 줄 제거&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;line_break&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c"&gt;# 명령어를 한 줄로 깔끔하게 유지&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="분할-화면-경계선-색상"&gt;
 분할 화면 경계선 색상
 &lt;a class="heading-anchor" href="#%eb%b6%84%ed%95%a0-%ed%99%94%eb%a9%b4-%ea%b2%bd%ea%b3%84%ec%84%a0-%ec%83%89%ec%83%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;경계선을 테마 컬러와 맞추면 훨씬 세련된 환경이 구축됩니다.
&lt;code&gt;~/.config/ghostty/config&lt;/code&gt;에 추가합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;window-divider-color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;#3d59a1&amp;#34; # 테마에 맞는 색상값&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;window-divider-width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문-및-트러블슈팅"&gt;
 ❓ 자주 묻는 질문 및 트러블슈팅
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8-%eb%b0%8f-%ed%8a%b8%eb%9f%ac%eb%b8%94%ec%8a%88%ed%8c%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q1-expo-실행-시-unable-to-run-simctl-code-72-에러"&gt;
 Q1. Expo 실행 시 &amp;lsquo;Unable to run simctl&amp;rsquo; (Code 72) 에러
 &lt;a class="heading-anchor" href="#q1-expo-%ec%8b%a4%ed%96%89-%ec%8b%9c-unable-to-run-simctl-code-72-%ec%97%90%eb%9f%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Xcode 경로 설정이 꼬인 문제입니다. 아래 명령어로 Xcode 위치를 다시 설정하세요.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo xcode-select -s /Applications/Xcode.app/Contents/Developer&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="q2-기본-터미널은-되는데-ghostty에서만-설정이-안-먹는-이유"&gt;
 Q2. 기본 터미널은 되는데 Ghostty에서만 설정이 안 먹는 이유
 &lt;a class="heading-anchor" href="#q2-%ea%b8%b0%eb%b3%b8-%ed%84%b0%eb%af%b8%eb%84%90%ec%9d%80-%eb%90%98%eb%8a%94%eb%8d%b0-ghostty%ec%97%90%ec%84%9c%eb%a7%8c-%ec%84%a4%ec%a0%95%ec%9d%b4-%ec%95%88-%eb%a8%b9%eb%8a%94-%ec%9d%b4%ec%9c%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Ghostty는 성능 최적화를 위해 일부 환경 파일을 생략하고 시작하는 경우가 있습니다.
아래 두 가지 방법을 함께 사용하면 해결됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.zshrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;설정 파일 수동 로드 후 &lt;code&gt;Cmd + Shift + ,&lt;/code&gt;로 즉시 반영합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-요약"&gt;
 ✅ 요약
 &lt;a class="heading-anchor" href="#-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Ghostty 설치 후 &lt;strong&gt;Nerd Font&lt;/strong&gt;를 반드시 적용합니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/.zshrc&lt;/code&gt; 맨 위에 &lt;strong&gt;Homebrew 경로를 최우선으로&lt;/strong&gt; 배치합니다.&lt;/li&gt;
&lt;li&gt;그래도 안 되면 고민하지 말고 &lt;code&gt;brew reinstall node&lt;/code&gt;를 실행합니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Cmd + Shift + ,&lt;/code&gt; 단축키를 활용해 실시간으로 환경을 다듬습니다.&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>[AI] 🤖 바이브 코딩의 핵심: Claude Code 프로젝트 문서 관리 완전 가이드</title><link>https://kyungryeol-yoon.github.io/ai/llm/claude-code-vibe-coding-documentation-guide/</link><pubDate>Tue, 21 Apr 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/ai/llm/claude-code-vibe-coding-documentation-guide/</guid><description>&lt;blockquote&gt;
&lt;p&gt;AI와 함께 개발하는 시대, 코드보다 중요한 건 &lt;strong&gt;문서&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;Claude Code를 활용한 프로젝트에서 문서는 &amp;ldquo;사람이 읽기 위한 기록&amp;quot;이 아니라
**&amp;ldquo;AI가 매 세션마다 기억을 복원하기 위한 장치&amp;rdquo;**입니다.
이 글에서는 어떤 언어, 어떤 프로젝트에서든 통용되는 문서 관리 전략과
실전 프롬프트를 공유합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="1-왜-문서-관리가-바이브-코딩의-핵심인가"&gt;
 1️⃣ 왜 문서 관리가 바이브 코딩의 핵심인가
 &lt;a class="heading-anchor" href="#1-%ec%99%9c-%eb%ac%b8%ec%84%9c-%ea%b4%80%eb%a6%ac%ea%b0%80-%eb%b0%94%ec%9d%b4%eb%b8%8c-%ec%bd%94%eb%94%a9%ec%9d%98-%ed%95%b5%ec%8b%ac%ec%9d%b8%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="ai는-매-세션마다-기억을-잃습니다"&gt;
 AI는 매 세션마다 기억을 잃습니다
 &lt;a class="heading-anchor" href="#ai%eb%8a%94-%eb%a7%a4-%ec%84%b8%ec%85%98%eb%a7%88%eb%8b%a4-%ea%b8%b0%ec%96%b5%ec%9d%84-%ec%9e%83%ec%8a%b5%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;사람은 프로젝트를 며칠 놓아둬도 코드를 보면 &amp;ldquo;아 맞아, 이랬지&amp;rdquo; 하고 감을 되찾습니다.
하지만 AI는 매번 0부터 다시 시작합니다. 이전 세션에서 아무리 좋은 대화를 했어도,
새 세션이 열리면 모든 맥락이 사라집니다.&lt;/p&gt;
&lt;p&gt;이때 &lt;strong&gt;문서가 AI의 장기 기억&lt;/strong&gt; 역할을 합니다.
잘 정리된 문서가 있으면 AI는 몇 초 만에 프로젝트 맥락을 파악하고 작업에 들어갈 수 있습니다.
문서가 없으면 매번 처음부터 설명해야 하고, 그만큼 토큰을 낭비하게 됩니다.&lt;/p&gt;
&lt;h3 id="문서가-곧-토큰입니다"&gt;
 문서가 곧 토큰입니다
 &lt;a class="heading-anchor" href="#%eb%ac%b8%ec%84%9c%ea%b0%80-%ea%b3%a7-%ed%86%a0%ed%81%b0%ec%9e%85%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Claude Code에서 토큰 비용은 &lt;strong&gt;이전 대화 길이에 비례&lt;/strong&gt;합니다.
매 응답마다 이전 대화 전체를 다시 처리하기 때문입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;10턴 대화: 이전 10턴 + 새 요청 → 토큰 적음
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;100턴 대화: 이전 100턴 + 새 요청 → 토큰 많음 (10배)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;문서가 잘 분리되어 있으면 AI가 &amp;ldquo;이 작업은 PLAN.md만 보면 되겠다&amp;quot;고 판단해서
불필요한 파일을 읽지 않습니다. &lt;strong&gt;문서 분리 = 토큰 절약&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;h3 id="사람을-위한-문서-vs-ai를-위한-문서"&gt;
 사람을 위한 문서 vs AI를 위한 문서
 &lt;a class="heading-anchor" href="#%ec%82%ac%eb%9e%8c%ec%9d%84-%ec%9c%84%ed%95%9c-%eb%ac%b8%ec%84%9c-vs-ai%eb%a5%bc-%ec%9c%84%ed%95%9c-%eb%ac%b8%ec%84%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;전통적인 문서화는 &amp;ldquo;나중에 다른 사람이 읽을 때&amp;quot;를 위한 것이었습니다.
AI 시대의 문서화는 &amp;ldquo;5분 후 새 세션의 AI가 읽을 때&amp;quot;를 위한 것입니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;관점&lt;/th&gt;
					&lt;th&gt;사람을 위한 문서&lt;/th&gt;
					&lt;th&gt;AI를 위한 문서&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;목적&lt;/td&gt;
					&lt;td&gt;이해와 커뮤니케이션&lt;/td&gt;
					&lt;td&gt;맥락 복원과 작업 지시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;형식&lt;/td&gt;
					&lt;td&gt;자유롭고 서술적&lt;/td&gt;
					&lt;td&gt;구조화되고 명확&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;업데이트&lt;/td&gt;
					&lt;td&gt;가끔 (릴리즈 때)&lt;/td&gt;
					&lt;td&gt;매 세션마다&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;분리 기준&lt;/td&gt;
					&lt;td&gt;독자별&lt;/td&gt;
					&lt;td&gt;역할별 (질문별)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="2-프로젝트-문서-구조"&gt;
 2️⃣ 프로젝트 문서 구조
 &lt;a class="heading-anchor" href="#2-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%eb%ac%b8%ec%84%9c-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="추천-파일-구성"&gt;
 추천 파일 구성
 &lt;a class="heading-anchor" href="#%ec%b6%94%ec%b2%9c-%ed%8c%8c%ec%9d%bc-%ea%b5%ac%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;어떤 언어, 어떤 프로젝트에서든 이 5개 파일이면 충분합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;my-project/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;├── README.md # &amp;#34;이 프로젝트는 뭐지?&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;├── CLAUDE.md # &amp;#34;어떻게 작업해야 하지?&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;├── PLAN.md # &amp;#34;무엇을 만들어야 하지?&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;├── CHANGELOG.md # &amp;#34;언제 뭐가 바뀌었지?&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;├── DECISIONS.md # &amp;#34;왜 이렇게 했지?&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;└── DESIGN.md # &amp;#34;UI를 어떻게 만들지?&amp;#34; (프론트엔드 프로젝트인 경우)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="각-문서의-역할"&gt;
 각 문서의 역할
 &lt;a class="heading-anchor" href="#%ea%b0%81-%eb%ac%b8%ec%84%9c%ec%9d%98-%ec%97%ad%ed%95%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;핵심은 &lt;strong&gt;각 문서가 하나의 질문에만 답하도록&lt;/strong&gt; 설계하는 것입니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;문서&lt;/th&gt;
					&lt;th&gt;답하는 질문&lt;/th&gt;
					&lt;th&gt;AI가 읽는 시점&lt;/th&gt;
					&lt;th&gt;업데이트 빈도&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;README.md&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;이 프로젝트는 뭐지?&amp;rdquo;&lt;/td&gt;
					&lt;td&gt;새 세션 첫 진입&lt;/td&gt;
					&lt;td&gt;릴리즈 때&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CLAUDE.md&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;어떻게 작업해야 하지?&amp;rdquo;&lt;/td&gt;
					&lt;td&gt;모든 세션에서 항상&lt;/td&gt;
					&lt;td&gt;매 세션&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PLAN.md&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;무엇을 만들어야 하지?&amp;rdquo;&lt;/td&gt;
					&lt;td&gt;기능 구현 시&lt;/td&gt;
					&lt;td&gt;계획 변경 시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CHANGELOG.md&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;언제 뭐가 바뀌었지?&amp;rdquo;&lt;/td&gt;
					&lt;td&gt;버그 추적 시&lt;/td&gt;
					&lt;td&gt;매 작업 완료&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;DECISIONS.md&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;왜 이렇게 했지?&amp;rdquo;&lt;/td&gt;
					&lt;td&gt;구조 변경 고민 시&lt;/td&gt;
					&lt;td&gt;중요 결정 시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;DESIGN.md&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;UI를 어떻게 만들지?&amp;rdquo;&lt;/td&gt;
					&lt;td&gt;UI 작업 시&lt;/td&gt;
					&lt;td&gt;디자인 변경 시&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: 문서가 하나의 거대한 파일이면 AI가 매번 전체를 읽느라 토큰을 낭비합니다.
분리하면 필요한 부분만 읽고 빠르게 작업에 들어갈 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="3-각-문서-작성-가이드"&gt;
 3️⃣ 각 문서 작성 가이드
 &lt;a class="heading-anchor" href="#3-%ea%b0%81-%eb%ac%b8%ec%84%9c-%ec%9e%91%ec%84%b1-%ea%b0%80%ec%9d%b4%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="claudemd--ai의-작업-매뉴얼"&gt;
 CLAUDE.md — AI의 &amp;ldquo;작업 매뉴얼&amp;rdquo;
 &lt;a class="heading-anchor" href="#claudemd--ai%ec%9d%98-%ec%9e%91%ec%97%85-%eb%a7%a4%eb%89%b4%ec%96%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;CLAUDE.md는 Claude Code가 &lt;strong&gt;모든 세션에서 자동으로 읽는 파일&lt;/strong&gt;입니다.
프로젝트 루트에 있으면 Claude Code가 시작할 때 가장 먼저 참고합니다.
&lt;strong&gt;AI의 첫 번째 기억&lt;/strong&gt;이자 가장 중요한 문서입니다.&lt;/p&gt;
&lt;p&gt;포함해야 할 내용:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# 프로젝트명
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 프로젝트 개요
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;한 줄 설명
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 📚 문서 인덱스
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; PLAN.md: 전체 기능 설계 및 개발 일정
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; DESIGN.md: 디자인 시스템 (프론트엔드인 경우)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; CHANGELOG.md: 버전별 변경 이력
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; DECISIONS.md: 중요한 기술적 결정 기록
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 🎯 코딩 규칙
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;(프로젝트 기술 스택에 맞는 규칙)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 📋 현재 진행 상황
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Phase 1: ✅ 완료
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Phase 2: 🔄 진행 중 (어디까지 했는지)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Phase 3: ⬜ 미시작
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 🔄 작업 완료 시 자동 수행 규칙
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;1.&lt;/span&gt; CHANGELOG.md에 변경사항 추가
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;2.&lt;/span&gt; 이 파일의 진행 상황 업데이트
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;3.&lt;/span&gt; git commit 메시지 규칙: feat:, fix:, chore:, docs:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## ⚠️ 알려진 이슈
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;- (현재 해결 중이거나 인지하고 있는 문제들)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: 짧고 가볍게 유지합니다 (200줄 이하 권장). 세부 내용은 다른 문서로 링크하고, &amp;ldquo;현재 진행 상황&amp;quot;은 매 세션마다 업데이트합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="planmd--프로젝트의-설계도"&gt;
 PLAN.md — 프로젝트의 &amp;ldquo;설계도&amp;rdquo;
 &lt;a class="heading-anchor" href="#planmd--%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8%ec%9d%98-%ec%84%a4%ea%b3%84%eb%8f%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;무엇을 만들어야 하는지, 어떤 순서로 만들지를 담는 문서입니다.
기능 정의, 데이터 모델, 화면 구성, 개발 일정이 포함됩니다.&lt;/p&gt;
&lt;p&gt;포함해야 할 내용:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;프로젝트 개요 (목적, 기술 스택)&lt;/li&gt;
&lt;li&gt;핵심 기능 정의&lt;/li&gt;
&lt;li&gt;화면/API/모듈 설계&lt;/li&gt;
&lt;li&gt;데이터 모델 (TypeScript interface, Python dataclass, DB 스키마 등)&lt;/li&gt;
&lt;li&gt;폴더 구조&lt;/li&gt;
&lt;li&gt;Phase별 개발 일정 (체크리스트 형태)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: Phase를 체크리스트(&lt;code&gt;- [ ]&lt;/code&gt;)로 작성하면 진행 추적이 쉽습니다. 너무 길어지면 기능별로 분리(&lt;code&gt;docs/features/&lt;/code&gt;)하는 것을 권장합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="changelogmd--변경-이력-추적"&gt;
 CHANGELOG.md — 변경 이력 추적
 &lt;a class="heading-anchor" href="#changelogmd--%eb%b3%80%ea%b2%bd-%ec%9d%b4%eb%a0%a5-%ec%b6%94%ec%a0%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Keep a Changelog 형식을 사용합니다.
AI가 버그 추적 시 &amp;ldquo;최근에 뭐가 바뀌었지?&amp;ldquo;를 빠르게 파악할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# Changelog
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## [Unreleased]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### Added
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 새로 추가된 기능
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## [1.0.0] - 2026-04-25
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### Added
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 초기 출시
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### Fixed
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;- 수정한 버그&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="decisionsmd--기술-결정-기록"&gt;
 DECISIONS.md — 기술 결정 기록
 &lt;a class="heading-anchor" href="#decisionsmd--%ea%b8%b0%ec%88%a0-%ea%b2%b0%ec%a0%95-%ea%b8%b0%eb%a1%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&amp;ldquo;왜 이 라이브러리를 썼지?&amp;rdquo;, &amp;ldquo;왜 이 구조로 했지?&amp;ldquo;에 대한 답을 남깁니다.
3개월 후 리팩토링할 때 과거의 맥락을 복원하는 데 결정적인 역할을 합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# Architecture Decisions
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 001: 데이터 저장 방식
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 날짜: 2026-04-20
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 상태: 승인됨
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 결정: 서버 없이 로컬 저장
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 이유: 서버 운영비 불필요, 개인정보 미수집
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;- 결과: 기기 간 동기화 불가 (v2.0에서 고려)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="designmd--디자인-일관성-프론트엔드"&gt;
 DESIGN.md — 디자인 일관성 (프론트엔드)
 &lt;a class="heading-anchor" href="#designmd--%eb%94%94%ec%9e%90%ec%9d%b8-%ec%9d%bc%ea%b4%80%ec%84%b1-%ed%94%84%eb%a1%a0%ed%8a%b8%ec%97%94%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;AI는 매번 미세하게 다른 스타일을 생성할 수 있습니다.
DESIGN.md가 있으면 색상, 폰트, 간격, 컴포넌트 규칙을 일관되게 유지할 수 있습니다.&lt;/p&gt;
&lt;p&gt;포함해야 할 내용:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컬러 팔레트 (정확한 hex 코드)&lt;/li&gt;
&lt;li&gt;타이포그래피 (폰트, 사이즈 스케일)&lt;/li&gt;
&lt;li&gt;간격 시스템 (4, 8, 12, 16, 24, 32&amp;hellip;)&lt;/li&gt;
&lt;li&gt;모서리 둥글기 스케일&lt;/li&gt;
&lt;li&gt;컴포넌트별 규칙 (버튼, 카드, 입력 필드)&lt;/li&gt;
&lt;li&gt;애니메이션 가이드&lt;/li&gt;
&lt;li&gt;카피라이팅 톤&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="4-언어별-초기화-프롬프트"&gt;
 4️⃣ 언어별 초기화 프롬프트
 &lt;a class="heading-anchor" href="#4-%ec%96%b8%ec%96%b4%eb%b3%84-%ec%b4%88%ea%b8%b0%ed%99%94-%ed%94%84%eb%a1%ac%ed%94%84%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="공통-프롬프트-모든-프로젝트"&gt;
 공통 프롬프트 (모든 프로젝트)
 &lt;a class="heading-anchor" href="#%ea%b3%b5%ed%86%b5-%ed%94%84%eb%a1%ac%ed%94%84%ed%8a%b8-%eb%aa%a8%eb%93%a0-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;어떤 기술 스택이든 이 프롬프트로 문서 구조를 초기화할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;아래 지시사항을 순서대로 실행해줘.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;## 사전 파악
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;먼저 프로젝트 루트의 모든 설정 파일을 읽고
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;기술 스택, 구조, 현재 상태를 파악해.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;## 생성할 파일
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;### 1. README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;- 프로젝트 소개, 주요 기능, 기술 스택
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;- 설치 및 실행 방법
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;- 뱃지 포함 (기술 스택 기반 자동 감지)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;### 2. CLAUDE.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;- 문서 인덱스
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;- 코딩 규칙 (기술 스택에 맞게 자동 설정)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;- 현재 진행 상황
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;- 작업 완료 시 자동 수행 규칙
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;### 3. PLAN.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;- 프로젝트 개요
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;- 핵심 기능 정의
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;- 데이터 모델
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;- 폴더 구조
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;- Phase별 개발 일정 (체크리스트)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;### 4. CHANGELOG.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;- Keep a Changelog 형식
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;- 현재까지 작업 내용 기반으로 초안
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;### 5. DECISIONS.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;- ADR 형식
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;- 프로젝트에서 파악된 기술 결정 자동 추출
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;## 완료 후
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;각 파일 생성 결과를 체크리스트로 보고&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="react-native--typescript-프로젝트-모바일-앱"&gt;
 React Native / TypeScript 프로젝트 (모바일 앱)
 &lt;a class="heading-anchor" href="#react-native--typescript-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%eb%aa%a8%eb%b0%94%ec%9d%bc-%ec%95%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;아래 지시사항을 순서대로 실행해줘.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;## 사전 파악
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;package.json, tsconfig.json, app.json을 읽고
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;기술 스택과 현재 프로젝트 상태를 파악해.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;## 생성할 파일
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;### 1. README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;- 앱 소개, 주요 기능, 기술 스택
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;- 설치: npm install, npx expo start
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;- 뱃지: React Native, Expo, TypeScript
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;### 2. CLAUDE.md (아래 구조로)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;- 문서 인덱스 (README, PLAN, DESIGN, CHANGELOG, DECISIONS)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;- 코딩 규칙:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; - TypeScript strict mode
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; - 함수형 컴포넌트 + hooks
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; - StyleSheet.create 사용 (인라인 최소화)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; - camelCase (변수), PascalCase (컴포넌트/타입)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;- 현재 진행 상황 (Phase별 체크박스)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;- 작업 완료 시: CHANGELOG 업데이트, 진행 상황 갱신
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;- 커밋 규칙: feat:, fix:, chore:, docs:, refactor:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;### 3. PLAN.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;- 프로젝트 개요 (목적, 플랫폼, 기술 스택)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;- 화면 구성 (탭/스택 네비게이션 구조)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;- 핵심 기능 정의 (우선순위 P0/P1/P2)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;- TypeScript interface 정의
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;- 폴더 구조 (app/, components/, stores/, services/)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;- Phase별 개발 일정 (체크리스트)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;- 배포 요건 (App Store, Google Play)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;### 4. DESIGN.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;- 컬러 팔레트 (hex 코드)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;- 타이포그래피 (폰트, 사이즈 스케일)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;- 간격 시스템 (4/8/12/16/24/32)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;- 모서리 둥글기 스케일
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;- 컴포넌트별 규칙 (버튼, 카드, 입력 필드)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;- 애니메이션 가이드
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;- 다크 모드 대응
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;### 5. CHANGELOG.md + DECISIONS.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;- 현재까지 작업 기반으로 초안
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;## 완료 후 체크리스트로 보고&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="python-프로젝트-백엔드-api--데이터--자동화"&gt;
 Python 프로젝트 (백엔드 API / 데이터 / 자동화)
 &lt;a class="heading-anchor" href="#python-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%eb%b0%b1%ec%97%94%eb%93%9c-api--%eb%8d%b0%ec%9d%b4%ed%84%b0--%ec%9e%90%eb%8f%99%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;아래 지시사항을 순서대로 실행해줘.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;## 사전 파악
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;requirements.txt (또는 pyproject.toml, Pipfile),
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;main 진입점, 기존 코드 구조를 읽고 파악해.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;## 생성할 파일
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;### 1. README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;- 프로젝트 소개, 주요 기능
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;- 설치: pip install -r requirements.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;- 실행: python main.py 또는 uvicorn/flask 명령어
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;- 환경 변수 설명 (.env.example 포함)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;- 뱃지: Python 버전, 프레임워크
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;### 2. CLAUDE.md (아래 구조로)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;- 문서 인덱스
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;- 코딩 규칙:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; - PEP 8 준수
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; - Type hints 필수
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; - docstring: Google style
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; - 함수는 단일 책임 원칙
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; - 테스트: pytest 사용
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;- 현재 진행 상황
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;- 작업 완료 시: CHANGELOG 업데이트, pytest 실행
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;- 커밋 규칙: feat:, fix:, chore:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;### 3. PLAN.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;- 프로젝트 개요 (목적, 기술 스택)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;- 핵심 기능/모듈 정의
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;- API 엔드포인트 설계 (REST/GraphQL인 경우)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;- 데이터 모델 (SQLAlchemy/Pydantic/dataclass)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;- 폴더 구조 (app/, models/, services/, utils/, tests/)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;- Phase별 개발 일정 (체크리스트)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;### 4. CHANGELOG.md + DECISIONS.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;- 현재까지 작업 기반으로 초안
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;## 완료 후 체크리스트로 보고&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="swift-프로젝트-ios-네이티브-앱"&gt;
 Swift 프로젝트 (iOS 네이티브 앱)
 &lt;a class="heading-anchor" href="#swift-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-ios-%eb%84%a4%ec%9d%b4%ed%8b%b0%eb%b8%8c-%ec%95%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;아래 지시사항을 순서대로 실행해줘.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;## 사전 파악
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;.xcodeproj 또는 Package.swift, Info.plist,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;기존 Swift 파일 구조를 읽고 파악해.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;## 생성할 파일
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;### 1. README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;- 앱 소개, 주요 기능, 스크린샷 섹션
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;- 요구사항: Xcode 버전, iOS 최소 버전
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;- 빌드: Xcode에서 열고 Run
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;- 뱃지: Swift, iOS, Xcode
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;### 2. CLAUDE.md (아래 구조로)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;- 문서 인덱스
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;- 코딩 규칙:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; - Swift API Design Guidelines 준수
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; - MVVM 또는 SwiftUI+Observable 아키텍처
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; - guard let 우선 사용 (if let보다)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; - Protocol 기반 의존성 주입
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; - 네이밍: camelCase (프로퍼티), PascalCase (타입)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;- 현재 진행 상황
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;- 작업 완료 시: CHANGELOG 업데이트, 빌드 확인
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;- 커밋 규칙: feat:, fix:, chore:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;### 3. PLAN.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;- 앱 개요 (목적, 타겟 iOS 버전)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;- 화면 구성 (NavigationStack/TabView 구조)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;- 핵심 기능 정의
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;- 데이터 모델 (struct, Codable)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;- 폴더 구조 (Views/, Models/, ViewModels/, Services/)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;- Phase별 개발 일정
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;### 4. DESIGN.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;- Color Assets 정의
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;- Typography 스케일
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;- 컴포넌트별 규칙
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;- 다크 모드 대응
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;- SF Symbols 사용 가이드
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;### 5. CHANGELOG.md + DECISIONS.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;## 완료 후 체크리스트로 보고&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="java--kotlin-프로젝트-android--spring-boot"&gt;
 Java / Kotlin 프로젝트 (Android / Spring Boot)
 &lt;a class="heading-anchor" href="#java--kotlin-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-android--spring-boot" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;아래 지시사항을 순서대로 실행해줘.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;## 사전 파악
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;build.gradle (또는 pom.xml), 기존 소스 구조,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;application.properties를 읽고 파악해.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;## 생성할 파일
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;### 1. README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;- 프로젝트 소개, 주요 기능
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;- 요구사항: JDK 버전, Gradle/Maven
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;- 빌드: ./gradlew build (또는 mvn package)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;- 실행: ./gradlew bootRun (Spring) 또는 Android Studio
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;- 뱃지: Java/Kotlin, Spring Boot/Android
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;### 2. CLAUDE.md (아래 구조로)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;- 문서 인덱스
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;- 코딩 규칙:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; - [Android] Kotlin 우선, Jetpack Compose UI
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; - [Spring] Java/Kotlin, 계층 구조 (Controller→Service→Repository)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; - 네이밍: camelCase (메서드), PascalCase (클래스)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; - 예외 처리: 커스텀 Exception 사용
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; - 테스트: JUnit 5 + Mockito
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;- 현재 진행 상황
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;- 작업 완료 시: CHANGELOG 업데이트, 빌드 확인
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;- 커밋 규칙: feat:, fix:, chore:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;### 3. PLAN.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;- 프로젝트 개요
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;- [Android] 화면 구성 (Navigation Graph)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;- [Spring] API 엔드포인트 설계
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;- 데이터 모델 (Entity, DTO)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;- 폴더 구조
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;- Phase별 개발 일정
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;### 4. CHANGELOG.md + DECISIONS.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;## 완료 후 체크리스트로 보고&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="5-보안-가이드-api-key와-환경-변수"&gt;
 5️⃣ 보안 가이드: API Key와 환경 변수
 &lt;a class="heading-anchor" href="#5-%eb%b3%b4%ec%95%88-%ea%b0%80%ec%9d%b4%eb%93%9c-api-key%ec%99%80-%ed%99%98%ea%b2%bd-%eb%b3%80%ec%88%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="ai가-저지르는-보안-실수"&gt;
 AI가 저지르는 보안 실수
 &lt;a class="heading-anchor" href="#ai%ea%b0%80-%ec%a0%80%ec%a7%80%eb%a5%b4%eb%8a%94-%eb%b3%b4%ec%95%88-%ec%8b%a4%ec%88%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;바이브 코딩에서 가장 흔한 보안 사고는 AI가 환경 변수를 잘못 다루는 것입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;실제 사고 사례:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; 1. AI가 .env의 API Key를 코드에 하드코딩
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; 2. AI가 CLAUDE.md에 실제 키 값을 기록
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; 3. AI가 .env 파일을 git commit에 포함
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; 4. AI가 디버깅 중 콘솔에 키를 출력하는 코드 생성
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; 5. AI가 README에 &amp;#34;실행 시 이 키를 넣으세요&amp;#34;라며 실제 값 노출&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ 한번 GitHub에 올라간 키는 &lt;strong&gt;몇 초 내에 봇이 수집&lt;/strong&gt;합니다. 삭제해도 git 히스토리에 남아있어서 완전 제거가 어렵습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="claudemd에-넣어야-할-보안-규칙"&gt;
 CLAUDE.md에 넣어야 할 보안 규칙
 &lt;a class="heading-anchor" href="#claudemd%ec%97%90-%eb%84%a3%ec%96%b4%ec%95%bc-%ed%95%a0-%eb%b3%b4%ec%95%88-%ea%b7%9c%ec%b9%99" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 🔒 보안 규칙 (절대 위반 금지)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### 환경 변수
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; .env, .env.local 파일의 실제 값을 절대 코드나 문서에 기록하지 말 것
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; API Key, Secret, Token, Password를 절대 하드코딩하지 말 것
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 환경 변수는 반드시 process.env.VARIABLE_NAME으로 참조
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 디버깅 시에도 console.log로 환경 변수 값을 출력하지 말 것
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 커밋 전 반드시 .env가 .gitignore에 포함되어 있는지 확인
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### 문서에 적을 때
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 필요한 환경 변수의 &amp;#34;이름&amp;#34;만 기록 (값은 절대 기록 금지)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; .env.example 파일에 빈 값으로 목록만 제공
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### 금지 패턴
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;❌ const API_KEY = &amp;#34;sk-abc123...&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;❌ OPENWEATHER_API_KEY=abc123 (CLAUDE.md에 실제 값)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;❌ console.log(&amp;#34;Key:&amp;#34;, process.env.API_KEY)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;❌ fetch(&lt;span class="sb"&gt;`...?key=abc123...`&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### 허용 패턴
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;✅ const API_KEY = process.env.OPENWEATHER_API_KEY
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;✅ OPENWEATHER_API_KEY=your_key_here (.env.example)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;✅ &amp;#34;환율 API Key가 필요합니다 (.env 참고)&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="envexample-파일-관리"&gt;
 .env.example 파일 관리
 &lt;a class="heading-anchor" href="#envexample-%ed%8c%8c%ec%9d%bc-%ea%b4%80%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;프로젝트에 필요한 환경 변수를 &lt;code&gt;.env.example&lt;/code&gt;에 기록합니다.
이 파일은 git에 포함해도 안전합니다 (실제 값이 없으므로).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# .env.example (git에 포함 OK)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;OPENWEATHER_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_key_here
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;EXCHANGE_RATE_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_key_here
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;GOOGLE_MAPS_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_key_here
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;ADMOB_ANDROID_APP_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ca-app-pub-xxx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;ADMOB_IOS_APP_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ca-app-pub-xxx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# .env (git에 절대 포함 금지)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;OPENWEATHER_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;abc123실제키값
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;EXCHANGE_RATE_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xyz789실제키값&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="gitignore-필수-항목"&gt;
 .gitignore 필수 항목
 &lt;a class="heading-anchor" href="#gitignore-%ed%95%84%ec%88%98-%ed%95%ad%eb%aa%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# .gitignore&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;.env
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;.env.local
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;.env.production
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;.env.*.local
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;*.keystore
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;*.jks
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;*.p12
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;google-services.json
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;GoogleService-Info.plist&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="claudemd에-환경-변수-목록-기록-방법"&gt;
 CLAUDE.md에 환경 변수 목록 기록 방법
 &lt;a class="heading-anchor" href="#claudemd%ec%97%90-%ed%99%98%ea%b2%bd-%eb%b3%80%ec%88%98-%eb%aa%a9%eb%a1%9d-%ea%b8%b0%eb%a1%9d-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 🔑 필요한 환경 변수
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;| 변수명 | 용도 | 발급처 |
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;|--------|------|--------|
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;| OPENWEATHER_API_KEY | 날씨 조회 | openweathermap.org |
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;| EXCHANGE_RATE_API_KEY | 환율 조회 | exchangerate-api.com |
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;| GOOGLE_MAPS_API_KEY | 지도 (Android) | Google Cloud Console |
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;⚠️ 실제 값은 .env 파일에만 저장. 이 문서에 절대 기록 금지.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;⚠️ .env.example 참고하여 로컬에 .env 파일 생성할 것.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="언어별-환경-변수-참조-방식"&gt;
 언어별 환경 변수 참조 방식
 &lt;a class="heading-anchor" href="#%ec%96%b8%ec%96%b4%eb%b3%84-%ed%99%98%ea%b2%bd-%eb%b3%80%ec%88%98-%ec%b0%b8%ec%a1%b0-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Python&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;OPENWEATHER_API_KEY&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 또는 python-dotenv 사용&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// TypeScript / React Native
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EXPO_PUBLIC_OPENWEATHER_API_KEY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Expo에서는 EXPO_PUBLIC_ 접두사 필요
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-swift" data-lang="swift"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Swift (iOS)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;apiKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ProcessInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;processInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;OPENWEATHER_API_KEY&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 또는 xcconfig 파일 사용&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Java / Kotlin (Android)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;apiKey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BuildConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;OPENWEATHER_API_KEY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;gradle에서&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;참조&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="만약-키가-노출됐다면"&gt;
 만약 키가 노출됐다면
 &lt;a class="heading-anchor" href="#%eb%a7%8c%ec%95%bd-%ed%82%a4%ea%b0%80-%eb%85%b8%ec%b6%9c%eb%90%90%eb%8b%a4%eb%a9%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;1. 즉시 해당 서비스에서 키 재발급 (기존 키 비활성화)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;2. git 히스토리에서 제거:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; git filter-branch 또는 BFG Repo-Cleaner 사용
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;3. GitHub에서 &amp;#34;Secret scanning alert&amp;#34; 확인
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;4. .gitignore에 .env 추가 확인
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;5. 새 키로 .env 업데이트&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="6-세션-관리-전략"&gt;
 6️⃣ 세션 관리 전략
 &lt;a class="heading-anchor" href="#6-%ec%84%b8%ec%85%98-%ea%b4%80%eb%a6%ac-%ec%a0%84%eb%9e%b5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="세션의-원리"&gt;
 세션의 원리
 &lt;a class="heading-anchor" href="#%ec%84%b8%ec%85%98%ec%9d%98-%ec%9b%90%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Claude Code의 토큰 비용은 &lt;strong&gt;세션 길이에 비례&lt;/strong&gt;합니다.
한 세션에서 대화가 길어질수록 매 응답마다 이전 대화 전체를 다시 처리해야 하기 때문입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;세션 A (짧은 세션 3개):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; 세션 1: 20턴 → 20턴분 토큰
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; 세션 2: 15턴 → 15턴분 토큰
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; 세션 3: 10턴 → 10턴분 토큰
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;세션 B (긴 세션 1개):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; 45턴 → 1+2+3+...+45 = 누적 1,035턴분 토큰
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt; (이전 대화가 매번 재처리되므로)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;같은 작업이라도 &lt;strong&gt;짧은 세션 여러 개&lt;/strong&gt;가 &lt;strong&gt;긴 세션 하나&lt;/strong&gt;보다 토큰 효율이 좋습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="효율적인-세션-패턴"&gt;
 효율적인 세션 패턴
 &lt;a class="heading-anchor" href="#%ed%9a%a8%ec%9c%a8%ec%a0%81%ec%9d%b8-%ec%84%b8%ec%85%98-%ed%8c%a8%ed%84%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;작업 단위로 세션 분리 (가장 중요):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; 오전: &amp;#34;체크리스트 버그 수정&amp;#34; → exit
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; 오후: &amp;#34;지도 탭 구현&amp;#34; → exit (새 세션)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; 저녁: &amp;#34;문서 정리&amp;#34; → exit (새 세션)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;긴 세션은 /compact로 압축:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; 작업 중 대화가 20턴 넘어가면
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; /compact 실행 → 이전 내용 요약 → 토큰 절약
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;/resume으로 이전 세션 이어하기:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; claude --resume → 세션 목록에서 선택
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;effort 레벨 조절:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; /effort low → 오타 수정, 텍스트 변경
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; /effort medium → 일반 기능 구현 (기본값)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; /effort high → 복잡한 로직, 멀티파일 작업
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; /effort max → 아키텍처 설계, 풀리지 않는 디버깅&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="세션-끊는-타이밍"&gt;
 세션 끊는 타이밍
 &lt;a class="heading-anchor" href="#%ec%84%b8%ec%85%98-%eb%81%8a%eb%8a%94-%ed%83%80%ec%9d%b4%eb%b0%8d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;끊어야 할 때:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; ✅ 하나의 작업/이슈가 완료됐을 때
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; ✅ 다른 주제로 넘어갈 때
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; ✅ 대화가 20~30턴 이상 길어졌을 때
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;유지해야 할 때:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; 🔄 같은 파일을 연속 수정 중일 때
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt; 🔄 디버깅이 진행 중일 때
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt; 🔄 관련된 작업을 연속으로 할 때&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="7-claude-code-자동화-설정"&gt;
 7️⃣ Claude Code 자동화 설정
 &lt;a class="heading-anchor" href="#7-claude-code-%ec%9e%90%eb%8f%99%ed%99%94-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="슬래시-커맨드-등록"&gt;
 슬래시 커맨드 등록
 &lt;a class="heading-anchor" href="#%ec%8a%ac%eb%9e%98%ec%8b%9c-%ec%bb%a4%eb%a7%a8%eb%93%9c-%eb%93%b1%eb%a1%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;~/.claude/commands/&lt;/code&gt; 폴더에 마크다운 파일을 만들면
어떤 프로젝트에서든 &lt;code&gt;/명령어&lt;/code&gt;로 실행할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mkdir -p ~/.claude/commands&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;문서 초기화 커맨드&lt;/strong&gt; (&lt;code&gt;~/.claude/commands/init-docs.md&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# 프로젝트 문서 초기화
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;이 프로젝트에 다음 문서 구조를 생성해줘.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;실행 전 설정 파일들을 읽고 기술 스택을 파악할 것.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 생성할 파일
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;1.&lt;/span&gt; README.md (프로젝트 소개, 기술 스택, 설치 방법)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;2.&lt;/span&gt; CLAUDE.md (문서 인덱스, 코딩 규칙, 진행 상황, 자동 수행 규칙)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;3.&lt;/span&gt; PLAN.md (기능 설계, 데이터 모델, 폴더 구조, 개발 일정)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;4.&lt;/span&gt; CHANGELOG.md (Keep a Changelog 형식)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;5.&lt;/span&gt; DECISIONS.md (ADR 형식)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 규칙
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 기술 스택은 설정 파일에서 자동 감지
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 코딩 규칙은 기술 스택에 맞게 자동 설정
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 기존 파일이 있으면 덮어쓰지 말고 병합 제안
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 완료 후
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;생성 결과를 체크리스트로 보고&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;사용법:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; any-project
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;claude
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;/init-docs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;상태 점검 커맨드&lt;/strong&gt; (&lt;code&gt;~/.claude/commands/check-status.md&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# 프로젝트 상태 점검
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;현재 프로젝트 상태를 점검하고 보고해줘.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 점검 항목
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;1.&lt;/span&gt; CLAUDE.md의 진행 상황이 실제 코드와 일치하는지
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;2.&lt;/span&gt; CHANGELOG.md가 최신인지
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;3.&lt;/span&gt; 알려진 버그나 TODO가 남아있는지
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;4.&lt;/span&gt; 빌드/테스트가 정상적으로 통과하는지
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;5.&lt;/span&gt; 다음으로 해야 할 작업이 뭔지
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 보고 형식
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 현재 상태 요약
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 불일치 항목 (있으면)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;- 다음 작업 추천&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;문서 정리 커맨드&lt;/strong&gt; (&lt;code&gt;~/.claude/commands/clean-docs.md&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# 문서 정리
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;프로젝트의 모든 문서를 점검하고 정리해줘.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 작업
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;1.&lt;/span&gt; 중복된 내용 통합
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;2.&lt;/span&gt; 오래되어 관련 없어진 내용 제거
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;3.&lt;/span&gt; 각 문서의 역할이 명확한지 확인
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;4.&lt;/span&gt; 문서 간 링크가 올바른지 확인
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;5.&lt;/span&gt; 필요하면 새 문서 분리 제안
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 대상 파일
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;README.md, CLAUDE.md, PLAN.md, CHANGELOG.md, DECISIONS.md&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="글로벌-claudemd-설정"&gt;
 글로벌 CLAUDE.md 설정
 &lt;a class="heading-anchor" href="#%ea%b8%80%eb%a1%9c%eb%b2%8c-claudemd-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;~/.claude/CLAUDE.md&lt;/code&gt;에 모든 프로젝트 공통 규칙을 넣어두면
어떤 프로젝트에서든 자동으로 적용됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;touch ~/.claude/CLAUDE.md&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# 글로벌 Claude Code 규칙
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 모든 프로젝트 공통
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### 문서 규칙
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; README.md, CLAUDE.md, CHANGELOG.md는 필수
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 작업 완료 시 CHANGELOG.md 업데이트
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 중요한 결정은 DECISIONS.md에 기록
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### 커밋 메시지
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; feat: 새 기능
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; fix: 버그 수정
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; chore: 설정, 의존성
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; docs: 문서 변경
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; refactor: 리팩토링
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### 작업 스타일
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 큰 작업은 작은 단계로 나눠서 진행
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; 각 단계 완료 후 git commit
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;- 불확실한 부분은 먼저 질문하고 진행&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="8-실전-팁"&gt;
 8️⃣ 실전 팁
 &lt;a class="heading-anchor" href="#8-%ec%8b%a4%ec%a0%84-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="문서-길이-관리"&gt;
 문서 길이 관리
 &lt;a class="heading-anchor" href="#%eb%ac%b8%ec%84%9c-%ea%b8%b8%ec%9d%b4-%ea%b4%80%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;CLAUDE.md: 200줄 이하 (허브 역할, 짧게)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;PLAN.md: 500줄 이하 (넘으면 기능별 분리)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;DESIGN.md: 300줄 이하
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;CHANGELOG: 제한 없음 (시간순 누적)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;DECISIONS: 제한 없음 (결정순 누적)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="문서-간-링크-활용"&gt;
 문서 간 링크 활용
 &lt;a class="heading-anchor" href="#%eb%ac%b8%ec%84%9c-%ea%b0%84-%eb%a7%81%ed%81%ac-%ed%99%9c%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# PLAN.md
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;상세 디자인은 [&lt;span class="nt"&gt;DESIGN.md&lt;/span&gt;](&lt;span class="na"&gt;./DESIGN.md&lt;/span&gt;) 참고.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;AdMob 연기 결정은 [&lt;span class="nt"&gt;DECISIONS.md&lt;/span&gt;](&lt;span class="na"&gt;./DECISIONS.md#003&lt;/span&gt;) 참고.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;AI가 링크를 따라가면서 필요한 정보만 골라 읽을 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="ai에게-문서-업데이트-위임하기"&gt;
 AI에게 문서 업데이트 위임하기
 &lt;a class="heading-anchor" href="#ai%ec%97%90%ea%b2%8c-%eb%ac%b8%ec%84%9c-%ec%97%85%eb%8d%b0%ec%9d%b4%ed%8a%b8-%ec%9c%84%ec%9e%84%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;매번 직접 수정하지 말고 AI에게 맡기면 됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;체크리스트 버그 수정 완료했어.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;CHANGELOG.md에 추가하고,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;CLAUDE.md 진행 상황도 업데이트해줘.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="새-세션-시작-시-컨텍스트-최소화"&gt;
 새 세션 시작 시 컨텍스트 최소화
 &lt;a class="heading-anchor" href="#%ec%83%88-%ec%84%b8%ec%85%98-%ec%8b%9c%ec%9e%91-%ec%8b%9c-%ec%bb%a8%ed%85%8d%ec%8a%a4%ed%8a%b8-%ec%b5%9c%ec%86%8c%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;PLAN.md의 Phase 3 섹션만 읽고,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;예산 탭의 환율 변환 기능을 구현해줘.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: &amp;ldquo;전체를 읽어줘&amp;quot;보다 &amp;ldquo;특정 섹션만 읽어줘&amp;quot;가 토큰을 절약합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="9-정리"&gt;
 9️⃣ 정리
 &lt;a class="heading-anchor" href="#9-%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;바이브 코딩에서 문서 관리는 선택이 아닌 필수입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;문서가 없는 AI 개발:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; 매 세션마다 처음부터 설명
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; → 토큰 낭비
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; → 일관성 없는 코드
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; → 매번 다른 스타일
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;문서가 있는 AI 개발:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; 새 세션에서도 즉시 맥락 파악
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; → 토큰 절약
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; → 일관된 코드
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; → 누적되는 품질&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;시작은 간단합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; my-project
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;claude
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;/init-docs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이 한 줄이면 됩니다.
나머지는 AI가 알아서 해줍니다.
그리고 그 AI가 잘 해주도록 만드는 게 바로 &lt;strong&gt;문서&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;코드는 AI가 쓴다. 문서는 내가 설계한다.&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;이것이 바이브 코딩 시대의 개발자 역할입니다.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[AI Assignment - Python] 🐍 제너레이터 실전 — batch, file reader, infinite ID</title><link>https://kyungryeol-yoon.github.io/backend/python/ai-assignment-python-generator/</link><pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/python/ai-assignment-python-generator/</guid><description>&lt;h2 id="-과제-개요"&gt;
 🎯 과제 개요
 &lt;a class="heading-anchor" href="#-%ea%b3%bc%ec%a0%9c-%ea%b0%9c%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;데이터 파이프라인에서 자주 쓰이는 제너레이터 3개를 구현해봤습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;batch_generator&lt;/code&gt; — 데이터를 배치 단위로 나누기&lt;/li&gt;
&lt;li&gt;&lt;code&gt;file_line_reader&lt;/code&gt; — 대용량 파일을 한 줄씩 읽기 (빈 줄 처리 옵션)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;infinite_id_generator&lt;/code&gt; — 무한 고유 ID 생성기&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;요구사항: 모든 함수에 타입 힌트, &lt;code&gt;Generator&lt;/code&gt; 또는 &lt;code&gt;Iterator&lt;/code&gt; 사용, 파일이 없으면 &lt;code&gt;FileNotFoundError&lt;/code&gt; 발생, &lt;code&gt;next()&lt;/code&gt;와 &lt;code&gt;for&lt;/code&gt; 두 방식 모두 테스트.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-제너레이터-기본-개념"&gt;
 📌 제너레이터 기본 개념
 &lt;a class="heading-anchor" href="#-%ec%a0%9c%eb%84%88%eb%a0%88%ec%9d%b4%ed%84%b0-%ea%b8%b0%eb%b3%b8-%ea%b0%9c%eb%85%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;제너레이터는 값을 한 번에 다 만들지 않고, 필요할 때 하나씩 만들어내는 함수입니다. &lt;code&gt;return&lt;/code&gt; 대신 &lt;code&gt;yield&lt;/code&gt;를 사용합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 일반 함수 — 리스트를 통째로 메모리에 올림&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_numbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="c1"&gt;# 1억 개면 메모리 폭발&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 제너레이터 — 하나씩 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;gen_numbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="c1"&gt;# 1억 개여도 메모리 1개분만 사용&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="1-batch_generator"&gt;
 1️⃣ batch_generator
 &lt;a class="heading-anchor" href="#1-batch_generator" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1차-시도"&gt;
 1차 시도
 &lt;a class="heading-anchor" href="#1%ec%b0%a8-%ec%8b%9c%eb%8f%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;batch_generator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;동작은 맞지만 &lt;code&gt;range(len(data))&lt;/code&gt;를 만들어놓고 대부분 버립니다. 10개 데이터면 &lt;code&gt;range(10)&lt;/code&gt;이지만 실제로 필요한 건 4번 루프뿐입니다.&lt;/p&gt;
&lt;h3 id="-개선-range의-step-인자-활용"&gt;
 ✅ 개선: &lt;code&gt;range&lt;/code&gt;의 step 인자 활용
 &lt;a class="heading-anchor" href="#-%ea%b0%9c%ec%84%a0-range%ec%9d%98-step-%ec%9d%b8%ec%9e%90-%ed%99%9c%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;range(start, stop, step)&lt;/code&gt;의 세 번째 인자로 증가폭을 지정할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;batch_generator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Iterator&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="c1"&gt;# 0, 3, 6, 9&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;슬라이싱이 범위를 초과해도 에러 없이 잘라주기 때문에(&lt;code&gt;data[9:12]&lt;/code&gt; → &lt;code&gt;[9]&lt;/code&gt;), 조건문도 &lt;code&gt;return&lt;/code&gt;도 필요하지 않습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="2-file_line_reader"&gt;
 2️⃣ file_line_reader
 &lt;a class="heading-anchor" href="#2-file_line_reader" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;여러 번 헤맸던 함수입니다. 시도별로 정리합니다.&lt;/p&gt;
&lt;h3 id="1차-시도--두-가지-문제"&gt;
 1차 시도 — 두 가지 문제
 &lt;a class="heading-anchor" href="#1%ec%b0%a8-%ec%8b%9c%eb%8f%84--%eb%91%90-%ea%b0%80%ec%a7%80-%eb%ac%b8%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;file_line_reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;skip_empty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;FileNotFoundError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;파일을 찾을 수 없습니다. 경로를 확인해주세요.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;① &lt;code&gt;skip_empty&lt;/code&gt;를 구현하지 않음.&lt;/strong&gt; 파라미터는 받아놓고 전혀 사용하지 않아 빈 줄이 그대로 출력됩니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;② 에러를 &lt;code&gt;print&lt;/code&gt;로 덮어버림.&lt;/strong&gt; 요구사항은 &amp;ldquo;&lt;code&gt;FileNotFoundError&lt;/code&gt;를 발생시킨다&amp;quot;였는데, &lt;code&gt;try/except&lt;/code&gt;로 잡아서 조용히 처리하고 있었습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 호출자 입장에서&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;file_line_reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;없는파일.csv&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# → &amp;#34;파일을 찾을 수 없습니다&amp;#34; 출력 후 for 루프 0회 실행&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# → 버그가 조용히 숨어버림&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ 에러를 &lt;code&gt;print&lt;/code&gt;로 덮어버리면 호출자는 무엇이 잘못됐는지 알 수 없습니다. 에러는 숨기지 말고 발생시켜서 호출자가 처리하게 해야 합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="2차-시도--skip_empty-의미를-잘못-이해"&gt;
 2차 시도 — &lt;code&gt;skip_empty&lt;/code&gt; 의미를 잘못 이해
 &lt;a class="heading-anchor" href="#2%ec%b0%a8-%ec%8b%9c%eb%8f%84--skip_empty-%ec%9d%98%eb%af%b8%eb%a5%bc-%ec%9e%98%eb%aa%bb-%ec%9d%b4%ed%95%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;file_line_reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;skip_empty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;skip_empty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39; 파일을 찾을 수 없습니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;os.path.exists&lt;/code&gt;로 먼저 체크하도록 바꿨지만 여전히 없을 때 &lt;code&gt;print&lt;/code&gt;만 하고 조용히 끝납니다. 그리고 &lt;code&gt;skip_empty&lt;/code&gt;의 의미를 완전히 잘못 이해했습니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;내가 구현한 의미&lt;/th&gt;
					&lt;th&gt;실제 의미&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;True&lt;/code&gt; → &lt;code&gt;strip()&lt;/code&gt; 적용&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;True&lt;/code&gt; → 빈 줄 건너뛰기&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;False&lt;/code&gt; → &lt;code&gt;strip()&lt;/code&gt; 미적용&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;False&lt;/code&gt; → 빈 줄도 yield&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;strip()&lt;/code&gt;은 &lt;code&gt;skip_empty&lt;/code&gt;와 &lt;strong&gt;무관하게 항상&lt;/strong&gt; 적용되어야 합니다. &lt;code&gt;skip_empty&lt;/code&gt;는 strip 이후 빈 문자열이면 건너뛸지 결정하는 플래그입니다.&lt;/p&gt;
&lt;h3 id="-3차-시도-완성--eafp-패턴"&gt;
 ✅ 3차 시도 (완성) — EAFP 패턴
 &lt;a class="heading-anchor" href="#-3%ec%b0%a8-%ec%8b%9c%eb%8f%84-%ec%99%84%ec%84%b1--eafp-%ed%8c%a8%ed%84%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;file_line_reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;skip_empty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Iterator&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;stripped&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;skip_empty&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;stripped&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# 빈 문자열은 falsy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;stripped&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;EAFP 패턴 적용.&lt;/strong&gt; &lt;code&gt;os.path.exists&lt;/code&gt;로 먼저 체크(LBYL)하지 않고, &lt;code&gt;open()&lt;/code&gt;이 알아서 &lt;code&gt;FileNotFoundError&lt;/code&gt;를 던지도록 둡니다. 이것이 파이썬 철학인 &lt;strong&gt;EAFP(Easier to Ask for Forgiveness than Permission)&lt;/strong&gt; 입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;skip_empty&lt;/code&gt; 올바른 구현.&lt;/strong&gt; &lt;code&gt;strip()&lt;/code&gt;은 항상 적용하고, 빈 문자열이면 &lt;code&gt;continue&lt;/code&gt;로 건너뜁니다. Python에서 빈 문자열은 falsy이므로 &lt;code&gt;not stripped&lt;/code&gt;로 체크할 수 있습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: LBYL(&amp;ldquo;되는지 확인하고 해라&amp;rdquo;)보다 EAFP(&amp;ldquo;일단 해보고 안 되면 예외&amp;rdquo;)가 더 파이썬다운 방식입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="3-infinite_id_generator"&gt;
 3️⃣ infinite_id_generator
 &lt;a class="heading-anchor" href="#3-infinite_id_generator" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;infinite_id_generator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;item&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Iterator&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;04d&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;while True&lt;/code&gt; + &lt;code&gt;yield&lt;/code&gt;로 무한 생성합니다. &lt;code&gt;f&amp;quot;{count:04d}&amp;quot;&lt;/code&gt;는 4자리 0패딩입니다. 제너레이터는 &lt;code&gt;next()&lt;/code&gt; 호출 사이에 상태를 유지하므로 &lt;code&gt;count&lt;/code&gt;가 자동으로 누적됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-실행-결과"&gt;
 ▶️ 실행 결과
 &lt;a class="heading-anchor" href="#-%ec%8b%a4%ed%96%89-%ea%b2%b0%ea%b3%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;=== batch_generator ===
[0, 1, 2]
[3, 4, 5]
[6, 7, 8]
[9]

=== file_line_reader(skip_empty=True) ===
&amp;#39;서울,15.2,45,32.1&amp;#39;
&amp;#39;부산,17.8,61,22.3&amp;#39;
&amp;#39;대구,19.3,38,41.5&amp;#39;
&amp;#39;인천,14.7,55,29.8&amp;#39;

=== file_line_reader(skip_empty=False) ===
&amp;#39;서울,15.2,45,32.1&amp;#39;
&amp;#39;부산,17.8,61,22.3&amp;#39;
&amp;#39;&amp;#39;
&amp;#39;대구,19.3,38,41.5&amp;#39;
&amp;#39;&amp;#39;
&amp;#39;인천,14.7,55,29.8&amp;#39;

=== 없는 파일 ===
FileNotFoundError: [Errno 2] No such file or directory: &amp;#39;nonexistent.csv&amp;#39;

=== infinite_id_generator ===
user_0001
user_0002
user_0003&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="-타입-힌트--generator-vs-iterator"&gt;
 🏷️ 타입 힌트 — &lt;code&gt;Generator&lt;/code&gt; vs &lt;code&gt;Iterator&lt;/code&gt;
 &lt;a class="heading-anchor" href="#-%ed%83%80%ec%9e%85-%ed%9e%8c%ed%8a%b8--generator-vs-iterator" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Generator&lt;/code&gt;의 타입 파라미터는 3개입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Generator&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;YieldType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SendType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ReturnType&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;YieldType&lt;/strong&gt; — &lt;code&gt;yield&lt;/code&gt;로 내보내는 값의 타입&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SendType&lt;/strong&gt; — &lt;code&gt;.send()&lt;/code&gt;로 제너레이터에 값을 보낼 때의 타입&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ReturnType&lt;/strong&gt; — 제너레이터가 끝날 때 &lt;code&gt;return&lt;/code&gt;하는 값의 타입&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;대부분은 YieldType만 신경쓰면 되므로 나머지는 &lt;code&gt;None&lt;/code&gt;으로 두게 됩니다. 더 간결한 방법은 &lt;code&gt;Iterator&lt;/code&gt;를 사용하는 것입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;collections.abc&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Iterator&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;batch_generator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Iterator&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: &lt;code&gt;.send()&lt;/code&gt;나 return 값을 사용할 일이 없다면 &lt;code&gt;Generator[T, None, None]&lt;/code&gt; 대신 &lt;code&gt;Iterator[T]&lt;/code&gt;가 훨씬 깔끔합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-이번-과제에서-배운-것"&gt;
 💡 이번 과제에서 배운 것
 &lt;a class="heading-anchor" href="#-%ec%9d%b4%eb%b2%88-%ea%b3%bc%ec%a0%9c%ec%97%90%ec%84%9c-%eb%b0%b0%ec%9a%b4-%ea%b2%83" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;yield&lt;/code&gt;의 기본 동작:&lt;/strong&gt; 함수가 &lt;code&gt;yield&lt;/code&gt;를 만나면 값을 내보내고 일시정지합니다. 다음 호출에서 그 자리부터 재개합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;range(start, stop, step)&lt;/code&gt;:&lt;/strong&gt; 증가폭을 직접 지정할 수 있습니다. &lt;code&gt;range(0, len(data), batch_size)&lt;/code&gt; 같은 패턴은 파이썬 어디서든 활용됩니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EAFP 패턴:&lt;/strong&gt; &lt;code&gt;os.path.exists&lt;/code&gt;로 먼저 체크(LBYL)하는 대신, 일단 &lt;code&gt;open()&lt;/code&gt;을 시도하고 예외가 발생하면 처리(EAFP)하는 것이 더 파이썬답습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;에러를 숨기지 말기:&lt;/strong&gt; &lt;code&gt;try/except&lt;/code&gt;로 잡아서 &lt;code&gt;print&lt;/code&gt;로 덮는 것은 디버깅을 어렵게 만듭니다. 호출자가 예외를 받아서 처리할 수 있도록 자연스럽게 발생시켜야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;skip_empty&lt;/code&gt; 같은 파라미터의 의미:&lt;/strong&gt; 이름만 보고 추측하지 말고 요구사항을 정확히 읽어야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;타입 힌트 간결하게:&lt;/strong&gt; &lt;code&gt;Generator[T, None, None]&lt;/code&gt; 대신 &lt;code&gt;Iterator[T]&lt;/code&gt;를 사용합시다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-반복해서-나타난-패턴"&gt;
 🔄 반복해서 나타난 패턴
 &lt;a class="heading-anchor" href="#-%eb%b0%98%eb%b3%b5%ed%95%b4%ec%84%9c-%eb%82%98%ed%83%80%eb%82%9c-%ed%8c%a8%ed%84%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;세 과제를 진행하면서 반복적으로 마주친 두 가지 패턴이 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;① 하드코딩 의존:&lt;/strong&gt; &lt;code&gt;result == 'done'&lt;/code&gt;, &lt;code&gt;isinstance(arg, int)&lt;/code&gt;, &lt;code&gt;skip_empty&lt;/code&gt; 오해 — 전부 특정 값이나 상황에 의존하는 코드를 작성하는 습관입니다. 범용 함수를 만들 때는 의도적으로 추상화해야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;② 에러 숨김:&lt;/strong&gt; 에러를 값으로 반환하거나 &lt;code&gt;print&lt;/code&gt; 후 조용히 종료하면 호출자는 무엇이 잘못됐는지 알 수 없습니다. 예외는 적절한 레이어에서 처리되어야 합니다.&lt;/p&gt;</description></item><item><title>[AI Assignment - Python] 🎀 데코레이터 완전 정복 — timer, retry, validate_types 직접 구현</title><link>https://kyungryeol-yoon.github.io/backend/python/ai-assignment-python-decorator-timer-retry-validate/</link><pubDate>Tue, 14 Apr 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/python/ai-assignment-python-decorator-timer-retry-validate/</guid><description>&lt;h2 id="-과제-실무형-데코레이터-3개-구현"&gt;
 🎯 과제: 실무형 데코레이터 3개 구현
 &lt;a class="heading-anchor" href="#-%ea%b3%bc%ec%a0%9c-%ec%8b%a4%eb%ac%b4%ed%98%95-%eb%8d%b0%ec%bd%94%eb%a0%88%ec%9d%b4%ed%84%b0-3%ea%b0%9c-%ea%b5%ac%ed%98%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;@timer&lt;/code&gt; — 함수 실행 시간 측정&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@retry(max_attempts=3)&lt;/code&gt; — 실패 시 자동 재시도&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@validate_types&lt;/code&gt; — 타입 힌트 기반 런타임 타입 검증&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;모든 데코레이터에 &lt;code&gt;functools.wraps&lt;/code&gt;를 적용하는 것이 요구사항이었습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-데코레이터-기본-구조"&gt;
 📐 데코레이터 기본 구조
 &lt;a class="heading-anchor" href="#-%eb%8d%b0%ec%bd%94%eb%a0%88%ec%9d%b4%ed%84%b0-%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;과제에 들어가기 전에 먼저 기본 구조를 정리했습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;my_decorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 함수 실행 전에 할 일&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 함수 실행 후에 할 일&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;wrapper&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# @my_decorator는 사실 이것과 같습니다:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# say_hello = my_decorator(say_hello)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;인자를 받는 데코레이터는 한 겹 더 감쌉니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="c1"&gt;# ← 데코레이터 팩토리&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="c1"&gt;# ← 실제 데코레이터&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;wrapper&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;decorator&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="1-timer"&gt;
 1️⃣ @timer
 &lt;a class="heading-anchor" href="#1-timer" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1차-시도"&gt;
 1차 시도
 &lt;a class="heading-anchor" href="#1%ec%b0%a8-%ec%8b%9c%eb%8f%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;running_check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;start_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;end_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;done&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;출력: slow_function 실행 시간: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;end_time&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start_time&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;.2f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;초&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;running_check&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__repr__&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;running_check&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="지적받은-점-3가지"&gt;
 지적받은 점 3가지
 &lt;a class="heading-anchor" href="#%ec%a7%80%ec%a0%81%eb%b0%9b%ec%9d%80-%ec%a0%90-3%ea%b0%80%ec%a7%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;if result == 'done'&lt;/code&gt; 하드코딩:&lt;/strong&gt; 데코레이터는 어떤 함수든 감쌀 수 있어야 합니다. &lt;code&gt;'done'&lt;/code&gt;을 반환하는 함수에서만 작동하면 범용성이 없습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;text&lt;/code&gt;를 반환하고 &lt;code&gt;result&lt;/code&gt;를 소실:&lt;/strong&gt; 원래 함수의 반환값을 돌려줘야 하는데, 출력 문자열을 반환하고 있었습니다. &lt;code&gt;if&lt;/code&gt;를 타지 않으면 &lt;code&gt;text&lt;/code&gt;가 미정의되어 &lt;code&gt;NameError&lt;/code&gt;도 발생합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;데코레이터 안에서 직접 실행:&lt;/strong&gt; &lt;code&gt;print(running_check())&lt;/code&gt; 이 줄 때문에 &lt;code&gt;@timer&lt;/code&gt;가 붙는 순간 함수가 바로 실행됩니다. 데코레이터는 감싼 함수를 반환만 해야 합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 실행 타이밍 이해&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@timer&lt;/span&gt; &lt;span class="c1"&gt;# ← 이 시점에 timer(slow_function) 실행&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;slow_function&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="c1"&gt;# → wrapper를 반환만 해야 함&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;slow_function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# ← 이 시점에 wrapper() 실행&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="2차-시도-완성"&gt;
 2차 시도 (완성)
 &lt;a class="heading-anchor" href="#2%ec%b0%a8-%ec%8b%9c%eb%8f%84-%ec%99%84%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nd"&gt;@wraps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;elapsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 실행 시간: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;elapsed&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;.2f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;초&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;wrapper&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: 핵심 패턴 — wrapper는 &lt;code&gt;result&lt;/code&gt;를 반환, 데코레이터는 &lt;code&gt;wrapper&lt;/code&gt;를 반환합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="2-retry"&gt;
 2️⃣ @retry
 &lt;a class="heading-anchor" href="#2-retry" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1차-시도-1"&gt;
 1차 시도
 &lt;a class="heading-anchor" href="#1%ec%b0%a8-%ec%8b%9c%eb%8f%84-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;retry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;wrapper&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;decorator&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;재시도 로직을 데코레이터 안이 아니라 &lt;code&gt;__main__&lt;/code&gt;에 따로 작성했습니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# __main__에서 직접 재시도 — 데코레이터의 의미가 없어짐&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;check&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;unstable_api_call&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;status&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;ok&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;시도 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 실패: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ 데코레이터의 가치는 호출하는 쪽이 재시도 로직을 몰라도 되게 만드는 것입니다. &lt;code&gt;try/except&lt;/code&gt; + &lt;code&gt;for&lt;/code&gt; 루프가 &lt;code&gt;wrapper&lt;/code&gt; 안에 있어야 합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="2차-시도--return-vs-raise-문제"&gt;
 2차 시도 — return vs raise 문제
 &lt;a class="heading-anchor" href="#2%ec%b0%a8-%ec%8b%9c%eb%8f%84--return-vs-raise-%eb%ac%b8%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;last_exception&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 시도 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 성공&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;last_exception&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 시도 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 실패: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;last_exception&lt;/span&gt; &lt;span class="c1"&gt;# ← 문제!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;3번 다 실패하면:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;result = 서버 응답 없음
type = &amp;lt;class &amp;#39;ConnectionError&amp;#39;&amp;gt; ← 예외 객체가 정상 반환값처럼 돌아옴&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;return last_exception&lt;/code&gt;은 예외를 정상 반환값으로 돌려보냅니다. 호출하는 쪽에서 에러가 발생했는지 알 수가 없습니다.&lt;/p&gt;
&lt;h3 id="3차-시도--바깥-tryexcept-추가-역시-실패"&gt;
 3차 시도 — 바깥 try/except 추가 (역시 실패)
 &lt;a class="heading-anchor" href="#3%ec%b0%a8-%ec%8b%9c%eb%8f%84--%eb%b0%94%ea%b9%a5-tryexcept-%ec%b6%94%ea%b0%80-%ec%97%ad%ec%8b%9c-%ec%8b%a4%ed%8c%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;last_exception&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;last_exception&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;last_exception&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;안쪽 &lt;code&gt;except&lt;/code&gt;가 이미 예외를 처리하기 때문에 바깥 &lt;code&gt;except&lt;/code&gt;까지 예외가 전파되지 않았습니다. 결과적으로 &lt;code&gt;None&lt;/code&gt;이 반환되었습니다.&lt;/p&gt;
&lt;h3 id="4차-시도-완성"&gt;
 4차 시도 (완성)
 &lt;a class="heading-anchor" href="#4%ec%b0%a8-%ec%8b%9c%eb%8f%84-%ec%99%84%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;retry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nd"&gt;@wraps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;last_exception&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 시도 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 성공&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;last_exception&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 시도 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 실패: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;last_exception&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;wrapper&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;decorator&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: 성공하면 &lt;code&gt;return&lt;/code&gt;으로 함수가 즉시 종료됩니다. &lt;code&gt;for&lt;/code&gt;문이 끝까지 다 돌았다는 것 자체가 전부 실패를 의미하므로, &lt;code&gt;for&lt;/code&gt;문 바로 뒤에 &lt;code&gt;raise&lt;/code&gt;만 놓으면 됩니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="3-validate_types"&gt;
 3️⃣ @validate_types
 &lt;a class="heading-anchor" href="#3-validate_types" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1차-시도--int-하드코딩"&gt;
 1차 시도 — int 하드코딩
 &lt;a class="heading-anchor" href="#1%ec%b0%a8-%ec%8b%9c%eb%8f%84--int-%ed%95%98%eb%93%9c%ec%bd%94%eb%94%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_types&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nd"&gt;@wraps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;인자는 정수(int)여야 합니다. 받은 타입: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;wrapper&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;동작은 하지만, 모든 인자가 &lt;code&gt;int&lt;/code&gt;인지만 검사합니다. &lt;code&gt;get_type_hints&lt;/code&gt;와 &lt;code&gt;inspect&lt;/code&gt;를 import 해놓고도 안 쓰고 있었습니다. 이러면 &lt;code&gt;greet(name: str, count: int)&lt;/code&gt; 같은 함수에서 &lt;code&gt;str&lt;/code&gt;을 넣어도 에러가 납니다.&lt;/p&gt;
&lt;h3 id="2차-시도--에러-메시지-문제"&gt;
 2차 시도 — 에러 메시지 문제
 &lt;a class="heading-anchor" href="#2%ec%b0%a8-%ec%8b%9c%eb%8f%84--%ec%97%90%eb%9f%ac-%eb%a9%94%ec%8b%9c%ec%a7%80-%eb%ac%b8%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;param_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hints&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;param_name&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;인자는 정수(int)여야 합니다. 받은 타입: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;로직은 맞았지만 에러 메시지에 두 가지 문제가 있었습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;quot;정수(int)&amp;quot;&lt;/code&gt;가 하드코딩 — &lt;code&gt;str&lt;/code&gt;이어야 하는 파라미터에도 &amp;ldquo;정수(int)여야 합니다&amp;quot;가 출력됨&lt;/li&gt;
&lt;li&gt;&lt;code&gt;type(param_name)&lt;/code&gt; — &lt;code&gt;param_name&lt;/code&gt;은 &lt;code&gt;&amp;quot;a&amp;quot;&lt;/code&gt; 같은 문자열이므로 항상 &lt;code&gt;&amp;lt;class 'str'&amp;gt;&lt;/code&gt;이 나옴. &lt;code&gt;type(value)&lt;/code&gt;를 써야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3차-시도-완성"&gt;
 3차 시도 (완성)
 &lt;a class="heading-anchor" href="#3%ec%b0%a8-%ec%8b%9c%eb%8f%84-%ec%99%84%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_types&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nd"&gt;@wraps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;hints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_type_hints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;param_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hints&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;param_name&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;param_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;의 타입이 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hints&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;param_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;여야 하지만 &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;이 전달됨&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;wrapper&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-실행-결과"&gt;
 ✅ 실행 결과
 &lt;a class="heading-anchor" href="#-%ec%8b%a4%ed%96%89-%ea%b2%b0%ea%b3%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;=== timer ===
slow_function 실행 시간: 1.50초

=== retry ===
unstable_api_call 시도 1/3 실패: 서버 응답 없음
unstable_api_call 시도 2/3 성공

=== validate_types ===
add(1, 2) → 3
add(&amp;#34;1&amp;#34;, &amp;#34;2&amp;#34;) → TypeError: &amp;#39;a&amp;#39;의 타입이 int여야 하지만 str이 전달됨
greet(123, 3) → TypeError: &amp;#39;name&amp;#39;의 타입이 str여야 하지만 int이 전달됨
greet(&amp;#34;hello&amp;#34;, 3) → hellohellohello&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="-functoolswraps는-왜-필요한가"&gt;
 🔍 functools.wraps는 왜 필요한가
 &lt;a class="heading-anchor" href="#-functoolswraps%eb%8a%94-%ec%99%9c-%ed%95%84%ec%9a%94%ed%95%9c%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;처음에는 &lt;code&gt;@wraps&lt;/code&gt; 없이도 &lt;code&gt;func.__name__&lt;/code&gt;이 잘 나와서 필요 없다고 생각했습니다. 하지만 그건 데코레이터 내부에서 &lt;code&gt;func&lt;/code&gt;을 직접 참조하고 있기 때문이었습니다. 문제는 바깥에서 볼 때입니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@timer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;slow_function&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;느린 함수입니다&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# @wraps 없이&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slow_function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# → &amp;#34;wrapper&amp;#34; ← 원래 이름 소실&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slow_function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__doc__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# → None ← docstring 소실&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# @wraps 있으면&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slow_function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# → &amp;#34;slow_function&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slow_function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__doc__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# → &amp;#34;느린 함수입니다&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ FastAPI 같은 프레임워크가 함수의 &lt;code&gt;__name__&lt;/code&gt;과 &lt;code&gt;__doc__&lt;/code&gt;을 읽어서 API 문서를 자동 생성하는데, &lt;code&gt;@wraps&lt;/code&gt;가 없으면 모든 엔드포인트 이름이 &amp;ldquo;wrapper&amp;quot;로 표시됩니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-python-타입-힌트는-런타임에-강제되지-않는다"&gt;
 💡 Python 타입 힌트는 런타임에 강제되지 않는다
 &lt;a class="heading-anchor" href="#-python-%ed%83%80%ec%9e%85-%ed%9e%8c%ed%8a%b8%eb%8a%94-%eb%9f%b0%ed%83%80%ec%9e%84%ec%97%90-%ea%b0%95%ec%a0%9c%eb%90%98%ec%a7%80-%ec%95%8a%eb%8a%94%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;과제 중에 &amp;ldquo;타입 힌트를 넣으면 &lt;code&gt;add(&amp;quot;1&amp;quot;, 2)&lt;/code&gt;에서 바로 에러가 나지 않나요?&amp;ldquo;라는 의문이 생겼습니다. 답은 &lt;strong&gt;아닙니다&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;world&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# → &amp;#34;helloworld&amp;#34; (에러 없음!)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# → 3.8 (int 아닌데 에러 없음!)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Python의 타입 힌트는 그냥 &amp;ldquo;메모&amp;quot;입니다. 실제로 타입을 강제하려면 &lt;code&gt;mypy&lt;/code&gt; 같은 정적 분석 도구를 쓰거나, 이번 과제의 &lt;code&gt;@validate_types&lt;/code&gt;처럼 런타임에 직접 체크해야 합니다. FastAPI가 내부적으로 이런 런타임 검증을 해주는 대표적인 예입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-데코레이터가-왜-필요한가"&gt;
 🤔 데코레이터가 왜 필요한가
 &lt;a class="heading-anchor" href="#-%eb%8d%b0%ec%bd%94%eb%a0%88%ec%9d%b4%ed%84%b0%ea%b0%80-%ec%99%9c-%ed%95%84%ec%9a%94%ed%95%9c%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;과제를 하면서 &amp;ldquo;굳이 데코레이터가 필요한가?&amp;ldquo;라는 의문이 들었습니다. 하지만 &lt;code&gt;@retry&lt;/code&gt; 없이 API 호출 3개를 만든다고 가정하면 답이 나옵니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 데코레이터 없이 — 재시도 로직이 매번 반복&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_openai&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_anthropic&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="c1"&gt;# ← 똑같은 코드&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;anthropic&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 데코레이터로 — 비즈니스 로직만 남음&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@retry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_openai&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@retry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_anthropic&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;anthropic&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;데코레이터의 가치는 &lt;strong&gt;횡단 관심사의 분리&lt;/strong&gt;입니다. 로깅, 인증, 재시도, 캐싱, 타입 검증 같은 건 비즈니스 로직이 아닌데 여기저기서 필요합니다. 이걸 함수마다 반복하는 대신 &lt;code&gt;@&lt;/code&gt; 한 줄로 붙이는 것입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-이번-과제에서-배운-것"&gt;
 📝 이번 과제에서 배운 것
 &lt;a class="heading-anchor" href="#-%ec%9d%b4%eb%b2%88-%ea%b3%bc%ec%a0%9c%ec%97%90%ec%84%9c-%eb%b0%b0%ec%9a%b4-%ea%b2%83" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;데코레이터 기본 패턴:&lt;/strong&gt; &lt;code&gt;wrapper&lt;/code&gt;는 &lt;code&gt;result&lt;/code&gt;를 반환, 데코레이터는 &lt;code&gt;wrapper&lt;/code&gt;를 반환합니다. 데코레이터 안에서 함수를 직접 실행하면 안 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;인자 있는 데코레이터:&lt;/strong&gt; 팩토리 → 데코레이터 → wrapper의 3중 중첩 구조입니다. 키워드 인자로 호출할 때는 이름이 일치해야 하고, 위치 인자로 호출하면 상관없습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;return&lt;/code&gt; vs &lt;code&gt;raise&lt;/code&gt;:&lt;/strong&gt; 예외를 &lt;code&gt;return&lt;/code&gt;하면 정상 반환값처럼 돌아갑니다. 예외는 반드시 &lt;code&gt;raise&lt;/code&gt;로 발생시켜야 호출하는 쪽에서 인지할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;@wraps&lt;/code&gt;의 역할:&lt;/strong&gt; 원래 함수의 &lt;code&gt;__name__&lt;/code&gt;, &lt;code&gt;__doc__&lt;/code&gt; 등 메타데이터를 보존합니다. FastAPI 같은 프레임워크의 자동 문서 생성에 영향을 줍니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;타입 힌트는 메모일 뿐:&lt;/strong&gt; Python은 런타임에 타입을 강제하지 않습니다. &lt;code&gt;get_type_hints()&lt;/code&gt;와 &lt;code&gt;inspect.signature()&lt;/code&gt;로 직접 읽어와야 합니다.&lt;/p&gt;</description></item><item><title>[AI Assignment - Python] 🐍 타입 힌트와 컴프리헨션 — WeatherAnalyzer 클래스 구현기</title><link>https://kyungryeol-yoon.github.io/backend/python/ai-assignment-python-type-hints-comprehension-weather-analyzer/</link><pubDate>Tue, 07 Apr 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/python/ai-assignment-python-type-hints-comprehension-weather-analyzer/</guid><description>&lt;h2 id="-과제-weatheranalyzer-클래스-구현"&gt;
 🎯 과제: WeatherAnalyzer 클래스 구현
 &lt;a class="heading-anchor" href="#-%ea%b3%bc%ec%a0%9c-weatheranalyzer-%ed%81%b4%eb%9e%98%ec%8a%a4-%ea%b5%ac%ed%98%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;첫 번째 과제는 &lt;strong&gt;타입 힌트&lt;/strong&gt;와 &lt;strong&gt;컴프리헨션&lt;/strong&gt;을 활용한 날씨 데이터 분석 클래스 만들기입니다.&lt;/p&gt;
&lt;h3 id="입력-데이터"&gt;
 입력 데이터
 &lt;a class="heading-anchor" href="#%ec%9e%85%eb%a0%a5-%eb%8d%b0%ec%9d%b4%ed%84%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;weather_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;서울&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;date&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2026-04-01&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;temp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;15.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;humidity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pm25&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;32.1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;서울&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;date&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2026-04-02&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;temp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;18.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;humidity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pm25&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;28.7&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;부산&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;date&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2026-04-01&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;temp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;17.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;humidity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;61&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pm25&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;22.3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;부산&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;date&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2026-04-02&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;temp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;20.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;humidity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;58&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pm25&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;19.5&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="요구사항"&gt;
 요구사항
 &lt;a class="heading-anchor" href="#%ec%9a%94%ea%b5%ac%ec%82%ac%ed%95%ad" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;get_city_avg(city)&lt;/code&gt; — 특정 도시의 temp, humidity, pm25 &lt;strong&gt;각각의 평균&lt;/strong&gt;을 딕셔너리로 반환&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_good_air_days(threshold)&lt;/code&gt; — pm25가 threshold 이하인 날만 필터링 (컴프리헨션 사용)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;summary()&lt;/code&gt; — 모든 도시별 평균을 &lt;code&gt;{&amp;quot;서울&amp;quot;: {...}, &amp;quot;부산&amp;quot;: {...}}&lt;/code&gt; 형태로 반환 (딕셔너리 컴프리헨션 사용)&lt;/li&gt;
&lt;li&gt;모든 함수에 타입 힌트 적용&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="1-1차-시도-일단-기억나는-대로-작성"&gt;
 1️⃣ 1차 시도: 일단 기억나는 대로 작성
 &lt;a class="heading-anchor" href="#1-1%ec%b0%a8-%ec%8b%9c%eb%8f%84-%ec%9d%bc%eb%8b%a8-%ea%b8%b0%ec%96%b5%eb%82%98%eb%8a%94-%eb%8c%80%eb%a1%9c-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WeatherAnalyzer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;list_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]]):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list_input&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_city_avg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;temp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;humidity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pm25&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;city&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_good_air_days&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;30.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;pm25&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;]]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;temp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;humidity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pm25&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="리뷰에서-지적받은-점"&gt;
 리뷰에서 지적받은 점
 &lt;a class="heading-anchor" href="#%eb%a6%ac%eb%b7%b0%ec%97%90%ec%84%9c-%ec%a7%80%ec%a0%81%eb%b0%9b%ec%9d%80-%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;타입 힌트 오류:&lt;/strong&gt; &lt;code&gt;dict[str]&lt;/code&gt;은 유효하지 않습니다. &lt;code&gt;dict&lt;/code&gt;는 key와 value 타입을 둘 다 명시해야 합니다. 값이 &lt;code&gt;str&lt;/code&gt;, &lt;code&gt;float&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt; 등 여러 타입이 섞여 있으므로 &lt;code&gt;dict[str, Any]&lt;/code&gt;로 써야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;get_city_avg 로직 오류:&lt;/strong&gt; 가장 큰 실수였습니다. 온도, 습도, 미세먼지를 &lt;strong&gt;합산해서 3으로 나누는&lt;/strong&gt; 의미 없는 계산을 하고 있었습니다. 요구사항은 각 항목의 &lt;strong&gt;도시별 평균&lt;/strong&gt;이었습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 내가 한 것 (틀림)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;temp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;humidity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pm25&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="c1"&gt;# → 의미 없는 숫자&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 기대한 것&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;temp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;18.95&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;humidity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;59.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pm25&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;20.9&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;# → 각 항목별 평균&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;딕셔너리 키 중복 문제:&lt;/strong&gt; 컴프리헨션에서 같은 키(&amp;ldquo;부산&amp;rdquo;)가 여러 번 나오면 마지막 값만 남습니다. 즉 부산 4/1 데이터가 사라집니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;summary의 반환 타입 불일치:&lt;/strong&gt; 리스트로 감싸서 &lt;code&gt;list[dict]&lt;/code&gt;를 반환하고 있었는데, 요구사항은 &lt;code&gt;dict[str, dict]&lt;/code&gt;이었습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="2-2차-시도-로직-수정--dataclass-도전"&gt;
 2️⃣ 2차 시도: 로직 수정 + dataclass 도전
 &lt;a class="heading-anchor" href="#2-2%ec%b0%a8-%ec%8b%9c%eb%8f%84-%eb%a1%9c%ec%a7%81-%ec%88%98%ec%a0%95--dataclass-%eb%8f%84%ec%a0%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dataclass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WeatherAnalyzer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;humidity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pm25&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;list_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]]):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list_input&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_city_avg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;temp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;temp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;city&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;city&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;])},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;humidity&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;humidity&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;city&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;city&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;])},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;pm25&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;pm25&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;city&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;city&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;])},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;]]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;city&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_city_avg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cities&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="좋아진-점"&gt;
 좋아진 점
 &lt;a class="heading-anchor" href="#%ec%a2%8b%ec%95%84%ec%a7%84-%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;항목별 평균을 &lt;strong&gt;따로&lt;/strong&gt; 구하는 방향은 맞았습니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;summary()&lt;/code&gt;에서 &lt;code&gt;get_city_avg()&lt;/code&gt;를 &lt;strong&gt;재활용&lt;/strong&gt;하는 설계도 좋았습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="여전히-남은-문제"&gt;
 여전히 남은 문제
 &lt;a class="heading-anchor" href="#%ec%97%ac%ec%a0%84%ed%9e%88-%eb%82%a8%ec%9d%80-%eb%ac%b8%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;@dataclass 오용:&lt;/strong&gt; &lt;code&gt;@dataclass&lt;/code&gt;는 &lt;code&gt;__init__&lt;/code&gt;을 자동 생성해주는 데코레이터인데, 직접 &lt;code&gt;__init__&lt;/code&gt;을 정의하면 자동생성이 무시됩니다. 위에 선언한 &lt;code&gt;city&lt;/code&gt;, &lt;code&gt;date&lt;/code&gt; 등의 필드도 실제로 사용되지 않았습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;반환 구조:&lt;/strong&gt; &lt;code&gt;dict&lt;/code&gt; 안에 &lt;code&gt;list&lt;/code&gt; 안에 &lt;code&gt;dict&lt;/code&gt; 3개라는 불필요하게 복잡한 구조가 만들어졌습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 내 반환값 (너무 복잡)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;부산&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;temp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;18.95&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;humidity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;59.5&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pm25&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;20.9&lt;/span&gt;&lt;span class="p"&gt;}]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 기대한 반환값 (심플)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;temp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;18.95&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;humidity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;59.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pm25&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;20.9&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;같은 필터링이 6번 반복:&lt;/strong&gt; &lt;code&gt;data['city'] == city&lt;/code&gt; 필터링을 temp, humidity, pm25마다 sum과 len에서 각각 반복하고 있었습니다. 총 6번. 먼저 한 번 필터링하고 재사용하면 됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="3-3차-시도-최종-피드백-반영"&gt;
 3️⃣ 3차 시도 (최종): 피드백 반영
 &lt;a class="heading-anchor" href="#3-3%ec%b0%a8-%ec%8b%9c%eb%8f%84-%ec%b5%9c%ec%a2%85-%ed%94%bc%eb%93%9c%eb%b0%b1-%eb%b0%98%ec%98%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WeatherAnalyzer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;list_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]]):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list_input&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_city_avg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;city_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;city&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;temp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;temp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;city_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;humidity&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;humidity&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;city_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;pm25&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;pm25&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;city_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_good_air_days&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;30.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;pm25&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;]]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;city&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_list_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_city_avg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cities&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="실행-결과"&gt;
 실행 결과
 &lt;a class="heading-anchor" href="#%ec%8b%a4%ed%96%89-%ea%b2%b0%ea%b3%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;get_city_avg(&amp;#39;부산&amp;#39;) → {&amp;#39;temp&amp;#39;: 18.95, &amp;#39;humidity&amp;#39;: 59.5, &amp;#39;pm25&amp;#39;: 20.9}
get_good_air_days(20) → [{&amp;#39;city&amp;#39;: &amp;#39;부산&amp;#39;, &amp;#39;date&amp;#39;: &amp;#39;2026-04-02&amp;#39;, &amp;#39;temp&amp;#39;: 20.1, &amp;#39;humidity&amp;#39;: 58, &amp;#39;pm25&amp;#39;: 19.5}]
summary() → {&amp;#39;부산&amp;#39;: {&amp;#39;temp&amp;#39;: 18.95, ...}, &amp;#39;서울&amp;#39;: {&amp;#39;temp&amp;#39;: 16.85, ...}}&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="-모범답안과-비교"&gt;
 🏆 모범답안과 비교
 &lt;a class="heading-anchor" href="#-%eb%aa%a8%eb%b2%94%eb%8b%b5%ec%95%88%ea%b3%bc-%eb%b9%84%ea%b5%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;리뷰에서 받은 모범답안에는 몇 가지 추가 테크닉이 있었습니다.&lt;/p&gt;
&lt;h3 id="필드-반복을-상수로-제거"&gt;
 필드 반복을 상수로 제거
 &lt;a class="heading-anchor" href="#%ed%95%84%eb%93%9c-%eb%b0%98%eb%b3%b5%ec%9d%84-%ec%83%81%ec%88%98%eb%a1%9c-%ec%a0%9c%ea%b1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WeatherAnalyzer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;FIELDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;temp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;humidity&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;pm25&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_city_avg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;city_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_data&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;city&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;city_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FIELDS&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;FIELDS&lt;/code&gt;를 상수로 정의해두면 필드가 추가되어도 한 곳만 수정하면 됩니다. 딕셔너리 컴프리헨션으로 3줄이 1줄로 줄어듭니다.&lt;/p&gt;
&lt;h3 id="방어-코드"&gt;
 방어 코드
 &lt;a class="heading-anchor" href="#%eb%b0%a9%ec%96%b4-%ec%bd%94%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;city_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;도시 &amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;의 데이터가 없습니다&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ 존재하지 않는 도시를 넣으면 &lt;code&gt;n = 0&lt;/code&gt;이 되어 &lt;code&gt;ZeroDivisionError&lt;/code&gt;가 발생합니다. 실무에서는 이런 엣지 케이스를 항상 고려해야 합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="__repr__-구현"&gt;
 &lt;code&gt;__repr__&lt;/code&gt; 구현
 &lt;a class="heading-anchor" href="#__repr__-%ea%b5%ac%ed%98%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__repr__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;WeatherAnalyzer(&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;건, 도시: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;city&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_data&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;print(analyzer)&lt;/code&gt; 했을 때 객체 정보를 한눈에 볼 수 있어 디버깅에 유용합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-이번-과제에서-배운-것"&gt;
 📝 이번 과제에서 배운 것
 &lt;a class="heading-anchor" href="#-%ec%9d%b4%eb%b2%88-%ea%b3%bc%ec%a0%9c%ec%97%90%ec%84%9c-%eb%b0%b0%ec%9a%b4-%ea%b2%83" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;타입 힌트:&lt;/strong&gt; &lt;code&gt;dict[str]&lt;/code&gt;이 아니라 &lt;code&gt;dict[str, Any]&lt;/code&gt;처럼 key/value 타입을 모두 명시해야 합니다. 모던 Python에서 타입 힌트는 선택이 아닌 사실상 표준입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;컴프리헨션의 함정:&lt;/strong&gt; 딕셔너리 컴프리헨션에서 같은 키가 여러 번 나오면 마지막 값만 남습니다. 데이터를 먼저 그룹핑하고 집계해야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;@dataclass의 용도:&lt;/strong&gt; &lt;code&gt;@dataclass&lt;/code&gt;는 데이터를 담는 클래스에 쓰는 것이지, 로직 중심의 분석 클래스에 억지로 끼워넣을 필요가 없습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;필터링 한 번, 재사용 여러 번:&lt;/strong&gt; 같은 조건의 필터링을 반복하지 말고 변수에 담아서 재사용합니다. 가독성과 성능 모두 좋아집니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: 메서드 안에 &lt;code&gt;print&lt;/code&gt;를 넣지 않는 것이 좋은 습관입니다. 메서드는 값을 반환하고, 출력은 호출하는 쪽에서 결정해야 합니다.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] 🧹 GitHub Actions Runner Pod 디스크 정리: kubectl exec + docker prune 일괄 실행</title><link>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-github-runner-docker-prune-cleanup/</link><pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-github-runner-docker-prune-cleanup/</guid><description>&lt;p&gt;Kubernetes에 올린 GitHub Actions self-hosted runner는 CI 빌드를 반복하면서 Docker 이미지·빌드 캐시가 쌓여 노드 디스크를 가득 채우기 쉽습니다. 이 글에서는 &lt;code&gt;kubectl get pods -l&lt;/code&gt;로 runner Pod를 골라 &lt;code&gt;xargs&lt;/code&gt;로 묶어, &lt;strong&gt;여러 Pod에 한 번에 &lt;code&gt;docker system prune&lt;/code&gt;을 실행하는 한 줄 명령어&lt;/strong&gt;를 분해하고, 안전한 옵션 선택과 CronJob 자동화까지 실무 관점으로 정리합니다.&lt;/p&gt;
&lt;h2 id="-핵심-명령어-한-줄"&gt;
 🎯 핵심 명령어 한 줄
 &lt;a class="heading-anchor" href="#-%ed%95%b5%ec%8b%ac-%eb%aa%85%eb%a0%b9%ec%96%b4-%ed%95%9c-%ec%a4%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get -n github-runner pods -l &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;githubrunner-cs -o name &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; xargs -I &lt;span class="o"&gt;{}&lt;/span&gt; kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; -n github-runner &lt;span class="o"&gt;{}&lt;/span&gt; -c githubrunner-cs -- docker system prune -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이 한 줄은 &lt;code&gt;github-runner&lt;/code&gt; 네임스페이스에서 &lt;code&gt;app=githubrunner-cs&lt;/code&gt; 라벨이 붙은 모든 runner Pod를 찾아, 각 Pod의 &lt;code&gt;githubrunner-cs&lt;/code&gt; 컨테이너 안에서 &lt;code&gt;docker system prune -f&lt;/code&gt;를 실행합니다. 결과적으로 모든 runner의 Docker 찌꺼기를 한 번에 정리합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-왜-runner-pod에-찌꺼기가-쌓일까"&gt;
 🧐 왜 runner Pod에 찌꺼기가 쌓일까?
 &lt;a class="heading-anchor" href="#-%ec%99%9c-runner-pod%ec%97%90-%ec%b0%8c%ea%ba%bc%ea%b8%b0%ea%b0%80-%ec%8c%93%ec%9d%bc%ea%b9%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;self-hosted runner는 CI 빌드마다 Docker 이미지를 받고 빌드 캐시를 남기는데, 이게 정리되지 않고 누적되기 때문입니다.&lt;/strong&gt; 특히 runner Pod 안에서 Docker 빌드를 돌리는 &lt;strong&gt;DinD(Docker-in-Docker)&lt;/strong&gt; 구조에서는 다음이 쌓입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;빌드 중간 단계 이미지와 &lt;strong&gt;dangling 이미지&lt;/strong&gt;(태그가 떨어진 &lt;code&gt;&amp;lt;none&amp;gt;&lt;/code&gt; 이미지)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker build&lt;/code&gt; 과정에서 생기는 &lt;strong&gt;빌드 캐시&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;종료된 컨테이너, 사용하지 않는 네트워크&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;GitHub Actions의 공식 호스티드 runner는 매번 깨끗한 VM에서 시작하지만, &lt;strong&gt;self-hosted runner는 환경이 유지&lt;/strong&gt;되므로 직접 청소하지 않으면 계속 누적됩니다. 결국 노드의 디스크가 가득 차면 &lt;code&gt;ImagePull&lt;/code&gt; 실패나 Pod &lt;code&gt;Evicted&lt;/code&gt;로 이어집니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ 디스크가 이미 가득 찬 뒤에는 Pod가 &lt;code&gt;Evicted&lt;/code&gt;되어 정리 명령조차 못 들어갈 수 있습니다. **주기적 정리(자동화)**가 핵심입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-명령어-한-줄-분해하기"&gt;
 🔬 명령어 한 줄 분해하기
 &lt;a class="heading-anchor" href="#-%eb%aa%85%eb%a0%b9%ec%96%b4-%ed%95%9c-%ec%a4%84-%eb%b6%84%ed%95%b4%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;명령어는 세 토막으로 나눠 보면 명확합니다.&lt;/p&gt;
&lt;h3 id="1-대상-pod-고르기--kubectl-get--l"&gt;
 1️⃣ 대상 Pod 고르기 — &lt;code&gt;kubectl get -l&lt;/code&gt;
 &lt;a class="heading-anchor" href="#1-%eb%8c%80%ec%83%81-pod-%ea%b3%a0%eb%a5%b4%ea%b8%b0--kubectl-get--l" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get -n github-runner pods -l &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;githubrunner-cs -o name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;-l app=githubrunner-cs&lt;/code&gt;는 &lt;strong&gt;label selector&lt;/strong&gt;로 runner Pod만 선택합니다. &lt;code&gt;-o name&lt;/code&gt;은 출력을 &lt;code&gt;pod/이름&lt;/code&gt; 형식으로 단순화해 다음 단계에 넘기기 좋게 만듭니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pod/githubrunner-cs-0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;pod/githubrunner-cs-1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;pod/githubrunner-cs-2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="2-각-pod로-펼치기--xargs--i-"&gt;
 2️⃣ 각 Pod로 펼치기 — &lt;code&gt;xargs -I {}&lt;/code&gt;
 &lt;a class="heading-anchor" href="#2-%ea%b0%81-pod%eb%a1%9c-%ed%8e%bc%ec%b9%98%ea%b8%b0--xargs--i-" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; xargs -I &lt;span class="o"&gt;{}&lt;/span&gt; kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; ... &lt;span class="o"&gt;{}&lt;/span&gt; ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;xargs -I {}&lt;/code&gt;는 앞 단계에서 받은 줄(Pod 이름)을 하나씩 &lt;code&gt;{}&lt;/code&gt; 자리에 끼워 넣어 명령을 &lt;strong&gt;Pod 개수만큼 반복&lt;/strong&gt;합니다. Pod가 3개면 &lt;code&gt;kubectl exec&lt;/code&gt;가 3번 실행됩니다.&lt;/p&gt;
&lt;h3 id="3-컨테이너-안에서-실행--kubectl-exec--c-----docker-"&gt;
 3️⃣ 컨테이너 안에서 실행 — &lt;code&gt;kubectl exec -c ... -- docker ...&lt;/code&gt;
 &lt;a class="heading-anchor" href="#3-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%ec%95%88%ec%97%90%ec%84%9c-%ec%8b%a4%ed%96%89--kubectl-exec--c-----docker-" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; -n github-runner pod/githubrunner-cs-0 -c githubrunner-cs -- docker system prune -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-c githubrunner-cs&lt;/code&gt;: Pod에 컨테이너가 여러 개(예: runner + DinD 사이드카)일 때 &lt;strong&gt;어느 컨테이너에서 실행할지&lt;/strong&gt; 지정합니다. 생략하면 첫 번째 컨테이너에서 실행됩니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--&lt;/code&gt; 뒤가 컨테이너 안에서 실제로 돌릴 명령(&lt;code&gt;docker system prune -f&lt;/code&gt;)입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: Docker 데몬이 별도 사이드카(예: &lt;code&gt;dind&lt;/code&gt;)에 있다면 &lt;code&gt;-c&lt;/code&gt; 값을 그 컨테이너 이름으로 맞춰야 합니다. &lt;code&gt;kubectl get pod &amp;lt;name&amp;gt; -o jsonpath='{.spec.containers[*].name}'&lt;/code&gt;로 컨테이너 이름을 확인하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-docker-system-prune은-정확히-무엇을-지우나"&gt;
 🗑️ docker system prune은 정확히 무엇을 지우나
 &lt;a class="heading-anchor" href="#-docker-system-prune%ec%9d%80-%ec%a0%95%ed%99%95%ed%9e%88-%eb%ac%b4%ec%97%87%ec%9d%84-%ec%a7%80%ec%9a%b0%eb%82%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;docker system prune&lt;/code&gt;은 기본적으로 멈춘 컨테이너·미사용 네트워크·dangling 이미지·미사용 빌드 캐시를 삭제하지만, 볼륨과 태그가 붙은 미사용 이미지는 건드리지 않습니다.&lt;/strong&gt; 옵션에 따라 삭제 범위가 크게 달라지므로 표로 정리합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;명령&lt;/th&gt;
					&lt;th&gt;멈춘 컨테이너&lt;/th&gt;
					&lt;th&gt;dangling 이미지&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;태그된 미사용 이미지&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;빌드 캐시&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;볼륨&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;docker system prune&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;❌&lt;/td&gt;
					&lt;td&gt;✅(미사용)&lt;/td&gt;
					&lt;td&gt;❌&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;docker system prune -a&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅(전체)&lt;/td&gt;
					&lt;td&gt;❌&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;docker system prune -a --volumes&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅(전체)&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt; / &lt;code&gt;--force&lt;/code&gt;: 확인 프롬프트를 건너뜁니다. 스크립트·일괄 실행에는 필수입니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-a&lt;/code&gt; / &lt;code&gt;--all&lt;/code&gt;: dangling뿐 아니라 &lt;strong&gt;컨테이너가 참조하지 않는 모든 이미지&lt;/strong&gt;를 삭제합니다. 디스크는 더 확보되지만, 다음 빌드에서 베이스 이미지를 다시 받아야 합니다(캐시 손실).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--volumes&lt;/code&gt;: 미사용 볼륨까지 삭제합니다. &lt;strong&gt;데이터 유실 위험&lt;/strong&gt;이 있으니 runner 캐시 볼륨 구조를 모르면 쓰지 마세요.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ runner에서는 보통 **&lt;code&gt;docker system prune -f&lt;/code&gt;(기본)**가 안전한 균형점입니다. 디스크를 더 비워야 하면 &lt;code&gt;-a&lt;/code&gt;까지 고려하되, &lt;code&gt;--volumes&lt;/code&gt;는 무엇이 지워지는지 확인 후에만 사용하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-정리-전후-확인하기"&gt;
 🔎 정리 전후 확인하기
 &lt;a class="heading-anchor" href="#-%ec%a0%95%eb%a6%ac-%ec%a0%84%ed%9b%84-%ed%99%95%ec%9d%b8%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;정리 효과를 수치로 확인하려면 &lt;code&gt;docker system df&lt;/code&gt;를 활용합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 특정 runner Pod의 디스크 사용 현황&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; -n github-runner pod/githubrunner-cs-0 -c githubrunner-cs -- docker system df&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;TYPE TOTAL ACTIVE SIZE RECLAIMABLE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;Images 42 5 12.3GB 9.8GB (79%)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;Containers 8 2 1.2GB 0.9GB (75%)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;Local Volumes 15 3 4.1GB 3.0GB (73%)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;Build Cache 120 0 6.5GB 6.5GB (100%)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;RECLAIMABLE&lt;/code&gt; 값이 prune으로 회수 가능한 용량입니다. 노드 디스크 자체는 다음으로 확인합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 노드 파일시스템 사용률&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; -n github-runner pod/githubrunner-cs-0 -c githubrunner-cs -- df -h /&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-cronjob으로-자동화하기"&gt;
 ⏰ CronJob으로 자동화하기
 &lt;a class="heading-anchor" href="#-cronjob%ec%9c%bc%eb%a1%9c-%ec%9e%90%eb%8f%99%ed%99%94%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;수동 실행은 까먹기 쉬우니, &lt;strong&gt;CronJob으로 주기적 정리&lt;/strong&gt;를 거는 것이 실무에서 가장 깔끔합니다. 클러스터 안에서 &lt;code&gt;kubectl&lt;/code&gt;을 실행하려면 해당 명령에 대한 권한(RBAC)이 필요합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# ServiceAccount + RBAC (pods 조회 + exec 권한)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;runner-pruner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;github-runner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Role&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;runner-pruner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;github-runner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;list&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods/exec&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;RoleBinding&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;runner-pruner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;github-runner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;subjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;runner-pruner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;github-runner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;roleRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Role&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;runner-pruner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# CronJob — 매일 새벽 4시에 모든 runner Pod 정리&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;batch/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;CronJob&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;runner-docker-prune&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;github-runner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;0 4 * * *&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 매일 04:00 (클러스터 타임존 기준)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;concurrencyPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Forbid&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jobTemplate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serviceAccountName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;runner-pruner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restartPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Never&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pruner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;bitnami/kubectl:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;/bin/sh&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- -&lt;span class="l"&gt;c&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; kubectl get -n github-runner pods -l app=githubrunner-cs -o name
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; | xargs -I {} kubectl exec -n github-runner {} -c githubrunner-cs
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; -- docker system prune -f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: &lt;code&gt;schedule&lt;/code&gt;의 타임존은 기본적으로 kube-controller-manager 기준(UTC인 경우가 많음)입니다. KST 기준으로 돌리려면 &lt;code&gt;spec.timeZone: &amp;quot;Asia/Seoul&amp;quot;&lt;/code&gt;(Kubernetes 1.27+ 안정화)을 추가하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-한-줄-요약"&gt;
 📝 한 줄 요약
 &lt;a class="heading-anchor" href="#-%ed%95%9c-%ec%a4%84-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;self-hosted GitHub Actions runner는 환경이 유지되어 Docker 이미지·빌드 캐시가 누적되므로 주기적 정리가 필요합니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kubectl get -l ... -o name | xargs -I {} kubectl exec ... -- docker system prune -f&lt;/code&gt;로 &lt;strong&gt;여러 runner Pod를 한 번에&lt;/strong&gt; 정리할 수 있습니다.&lt;/li&gt;
&lt;li&gt;기본 &lt;code&gt;prune -f&lt;/code&gt;가 안전하며, &lt;code&gt;-a&lt;/code&gt;(전체 이미지)·&lt;code&gt;--volumes&lt;/code&gt;(볼륨)는 영향 범위를 이해하고 써야 합니다.&lt;/li&gt;
&lt;li&gt;운영에서는 RBAC + CronJob으로 &lt;strong&gt;자동화&lt;/strong&gt;하는 것이 가장 확실합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-docker-system-prune--f는-실행-중인-컨테이너도-지우나요"&gt;
 Q. &lt;code&gt;docker system prune -f&lt;/code&gt;는 실행 중인 컨테이너도 지우나요?
 &lt;a class="heading-anchor" href="#q-docker-system-prune--f%eb%8a%94-%ec%8b%a4%ed%96%89-%ec%a4%91%ec%9d%b8-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88%eb%8f%84-%ec%a7%80%ec%9a%b0%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;아닙니다. 멈춘(stopped) 컨테이너, dangling 이미지, 미사용 네트워크, 미사용 빌드 캐시만 삭제합니다. 실행 중인 컨테이너와 그것이 사용하는 이미지·볼륨은 보존됩니다.&lt;/p&gt;
&lt;h3 id="q--c-옵션은-꼭-써야-하나요"&gt;
 Q. &lt;code&gt;-c&lt;/code&gt; 옵션은 꼭 써야 하나요?
 &lt;a class="heading-anchor" href="#q--c-%ec%98%b5%ec%85%98%ec%9d%80-%ea%bc%ad-%ec%8d%a8%ec%95%bc-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Pod에 컨테이너가 하나면 생략해도 됩니다. runner + DinD 사이드카처럼 여러 컨테이너가 있으면 Docker 데몬이 있는 컨테이너를 &lt;code&gt;-c&lt;/code&gt;로 지정해야 합니다. 생략 시 첫 번째 컨테이너에서 실행됩니다.&lt;/p&gt;
&lt;h3 id="q-pod가-아주-많을-때-한-번에-돌려도-되나요"&gt;
 Q. Pod가 아주 많을 때 한 번에 돌려도 되나요?
 &lt;a class="heading-anchor" href="#q-pod%ea%b0%80-%ec%95%84%ec%a3%bc-%eb%a7%8e%ec%9d%84-%eb%95%8c-%ed%95%9c-%eb%b2%88%ec%97%90-%eb%8f%8c%eb%a0%a4%eb%8f%84-%eb%90%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;xargs&lt;/code&gt;는 기본적으로 순차 실행이라 안전합니다. 더 빠르게 병렬 실행하려면 &lt;code&gt;xargs -P 4&lt;/code&gt;처럼 동시 실행 수를 지정할 수 있지만, API 서버·노드 부하를 고려해 적당히 제한하세요.&lt;/p&gt;
&lt;h3 id="q-디스크를-더-확보하려면--a를-써야-하나요"&gt;
 Q. 디스크를 더 확보하려면 &lt;code&gt;-a&lt;/code&gt;를 써야 하나요?
 &lt;a class="heading-anchor" href="#q-%eb%94%94%ec%8a%a4%ed%81%ac%eb%a5%bc-%eb%8d%94-%ed%99%95%eb%b3%b4%ed%95%98%eb%a0%a4%eb%a9%b4--a%eb%a5%bc-%ec%8d%a8%ec%95%bc-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;-a&lt;/code&gt;는 태그가 있어도 컨테이너가 참조하지 않는 모든 이미지를 지웁니다. 디스크는 더 비지만 다음 빌드에서 베이스 이미지를 다시 받아야 해 빌드가 느려집니다. 정기 정리는 기본 &lt;code&gt;prune&lt;/code&gt;, 디스크 위기 시에만 &lt;code&gt;-a&lt;/code&gt;를 권장합니다.&lt;/p&gt;
&lt;h3 id="q-arcactions-runner-controller를-쓰면-어떻게-하나요"&gt;
 Q. ARC(Actions Runner Controller)를 쓰면 어떻게 하나요?
 &lt;a class="heading-anchor" href="#q-arcactions-runner-controller%eb%a5%bc-%ec%93%b0%eb%a9%b4-%ec%96%b4%eb%96%bb%ea%b2%8c-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;ARC의 ephemeral runner는 잡마다 Pod가 새로 떠 비교적 깨끗하지만, DinD 캐시를 공유 볼륨에 두는 구성이면 여전히 누적될 수 있습니다. 이 경우 공유 캐시 볼륨에 대한 정리 정책을 별도로 두거나 위 CronJob 방식을 적용하세요.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📚 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/reference/cli/docker/system/prune/"&gt;Docker Docs - docker system prune&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/engine/manage-resources/pruning/"&gt;Docker Docs - Prune unused Docker objects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#exec"&gt;Kubernetes Docs - kubectl exec&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/"&gt;Kubernetes Docs - CronJob (timeZone)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners"&gt;GitHub Docs - About self-hosted runners&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;관련 글: &lt;a href="https://kyungryeol-yoon.github.io/docker/docker-dangling-image/"&gt;Docker Dangling Image란?&lt;/a&gt; · &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-exec/"&gt;kubectl exec command&lt;/a&gt; · &lt;a href="https://kyungryeol-yoon.github.io/kubernetes/storage/containerd-overlayfs-snapshot-disk-usage-troubleshooting/"&gt;containerd OverlayFS 디스크 점유 추적&lt;/a&gt;
&lt;/content&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Python] 🚀 uv로 프로젝트 &amp; 패키지 관리 완벽 가이드</title><link>https://kyungryeol-yoon.github.io/backend/python/python-uv-guide/</link><pubDate>Thu, 19 Mar 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/python/python-uv-guide/</guid><description>&lt;h2 id="-uv로-python-프로젝트-관리하기"&gt;
 🐍 uv로 Python 프로젝트 관리하기
 &lt;a class="heading-anchor" href="#-uv%eb%a1%9c-python-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ea%b4%80%eb%a6%ac%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;uv&lt;/code&gt;는 Python 프로젝트에서 &lt;strong&gt;패키지 관리 + 가상환경 + Python 버전 관리&lt;/strong&gt;를 한 번에 해결해주는 최신 도구입니다.
Rust로 작성되어 기존 &lt;code&gt;pip&lt;/code&gt;보다 &lt;strong&gt;10~100배 빠르며&lt;/strong&gt;, &lt;code&gt;pip&lt;/code&gt;, &lt;code&gt;venv&lt;/code&gt;, &lt;code&gt;pyenv&lt;/code&gt;를 대체할 수 있는 &lt;strong&gt;올인원 툴&lt;/strong&gt;입니다 ⚡&lt;/p&gt;
&lt;p&gt;이 글에서는 실무에서 바로 사용할 수 있도록 &lt;strong&gt;정확한 명령어 기준으로 깔끔하게 정리&lt;/strong&gt;했습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-설치하기"&gt;
 📥 설치하기
 &lt;a class="heading-anchor" href="#-%ec%84%a4%ec%b9%98%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="macos--linux"&gt;
 macOS / Linux
 &lt;a class="heading-anchor" href="#macos--linux" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -LsSf https://astral.sh/uv/install.sh &lt;span class="p"&gt;|&lt;/span&gt; sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="windows"&gt;
 Windows
 &lt;a class="heading-anchor" href="#windows" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;powershell&lt;/span&gt; &lt;span class="n"&gt;-ExecutionPolicy&lt;/span&gt; &lt;span class="n"&gt;ByPass&lt;/span&gt; &lt;span class="n"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;irm https://astral.sh/uv/install.ps1 | iex&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="pip으로-설치"&gt;
 pip으로 설치
 &lt;a class="heading-anchor" href="#pip%ec%9c%bc%eb%a1%9c-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pip install uv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;설치 후 버전 확인:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="1-프로젝트-생성-및-설정"&gt;
 1️⃣ 프로젝트 생성 및 설정
 &lt;a class="heading-anchor" href="#1-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%83%9d%ec%84%b1-%eb%b0%8f-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="-프로젝트-생성"&gt;
 📦 프로젝트 생성
 &lt;a class="heading-anchor" href="#-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 현재 디렉토리에 새로운 파이썬 프로젝트 환경을 초기화하는 기본적인 파일과 폴더 구조가 자동으로 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;uv init
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 기본 프로젝트 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;uv init my-project
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 설정 파일만 필요하다면&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;uv init --bare
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 특정 Python 버전으로 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;uv init my-project --python 3.11
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 가상환경 없이 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;uv init my-project --no-venv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;⚠️ 만약 &lt;code&gt;error: Failed to discover parent workspace;&lt;/code&gt; 가 발생했다면 &lt;code&gt;--no-workspace&lt;/code&gt; 옵션을 넣어주어 프로젝트를 생성&lt;/p&gt;
&lt;h3 id="-uv-init-시-생성되는-파일"&gt;
 📁 uv init 시 생성되는 파일
 &lt;a class="heading-anchor" href="#-uv-init-%ec%8b%9c-%ec%83%9d%ec%84%b1%eb%90%98%eb%8a%94-%ed%8c%8c%ec%9d%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;uv init&lt;/code&gt; 실행 후 프로젝트 디렉토리에 아래 파일들이 자동으로 생성됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;my-project/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;├── pyproject.toml # 프로젝트 메타데이터 및 의존성 정의
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;├── .python-version # 사용할 Python 버전 고정
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;├── uv.lock # 의존성 버전 잠금 파일 (자동 생성)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;├── .venv/ # 가상환경 디렉토리
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;└── src/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; └── main.py # 기본 진입점&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: &lt;code&gt;uv.lock&lt;/code&gt; 파일은 git에 포함해야 팀원 전체가 동일한 의존성 환경을 보장받을 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="-의존성-관리"&gt;
 📚 의존성 관리
 &lt;a class="heading-anchor" href="#-%ec%9d%98%ec%a1%b4%ec%84%b1-%ea%b4%80%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 패키지 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;uv add requests
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 특정 버전 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;uv add &lt;span class="nv"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;2.31.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 개발 의존성 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;uv add --dev pytest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 로컬 패키지 (editable 모드)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;uv add -e ./localpackage&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-의존성-제거"&gt;
 ❌ 의존성 제거
 &lt;a class="heading-anchor" href="#-%ec%9d%98%ec%a1%b4%ec%84%b1-%ec%a0%9c%ea%b1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv remove requests
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv remove --dev pytest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-의존성-동기화"&gt;
 🔄 의존성 동기화
 &lt;a class="heading-anchor" href="#-%ec%9d%98%ec%a1%b4%ec%84%b1-%eb%8f%99%ea%b8%b0%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv sync &lt;span class="c1"&gt;# 전체 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv sync --dev &lt;span class="c1"&gt;# 개발 의존성 포함&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;uv sync --no-dev &lt;span class="c1"&gt;# 개발 의존성 제외&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-의존성-잠금"&gt;
 🔒 의존성 잠금
 &lt;a class="heading-anchor" href="#-%ec%9d%98%ec%a1%b4%ec%84%b1-%ec%9e%a0%ea%b8%88" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv lock
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv lock --dev
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;uv lock --no-dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="2-패키지-설치-pip-스타일"&gt;
 2️⃣ 패키지 설치 (pip 스타일)
 &lt;a class="heading-anchor" href="#2-%ed%8c%a8%ed%82%a4%ec%a7%80-%ec%84%a4%ec%b9%98-pip-%ec%8a%a4%ed%83%80%ec%9d%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="-기본-설치"&gt;
 📥 기본 설치
 &lt;a class="heading-anchor" href="#-%ea%b8%b0%eb%b3%b8-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv pip install requests&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-특정-버전-설치"&gt;
 🎯 특정 버전 설치
 &lt;a class="heading-anchor" href="#-%ed%8a%b9%ec%a0%95-%eb%b2%84%ec%a0%84-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv pip install &lt;span class="s2"&gt;&amp;#34;requests==2.31.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv pip install &lt;span class="s2"&gt;&amp;#34;requests&amp;gt;=2.31.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;uv pip install &lt;span class="s2"&gt;&amp;#34;requests&amp;lt;3.0.0&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-개발-도구-설치"&gt;
 🧪 개발 도구 설치
 &lt;a class="heading-anchor" href="#-%ea%b0%9c%eb%b0%9c-%eb%8f%84%ea%b5%ac-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv pip install --dev pytest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv pip install --dev black isort mypy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-패키지-제거"&gt;
 ❌ 패키지 제거
 &lt;a class="heading-anchor" href="#-%ed%8c%a8%ed%82%a4%ec%a7%80-%ec%a0%9c%ea%b1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv pip uninstall requests
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv pip uninstall -y requests&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-패키지-업그레이드"&gt;
 ⬆️ 패키지 업그레이드
 &lt;a class="heading-anchor" href="#-%ed%8c%a8%ed%82%a4%ec%a7%80-%ec%97%85%ea%b7%b8%eb%a0%88%ec%9d%b4%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv pip install --upgrade requests
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv pip install --upgrade pip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-패키지-조회"&gt;
 🔍 패키지 조회
 &lt;a class="heading-anchor" href="#-%ed%8c%a8%ed%82%a4%ec%a7%80-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv pip search &lt;span class="s2"&gt;&amp;#34;data science&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv pip show requests
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;uv pip list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;uv pip list outdated
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;uv pip freeze &lt;span class="c1"&gt;# 현재 환경의 의존성 requirements 형식으로 출력&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-uv-add-vs-uv-pip-install-차이"&gt;
 🤔 uv add vs uv pip install 차이
 &lt;a class="heading-anchor" href="#-uv-add-vs-uv-pip-install-%ec%b0%a8%ec%9d%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;두 명령어 모두 패키지를 설치하지만 사용 목적이 다릅니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;구분&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;uv add&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;uv pip install&lt;/code&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;용도&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;프로젝트 의존성으로 등록&lt;/td&gt;
					&lt;td&gt;즉시 설치 (pip 호환)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;pyproject.toml&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;✅ 자동 업데이트&lt;/td&gt;
					&lt;td&gt;✗ 업데이트 안 함&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;uv.lock&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;✅ 자동 갱신&lt;/td&gt;
					&lt;td&gt;✗ 갱신 안 함&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;추천 상황&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;팀 프로젝트, 공유 환경&lt;/td&gt;
					&lt;td&gt;일회성 설치, 임시 테스트&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: 팀 프로젝트에서는 &lt;code&gt;uv add&lt;/code&gt;를 사용해야 &lt;code&gt;pyproject.toml&lt;/code&gt;과 &lt;code&gt;uv.lock&lt;/code&gt;이 업데이트되어 팀원과 환경을 공유할 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="3-가상환경-관리"&gt;
 3️⃣ 가상환경 관리
 &lt;a class="heading-anchor" href="#3-%ea%b0%80%ec%83%81%ed%99%98%ea%b2%bd-%ea%b4%80%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="-가상환경-생성"&gt;
 🏗️ 가상환경 생성
 &lt;a class="heading-anchor" href="#-%ea%b0%80%ec%83%81%ed%99%98%ea%b2%bd-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv venv
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv venv --python 3.11
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;uv venv --name myenv
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;uv venv --clear&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-가상환경-활성화"&gt;
 ▶️ 가상환경 활성화
 &lt;a class="heading-anchor" href="#-%ea%b0%80%ec%83%81%ed%99%98%ea%b2%bd-%ed%99%9c%ec%84%b1%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="macos--linux-1"&gt;
 macOS / Linux
 &lt;a class="heading-anchor" href="#macos--linux-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;source&lt;/span&gt; myenv/bin/activate&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="windows-1"&gt;
 Windows
 &lt;a class="heading-anchor" href="#windows-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;.venv&lt;span class="se"&gt;\S&lt;/span&gt;cripts&lt;span class="se"&gt;\a&lt;/span&gt;ctivate
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;myenv&lt;span class="se"&gt;\S&lt;/span&gt;cripts&lt;span class="se"&gt;\a&lt;/span&gt;ctivate&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-가상환경-비활성화"&gt;
 ⛔ 가상환경 비활성화
 &lt;a class="heading-anchor" href="#-%ea%b0%80%ec%83%81%ed%99%98%ea%b2%bd-%eb%b9%84%ed%99%9c%ec%84%b1%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;deactivate&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="4-python-버전-관리"&gt;
 4️⃣ Python 버전 관리
 &lt;a class="heading-anchor" href="#4-python-%eb%b2%84%ec%a0%84-%ea%b4%80%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="-python-설치"&gt;
 📦 Python 설치
 &lt;a class="heading-anchor" href="#-python-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv python install 3.11
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv python install 3.11.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;uv python install 3.11 --force&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-버전-관리"&gt;
 🧰 버전 관리
 &lt;a class="heading-anchor" href="#-%eb%b2%84%ec%a0%84-%ea%b4%80%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv python list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv python remove 3.11
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;uv python pin 3.11&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-특정-버전-실행"&gt;
 ▶️ 특정 버전 실행
 &lt;a class="heading-anchor" href="#-%ed%8a%b9%ec%a0%95-%eb%b2%84%ec%a0%84-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv run --python 3.11 script.py
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv run --python 3.11 -m pytest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="5-스크립트-실행"&gt;
 5️⃣ 스크립트 실행
 &lt;a class="heading-anchor" href="#5-%ec%8a%a4%ed%81%ac%eb%a6%bd%ed%8a%b8-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="-기본-실행"&gt;
 ▶️ 기본 실행
 &lt;a class="heading-anchor" href="#-%ea%b8%b0%eb%b3%b8-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv run script.py
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv run -m module&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-의존성과-함께-실행"&gt;
 📦 의존성과 함께 실행
 &lt;a class="heading-anchor" href="#-%ec%9d%98%ec%a1%b4%ec%84%b1%ea%b3%bc-%ed%95%a8%ea%bb%98-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv run --with-deps script.py
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv run --no-deps script.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-인자-전달"&gt;
 🎛️ 인자 전달
 &lt;a class="heading-anchor" href="#-%ec%9d%b8%ec%9e%90-%ec%a0%84%eb%8b%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv run script.py --arg1 value1 --arg2 value2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;uv run -m pytest tests/ --verbose&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-환경-변수-설정"&gt;
 🌍 환경 변수 설정
 &lt;a class="heading-anchor" href="#-%ed%99%98%ea%b2%bd-%eb%b3%80%ec%88%98-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv run --env &lt;span class="nv"&gt;VAR1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;value1 --env &lt;span class="nv"&gt;VAR2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;value2 script.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-uv가-빠른-이유"&gt;
 ⚡ uv가 빠른 이유
 &lt;a class="heading-anchor" href="#-uv%ea%b0%80-%eb%b9%a0%eb%a5%b8-%ec%9d%b4%ec%9c%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;uv&lt;/code&gt;는 단순히 &amp;ldquo;빠르다&amp;quot;는 말로만 설명되지만, 그 이유는 다음 기술들의 조합입니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;기술&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Rust 구현&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;컴파일 언어로 Python 대비 실행 속도 우월&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;병렬 처리&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;여러 패키지를 동시에 다운로드·설치&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;전역 캐시&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;한 번 다운로드한 패키지는 하드 링크로 재사용 (디스크 절약)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;PubGrub 알고리즘&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;pip의 순차 탐색보다 효율적인 의존성 해결 알고리즘&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;HTTP/2 지원&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;연결 풀링으로 네트워크 요청 효율화&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-pip--venv--pyenv-vs-uv-비교"&gt;
 📊 pip + venv + pyenv vs uv 비교
 &lt;a class="heading-anchor" href="#-pip--venv--pyenv-vs-uv-%eb%b9%84%ea%b5%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;기존 방식&lt;/th&gt;
					&lt;th&gt;uv&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;프로젝트 초기화&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;수동 설정&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;uv init&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;가상환경 생성&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;python -m venv .venv&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;자동 생성&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;가상환경 활성화&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;매번 수동&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;uv run&lt;/code&gt; 시 자동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;패키지 설치&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;pip install&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;uv add&lt;/code&gt; / &lt;code&gt;uv pip install&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;의존성 잠금&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;pip freeze &amp;gt; requirements.txt&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;uv lock&lt;/code&gt; (자동)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Python 버전 관리&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;pyenv 별도 설치 필요&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;uv python install&lt;/code&gt; 통합&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;의존성 해결 방식&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;순차 처리&lt;/td&gt;
					&lt;td&gt;병렬 처리 (PubGrub)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;캐시 방식&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;프로젝트별 개별 저장&lt;/td&gt;
					&lt;td&gt;전역 캐시 + 하드 링크&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;속도&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;기준 (1x)&lt;/td&gt;
					&lt;td&gt;10~100x 빠름&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-실전-프로젝트-예제"&gt;
 🏗️ 실전 프로젝트 예제
 &lt;a class="heading-anchor" href="#-%ec%8b%a4%ec%a0%84-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="데이터-과학-프로젝트"&gt;
 데이터 과학 프로젝트
 &lt;a class="heading-anchor" href="#%eb%8d%b0%ec%9d%b4%ed%84%b0-%ea%b3%bc%ed%95%99-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv init data-science-project --python 3.11
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; data-science-project
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;uv add pandas numpy matplotlib scikit-learn
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;uv add --dev jupyter notebook
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;uv run jupyter notebook&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="fastapi-웹-서버"&gt;
 FastAPI 웹 서버
 &lt;a class="heading-anchor" href="#fastapi-%ec%9b%b9-%ec%84%9c%eb%b2%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv init web-api --python 3.11
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; web-api
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;uv add fastapi uvicorn sqlalchemy pydantic
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;uv add --dev pytest black mypy
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;uv run uvicorn src.main:app --reload&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="머신러닝-프로젝트"&gt;
 머신러닝 프로젝트
 &lt;a class="heading-anchor" href="#%eb%a8%b8%ec%8b%a0%eb%9f%ac%eb%8b%9d-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uv init ml-project --python 3.11
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ml-project
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;uv add torch torchvision transformers datasets
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;uv add --dev jupyter wandb tensorboard
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;uv run python src/train.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-실무-팁"&gt;
 💡 실무 팁
 &lt;a class="heading-anchor" href="#-%ec%8b%a4%eb%ac%b4-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;✅ &lt;code&gt;uv sync&lt;/code&gt; 하나로 팀 환경 통일 가능&lt;/li&gt;
&lt;li&gt;✅ &lt;code&gt;uv lock&lt;/code&gt;으로 의존성 충돌 방지&lt;/li&gt;
&lt;li&gt;✅ &lt;code&gt;uv run&lt;/code&gt;으로 Python 버전까지 통제&lt;/li&gt;
&lt;li&gt;✅ &lt;code&gt;pip + venv + pyenv&lt;/code&gt; 대체 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-이런-분들께-추천"&gt;
 🎯 이런 분들께 추천
 &lt;a class="heading-anchor" href="#-%ec%9d%b4%eb%9f%b0-%eb%b6%84%eb%93%a4%ea%bb%98-%ec%b6%94%ec%b2%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;⚡ 빠른 Python 환경을 원하시는 분&lt;/li&gt;
&lt;li&gt;🧩 의존성 관리에 스트레스 받는 분&lt;/li&gt;
&lt;li&gt;🐳 Docker / CI 환경에서 속도 개선이 필요한 분&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-마무리"&gt;
 🎉 마무리
 &lt;a class="heading-anchor" href="#-%eb%a7%88%eb%ac%b4%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;uv&lt;/code&gt;는 단순한 패키지 매니저가 아니라
👉 &lt;strong&gt;Python 개발 환경 전체를 관리하는 차세대 도구&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;앞으로 Python 프로젝트는 이렇게 관리하는 것이 표준이 될 가능성이 높습니다 🚀&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⚡ 빠른 패키지 설치&lt;/li&gt;
&lt;li&gt;🧩 의존성 관리 통합&lt;/li&gt;
&lt;li&gt;🐍 Python 버전 관리까지 한 번에&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;👉 기존 &lt;code&gt;pip&lt;/code&gt;, &lt;code&gt;venv&lt;/code&gt;, &lt;code&gt;pyenv&lt;/code&gt;를 따로 쓰던 분들에게 강력 추천!&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📚 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/astral-sh/uv"&gt;uv 공식 GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[LLM] Mac Mini M4 환경에서 Ollama 설치 및 관리 가이드</title><link>https://kyungryeol-yoon.github.io/ai/llm/mac-mini-m4-ollama-install-guide/</link><pubDate>Sat, 28 Feb 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/ai/llm/mac-mini-m4-ollama-install-guide/</guid><description>&lt;h1 id="mac-mini-m4apple-silicon-환경에서-ollama-설치-및-관리-가이드"&gt;
 Mac Mini M4(Apple Silicon) 환경에서 Ollama 설치 및 관리 가이드
 &lt;a class="heading-anchor" href="#mac-mini-m4apple-silicon-%ed%99%98%ea%b2%bd%ec%97%90%ec%84%9c-ollama-%ec%84%a4%ec%b9%98-%eb%b0%8f-%ea%b4%80%eb%a6%ac-%ea%b0%80%ec%9d%b4%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="-개요"&gt;
 📌 개요
 &lt;a class="heading-anchor" href="#-%ea%b0%9c%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;본 가이드는 Apple Silicon 기반 Mac Mini M4 환경에서 로컬 LLM(Local Large Language Model) 도구인 Ollama를 설치하고 관리하는 방법을 설명합니다.&lt;br&gt;
Homebrew를 활용하여 설치하고, 서비스 등록부터 모델 실행, 삭제 방법까지 전체 과정을 정리합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-1-homebrew-준비-및-설치"&gt;
 🚀 1. Homebrew 준비 및 설치
 &lt;a class="heading-anchor" href="#-1-homebrew-%ec%a4%80%eb%b9%84-%eb%b0%8f-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="11-homebrew-설치-확인"&gt;
 1.1 Homebrew 설치 확인
 &lt;a class="heading-anchor" href="#11-homebrew-%ec%84%a4%ec%b9%98-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;먼저 Homebrew가 설치되어 있는지 확인합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;설치되어 있지 않다면 Homebrew 공식 사이트 안내에 따라 먼저 설치하세요.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="12-homebrew-업데이트"&gt;
 1.2 Homebrew 업데이트
 &lt;a class="heading-anchor" href="#12-homebrew-%ec%97%85%eb%8d%b0%ec%9d%b4%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;패키지 인덱스를 최신 상태로 유지합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew update&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-2-ollama-설치"&gt;
 🛠 2. Ollama 설치
 &lt;a class="heading-anchor" href="#-2-ollama-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Homebrew를 통해 Ollama를 설치합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew install ollama&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;설치 완료 후 정상 설치 여부를 확인합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ollama --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-3-ollama-실행-방식"&gt;
 ⚙️ 3. Ollama 실행 방식
 &lt;a class="heading-anchor" href="#-3-ollama-%ec%8b%a4%ed%96%89-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="31-백그라운드-서비스-실행-권장"&gt;
 3.1 백그라운드 서비스 실행 (권장)
 &lt;a class="heading-anchor" href="#31-%eb%b0%b1%ea%b7%b8%eb%9d%bc%ec%9a%b4%eb%93%9c-%ec%84%9c%eb%b9%84%ec%8a%a4-%ec%8b%a4%ed%96%89-%ea%b6%8c%ec%9e%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;시스템 부팅 시 자동 실행되도록 설정:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew services start ollama&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;서비스 상태 확인:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew services list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="32-포그라운드-실행"&gt;
 3.2 포그라운드 실행
 &lt;a class="heading-anchor" href="#32-%ed%8f%ac%ea%b7%b8%eb%9d%bc%ec%9a%b4%eb%93%9c-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;현재 터미널 세션에서만 실행하려면:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ollama serve&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;터미널 세션이 종료되면 Ollama도 함께 종료됩니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-4-모델-다운로드-및-실행"&gt;
 🤖 4. 모델 다운로드 및 실행
 &lt;a class="heading-anchor" href="#-4-%eb%aa%a8%eb%8d%b8-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c-%eb%b0%8f-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;모델을 다운로드하고 바로 실행할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ollama run llama3.2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;처음 실행 시 모델이 자동으로 다운로드됩니다.&lt;/p&gt;
&lt;p&gt;설치된 모델 목록 확인:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ollama list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;현재 실행 중인 모델 확인:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ollama ps&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-5-외부-접속-허용-설정"&gt;
 🌐 5. 외부 접속 허용 설정
 &lt;a class="heading-anchor" href="#-5-%ec%99%b8%eb%b6%80-%ec%a0%91%ec%86%8d-%ed%97%88%ec%9a%a9-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;기본적으로 Ollama는 &lt;code&gt;127.0.0.1:11434&lt;/code&gt;에 바인딩됩니다.&lt;/p&gt;
&lt;p&gt;외부 네트워크 접근을 허용하려면:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;OLLAMA_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.0.0.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;영구 적용하려면 &lt;code&gt;~/.zshrc&lt;/code&gt; 또는 &lt;code&gt;~/.bashrc&lt;/code&gt;에 추가합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;export OLLAMA_HOST=0.0.0.0&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; ~/.zshrc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.zshrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-6-리소스-관리-팁-apple-silicon"&gt;
 🧠 6. 리소스 관리 팁 (Apple Silicon)
 &lt;a class="heading-anchor" href="#-6-%eb%a6%ac%ec%86%8c%ec%8a%a4-%ea%b4%80%eb%a6%ac-%ed%8c%81-apple-silicon" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Apple Silicon은 Unified Memory 구조를 사용하므로,
대형 모델 실행 시 메모리 사용량을 반드시 확인하는 것이 좋습니다.&lt;/p&gt;
&lt;p&gt;macOS에서 Activity Monitor를 통해 메모리 사용량을 모니터링하세요.&lt;/p&gt;
&lt;p&gt;대형 모델 실행 시:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;8GB RAM → 7B 이하 모델 권장&lt;/li&gt;
&lt;li&gt;16GB RAM → 13B 모델 가능&lt;/li&gt;
&lt;li&gt;32GB 이상 → 대형 모델 원활&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-7-ollama-완전-삭제-uninstall"&gt;
 ❌ 7. Ollama 완전 삭제 (Uninstall)
 &lt;a class="heading-anchor" href="#-7-ollama-%ec%99%84%ec%a0%84-%ec%82%ad%ec%a0%9c-uninstall" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="71-패키지-삭제"&gt;
 7.1 패키지 삭제
 &lt;a class="heading-anchor" href="#71-%ed%8c%a8%ed%82%a4%ec%a7%80-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew uninstall ollama&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="72-데이터-디렉토리-삭제"&gt;
 7.2 데이터 디렉토리 삭제
 &lt;a class="heading-anchor" href="#72-%eb%8d%b0%ec%9d%b4%ed%84%b0-%eb%94%94%eb%a0%89%ed%86%a0%eb%a6%ac-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;rm -rf ~/.ollama&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ 해당 명령은 모든 모델 데이터를 완전히 삭제하므로 신중하게 실행하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-마무리"&gt;
 ✅ 마무리
 &lt;a class="heading-anchor" href="#-%eb%a7%88%eb%ac%b4%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;이 가이드를 통해 Mac Mini M4 환경에서:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ollama 설치&lt;/li&gt;
&lt;li&gt;서비스 등록&lt;/li&gt;
&lt;li&gt;모델 실행&lt;/li&gt;
&lt;li&gt;외부 접속 설정&lt;/li&gt;
&lt;li&gt;완전 삭제&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;까지 전체 워크플로우를 정리했습니다.&lt;/p&gt;
&lt;p&gt;로컬 LLM 환경을 구축하려는 Apple Silicon 사용자에게 기본 세팅 가이드로 활용할 수 있습니다.&lt;/p&gt;</description></item><item><title>[LangChain] 🔀 Ensemble Retriever로 RAG 검색 정확도 높이기: BM25 + Vector 하이브리드 검색</title><link>https://kyungryeol-yoon.github.io/ai/llm/langchain-ensemble-retriever/</link><pubDate>Sun, 01 Feb 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/ai/llm/langchain-ensemble-retriever/</guid><description>&lt;p&gt;LangChain Ensemble Retriever는 BM25 키워드 검색과 Vector 의미 검색을 결합하여 단일 검색기보다 높은 정확도를 제공하는 하이브리드 검색 방식입니다. 두 검색기의 결과를 RRF(Reciprocal Rank Fusion) 알고리즘으로 재순위화하여 최적의 문서를 반환합니다. 이 글에서는 Ensemble Retriever의 동작 원리부터 BM25 + FAISS 조합 코드, weights 튜닝, 실무 적용 팁까지 정리합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-왜-단일-검색기로는-부족한가"&gt;
 🤔 왜 단일 검색기로는 부족한가?
 &lt;a class="heading-anchor" href="#-%ec%99%9c-%eb%8b%a8%ec%9d%bc-%ea%b2%80%ec%83%89%ea%b8%b0%eb%a1%9c%eb%8a%94-%eb%b6%80%ec%a1%b1%ed%95%9c%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;RAG(Retrieval-Augmented Generation) 시스템에서 검색 품질은 LLM 답변의 품질을 직접 결정합니다. 그런데 현재 가장 많이 쓰이는 두 가지 검색 방식은 각각 뚜렷한 한계가 있습니다.&lt;/p&gt;
&lt;h3 id="dense-retrieval-의미-기반--vector-search"&gt;
 Dense Retrieval (의미 기반 — Vector Search)
 &lt;a class="heading-anchor" href="#dense-retrieval-%ec%9d%98%eb%af%b8-%ea%b8%b0%eb%b0%98--vector-search" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;임베딩 벡터의 코사인 유사도로 의미적으로 유사한 문서를 찾습니다. 단어가 달라도 의미가 같으면 검색되는 것이 강점이지만, &lt;strong&gt;정확한 용어·고유명사·코드 식별자&lt;/strong&gt; 검색에는 취약합니다.&lt;/p&gt;
&lt;h3 id="sparse-retrieval-키워드-기반--bm25"&gt;
 Sparse Retrieval (키워드 기반 — BM25)
 &lt;a class="heading-anchor" href="#sparse-retrieval-%ed%82%a4%ec%9b%8c%eb%93%9c-%ea%b8%b0%eb%b0%98--bm25" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;단어 빈도(TF-IDF 기반 BM25)로 문서를 검색합니다. &amp;ldquo;쿠버네티스&amp;rdquo;, &amp;ldquo;CVE-2024-1234&amp;rdquo; 같은 정확한 키워드 일치에 강하지만, &lt;strong&gt;동의어·문맥 기반 질문&lt;/strong&gt;에는 약합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;방식&lt;/th&gt;
					&lt;th&gt;강점&lt;/th&gt;
					&lt;th&gt;약점&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Vector (Dense)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;의미 유사성, 동의어, 맥락 이해&lt;/td&gt;
					&lt;td&gt;정확한 용어·고유명사·코드 검색&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;BM25 (Sparse)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;키워드 정확 일치, 도메인 전문용어&lt;/td&gt;
					&lt;td&gt;오타, 동의어, 문맥 파악&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Hybrid (Ensemble)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;두 방식의 장점 결합&lt;/td&gt;
					&lt;td&gt;설정 복잡도 증가&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: 실무에서는 두 방식을 결합한 하이브리드 검색이 단일 방식보다 일관되게 더 나은 성능을 보입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-ensemble-retriever란"&gt;
 🔀 Ensemble Retriever란?
 &lt;a class="heading-anchor" href="#-ensemble-retriever%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Ensemble Retriever는 여러 검색기의 결과를 &lt;strong&gt;RRF(Reciprocal Rank Fusion)&lt;/strong&gt; 알고리즘으로 병합하는 LangChain 컴포넌트입니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;쿼리
 ├─ BM25Retriever → [문서A(1위), 문서C(2위), 문서E(3위), ...]
 └─ FAISSRetriever → [문서B(1위), 문서A(2위), 문서D(3위), ...]
 ↓
 RRF 재순위화 (weights 적용)
 ↓
 최종 결과: [문서A, 문서B, 문서C, ...]&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="rrf-알고리즘"&gt;
 RRF 알고리즘
 &lt;a class="heading-anchor" href="#rrf-%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;RRF(Reciprocal Rank Fusion)는 각 검색기에서 반환된 문서의 &lt;strong&gt;순위&lt;/strong&gt;를 기반으로 최종 점수를 계산합니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;RRF 점수 = Σ (weight_i / (rank_i + c))&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rank_i&lt;/code&gt; — 각 검색기에서의 순위 (1부터 시작)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;weight_i&lt;/code&gt; — 해당 검색기의 가중치&lt;/li&gt;
&lt;li&gt;&lt;code&gt;c&lt;/code&gt; — 상수 (기본값 60, 높을수록 순위 차이 완화)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;순위만 사용하기 때문에 서로 다른 점수 스케일을 가진 검색기를 직접 결합할 수 있다는 것이 핵심 장점입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-설치"&gt;
 🚀 설치
 &lt;a class="heading-anchor" href="#-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pip install langchain langchain-community langchain-openai faiss-cpu rank_bm25&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;패키지&lt;/th&gt;
					&lt;th&gt;용도&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;langchain&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;코어 프레임워크&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;langchain-community&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;BM25Retriever, FAISS 등 커뮤니티 컴포넌트&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;langchain-openai&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;OpenAI 임베딩&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;faiss-cpu&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Facebook AI 유사도 검색 (GPU 버전: &lt;code&gt;faiss-gpu&lt;/code&gt;)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;rank_bm25&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;BM25 알고리즘 구현체&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="1-기본-예제-bm25--faiss-결합"&gt;
 1️⃣ 기본 예제: BM25 + FAISS 결합
 &lt;a class="heading-anchor" href="#1-%ea%b8%b0%eb%b3%b8-%ec%98%88%ec%a0%9c-bm25--faiss-%ea%b2%b0%ed%95%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;가장 일반적인 조합인 BM25와 FAISS를 사용한 Ensemble Retriever 구성입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.retrievers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;EnsembleRetriever&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_community.retrievers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BM25Retriever&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_community.vectorstores&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FAISS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.documents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Document&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 샘플 문서&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;쿠버네티스(Kubernetes)는 컨테이너 오케스트레이션 플랫폼입니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Docker는 컨테이너 기반 가상화 기술로 애플리케이션을 패키징합니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Helm은 쿠버네티스 패키지 매니저로 차트를 통해 배포를 관리합니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Prometheus는 시계열 데이터베이스 기반의 모니터링 솔루션입니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Istio는 서비스 메시로 마이크로서비스 간 통신을 관리합니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# BM25 리트리버 (키워드 기반)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;bm25_retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BM25Retriever&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;bm25_retriever&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="c1"&gt;# 반환할 문서 수&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# FAISS 리트리버 (의미 기반)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;text-embedding-3-small&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vectorstore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FAISS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;faiss_retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vectorstore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_retriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;search_kwargs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;k&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Ensemble Retriever 구성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ensemble_retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EnsembleRetriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;retrievers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bm25_retriever&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;faiss_retriever&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;weights&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# BM25 40%, FAISS 60%&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 검색 실행&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ensemble_retriever&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;쿠버네티스 패키지 관리 도구는?&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="2-실전-예제-rag-파이프라인에-통합"&gt;
 2️⃣ 실전 예제: RAG 파이프라인에 통합
 &lt;a class="heading-anchor" href="#2-%ec%8b%a4%ec%a0%84-%ec%98%88%ec%a0%9c-rag-%ed%8c%8c%ec%9d%b4%ed%94%84%eb%9d%bc%ec%9d%b8%ec%97%90-%ed%86%b5%ed%95%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;문서 로딩부터 LLM 답변 생성까지 전체 RAG 파이프라인에 Ensemble Retriever를 통합합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.text_splitter&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_community.document_loaders&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TextLoader&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RetrievalQA&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 문서 로딩 및 분할&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TextLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;knowledge_base.txt&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;utf-8&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;raw_docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;splitter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;chunk_overlap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;splitter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw_docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. BM25 리트리버&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;bm25_retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BM25Retriever&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;bm25_retriever&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. FAISS 벡터스토어&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;text-embedding-3-small&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vectorstore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FAISS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;faiss_retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vectorstore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_retriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;search_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;mmr&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 다양성 확보 (Maximum Marginal Relevance)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;search_kwargs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;k&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;fetch_k&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;lambda_mult&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 4. Ensemble Retriever&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ensemble_retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EnsembleRetriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;retrievers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bm25_retriever&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;faiss_retriever&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;weights&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 5. RAG 체인 구성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o-mini&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;qa_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RetrievalQA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_chain_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;chain_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;stuff&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;retriever&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ensemble_retriever&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;return_source_documents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 6. 질의&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;qa_chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;서비스 메시의 역할은 무엇인가요?&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;result&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;--- 참조 문서 ---&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;source_documents&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;- &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="3-chromadb--bm25-조합"&gt;
 3️⃣ ChromaDB + BM25 조합
 &lt;a class="heading-anchor" href="#3-chromadb--bm25-%ec%a1%b0%ed%95%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;FAISS 대신 ChromaDB를 사용하는 경우입니다. 영구 저장이 필요한 프로덕션 환경에 적합합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_community.vectorstores&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Chroma&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ChromaDB 벡터스토어 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vectorstore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Chroma&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;collection_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my_collection&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;persist_directory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./chroma_db&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 디스크 저장&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chroma_retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vectorstore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_retriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;search_kwargs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;k&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Ensemble 구성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ensemble_retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EnsembleRetriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;retrievers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bm25_retriever&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chroma_retriever&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;weights&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-weights-설정-가이드"&gt;
 ⚖️ weights 설정 가이드
 &lt;a class="heading-anchor" href="#-weights-%ec%84%a4%ec%a0%95-%ea%b0%80%ec%9d%b4%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;weights&lt;/code&gt;는 각 검색기가 최종 순위에 미치는 영향력을 조절합니다. 합계가 반드시 1.0일 필요는 없지만, 상대적 비율로 이해하면 됩니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;상황&lt;/th&gt;
					&lt;th&gt;권장 weights (BM25 : Vector)&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;일반 QA (균형)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;[0.5, 0.5]&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;기술 문서, 코드, 전문용어&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;[0.6, 0.4]&lt;/code&gt; — BM25 강화&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;고객 상담, 자연어 질문&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;[0.3, 0.7]&lt;/code&gt; — Vector 강화&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;뉴스·블로그 등 일반 문서&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;[0.4, 0.6]&lt;/code&gt; — Vector 약간 우세&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;법률·의료 전문 도메인&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;[0.7, 0.3]&lt;/code&gt; — 정확한 용어 우선&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 세 개의 검색기를 결합할 수도 있습니다&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ensemble_retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EnsembleRetriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;retrievers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bm25_retriever&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;faiss_retriever&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chroma_retriever&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;weights&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: weights는 도메인과 질의 패턴에 따라 다르므로, 평가 데이터셋으로 실험하여 최적값을 찾는 것이 좋습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-다른-다중-검색기-전략과-비교"&gt;
 🔄 다른 다중 검색기 전략과 비교
 &lt;a class="heading-anchor" href="#-%eb%8b%a4%eb%a5%b8-%eb%8b%a4%ec%a4%91-%ea%b2%80%ec%83%89%ea%b8%b0-%ec%a0%84%eb%9e%b5%ea%b3%bc-%eb%b9%84%ea%b5%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Ensemble Retriever 외에도 LangChain이 제공하는 다중 검색기 전략들이 있습니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;전략&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
					&lt;th&gt;적합한 경우&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;EnsembleRetriever&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;여러 검색기 결과를 RRF로 병합&lt;/td&gt;
					&lt;td&gt;하이브리드 검색의 기본&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;MultiQueryRetriever&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;질문을 여러 변형으로 재생성 후 검색&lt;/td&gt;
					&lt;td&gt;모호한 질문, 다각도 검색&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ContextualCompression&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;검색 결과를 LLM으로 압축·필터링&lt;/td&gt;
					&lt;td&gt;불필요한 정보 제거&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ParentDocumentRetriever&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;작은 청크로 검색 후 원본 상위 문서 반환&lt;/td&gt;
					&lt;td&gt;문맥 손실 방지&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;SelfQueryRetriever&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;LLM이 메타데이터 필터를 자동 생성&lt;/td&gt;
					&lt;td&gt;구조화된 필터 조건 처리&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="multiqueryretriever와-ensemble-조합"&gt;
 MultiQueryRetriever와 Ensemble 조합
 &lt;a class="heading-anchor" href="#multiqueryretriever%ec%99%80-ensemble-%ec%a1%b0%ed%95%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.retrievers.multi_query&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MultiQueryRetriever&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# MultiQuery로 질문을 다각도로 확장&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;multi_query_retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MultiQueryRetriever&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;retriever&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;faiss_retriever&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# MultiQuery + BM25를 Ensemble로 결합&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ensemble_retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EnsembleRetriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;retrievers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bm25_retriever&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;multi_query_retriever&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;weights&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-프로덕션-고려사항"&gt;
 🏗️ 프로덕션 고려사항
 &lt;a class="heading-anchor" href="#-%ed%94%84%eb%a1%9c%eb%8d%95%ec%85%98-%ea%b3%a0%eb%a0%a4%ec%82%ac%ed%95%ad" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="성능-최적화"&gt;
 성능 최적화
 &lt;a class="heading-anchor" href="#%ec%84%b1%eb%8a%a5-%ec%b5%9c%ec%a0%81%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# FAISS 검색 타입별 특성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;faiss_retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vectorstore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_retriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;search_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;mmr&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 다양성 + 관련성 균형&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# search_type=&amp;#34;similarity&amp;#34;, # 순수 유사도 (기본값)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# search_type=&amp;#34;similarity_score_threshold&amp;#34;, # 최소 점수 필터&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;search_kwargs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;k&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;fetch_k&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# mmr에서 후보 풀 크기&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;lambda_mult&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 0=다양성 최대, 1=유사도 최대&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="대용량-문서-처리"&gt;
 대용량 문서 처리
 &lt;a class="heading-anchor" href="#%eb%8c%80%ec%9a%a9%eb%9f%89-%eb%ac%b8%ec%84%9c-%ec%b2%98%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# BM25 리트리버를 파일에서 직접 로딩 (메모리 효율)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_community.retrievers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BM25Retriever&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 청크 크기를 고려한 k 설정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;bm25_retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BM25Retriever&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;bm25_params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;k1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.75&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;# BM25 하이퍼파라미터 조정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;bm25_retriever&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="검색-결과-평가"&gt;
 검색 결과 평가
 &lt;a class="heading-anchor" href="#%ea%b2%80%ec%83%89-%ea%b2%b0%ea%b3%bc-%ed%8f%89%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 검색 결과 품질 간단 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;evaluate_retrieval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retriever&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_queries&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected_keyword&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;test_queries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;retriever&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;hit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expected_keyword&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;✅&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;❌&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;] → &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;개 반환&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;test_cases&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;쿠버네티스 설치 방법&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Kubernetes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;컨테이너 패키징&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Docker&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;evaluate_retrieval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ensemble_retriever&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_cases&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-실무-적용-팁"&gt;
 💡 실무 적용 팁
 &lt;a class="heading-anchor" href="#-%ec%8b%a4%eb%ac%b4-%ec%a0%81%ec%9a%a9-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;BM25 토크나이저 커스터마이징&lt;/strong&gt; — 한국어 문서는 기본 토크나이저가 형태소를 고려하지 않아 성능이 떨어질 수 있습니다. &lt;code&gt;konlpy&lt;/code&gt; 등의 한국어 형태소 분석기를 전처리 단계에 추가하는 것을 권장합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;청크 크기와 k의 균형&lt;/strong&gt; — 청크가 작을수록 더 많은 k가 필요합니다. 일반적으로 500&lt;del&gt;1000자 청크에 k=4&lt;/del&gt;8이 적절합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;중복 문서 처리&lt;/strong&gt; — 두 검색기가 같은 문서를 반환하면 EnsembleRetriever가 자동으로 중복을 제거하고 점수를 합산합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;점진적 도입&lt;/strong&gt; — 기존 Vector 검색만 사용하던 시스템이라면, &lt;code&gt;weights=[0.2, 0.8]&lt;/code&gt;처럼 BM25 비중을 낮게 시작하여 점진적으로 조정하세요.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-bm25retriever와-ensembleretriever-중-무엇이-더-나은가요"&gt;
 Q. BM25Retriever와 EnsembleRetriever 중 무엇이 더 나은가요?
 &lt;a class="heading-anchor" href="#q-bm25retriever%ec%99%80-ensembleretriever-%ec%a4%91-%eb%ac%b4%ec%97%87%ec%9d%b4-%eb%8d%94-%eb%82%98%ec%9d%80%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;단독으로는 우열을 가릴 수 없습니다. BM25는 키워드 일치에 강하고, Vector는 의미 이해에 강합니다. 대부분의 실무 RAG에서는 두 방식을 결합한 Ensemble이 단일 방식보다 일관되게 좋은 성능을 보입니다.&lt;/p&gt;
&lt;h3 id="q-weights-합이-반드시-10이어야-하나요"&gt;
 Q. weights 합이 반드시 1.0이어야 하나요?
 &lt;a class="heading-anchor" href="#q-weights-%ed%95%a9%ec%9d%b4-%eb%b0%98%eb%93%9c%ec%8b%9c-10%ec%9d%b4%ec%96%b4%ec%95%bc-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;아닙니다. &lt;code&gt;[0.4, 0.6]&lt;/code&gt;이든 &lt;code&gt;[2, 3]&lt;/code&gt;이든 상대적 비율만 중요합니다. 내부적으로 정규화됩니다.&lt;/p&gt;
&lt;h3 id="q-rank_bm25-패키지-없이-bm25retriever를-쓸-수-있나요"&gt;
 Q. &lt;code&gt;rank_bm25&lt;/code&gt; 패키지 없이 BM25Retriever를 쓸 수 있나요?
 &lt;a class="heading-anchor" href="#q-rank_bm25-%ed%8c%a8%ed%82%a4%ec%a7%80-%ec%97%86%ec%9d%b4-bm25retriever%eb%a5%bc-%ec%93%b8-%ec%88%98-%ec%9e%88%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;없습니다. &lt;code&gt;BM25Retriever&lt;/code&gt;는 내부적으로 &lt;code&gt;rank_bm25&lt;/code&gt;를 의존합니다. &lt;code&gt;pip install rank_bm25&lt;/code&gt;가 필수입니다.&lt;/p&gt;
&lt;h3 id="q-rrf의-c-파라미터는-어떻게-조정하나요"&gt;
 Q. RRF의 &lt;code&gt;c&lt;/code&gt; 파라미터는 어떻게 조정하나요?
 &lt;a class="heading-anchor" href="#q-rrf%ec%9d%98-c-%ed%8c%8c%eb%9d%bc%eb%af%b8%ed%84%b0%eb%8a%94-%ec%96%b4%eb%96%bb%ea%b2%8c-%ec%a1%b0%ec%a0%95%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;현재 LangChain의 &lt;code&gt;EnsembleRetriever&lt;/code&gt;는 &lt;code&gt;c&lt;/code&gt; 파라미터를 직접 노출하지 않습니다. 기본값 60이 대부분의 경우 적합하며, 커스터마이징이 필요하다면 소스를 상속하여 오버라이드할 수 있습니다.&lt;/p&gt;
&lt;h3 id="q-한국어-문서에서-bm25-성능이-낮습니다"&gt;
 Q. 한국어 문서에서 BM25 성능이 낮습니다.
 &lt;a class="heading-anchor" href="#q-%ed%95%9c%ea%b5%ad%ec%96%b4-%eb%ac%b8%ec%84%9c%ec%97%90%ec%84%9c-bm25-%ec%84%b1%eb%8a%a5%ec%9d%b4-%eb%82%ae%ec%8a%b5%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;한국어는 형태소 분석 없이 어절 단위로 분리되면 검색 정확도가 낮습니다. &lt;code&gt;konlpy&lt;/code&gt;의 &lt;code&gt;Okt&lt;/code&gt;나 &lt;code&gt;Mecab&lt;/code&gt;으로 형태소 분석 후 토큰을 직접 BM25에 전달하면 성능이 향상됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📚 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://python.langchain.com/docs/how_to/ensemble_retriever/"&gt;LangChain 공식 문서 - Ensemble Retriever&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[LLM] 🧠 프롬프트 엔지니어링 완전 가이드: Zero-shot, Few-shot, CoT부터 ReAct까지</title><link>https://kyungryeol-yoon.github.io/ai/llm/prompt-engineering-zero-shot-few-shot-cot/</link><pubDate>Sun, 11 Jan 2026 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/ai/llm/prompt-engineering-zero-shot-few-shot-cot/</guid><description>&lt;p&gt;프롬프트 엔지니어링은 LLM이 최적의 답변을 생성하도록 입력 텍스트의 형식, 맥락, 구조를 설계하는 기술입니다. 단어 하나의 차이가 결과를 크게 바꾸며, 예시 제공 방식에 따라 Zero-shot부터 Few-shot CoT까지 다양한 기법이 존재합니다. 이 글에서는 기본 기법의 개념과 차이부터 Chain-of-Thought, Tree-of-Thought, ReAct 같은 고급 기법까지 실제 프롬프트 예시와 함께 정리합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-프롬프트-엔지니어링이란"&gt;
 🤔 프롬프트 엔지니어링이란?
 &lt;a class="heading-anchor" href="#-%ed%94%84%eb%a1%ac%ed%94%84%ed%8a%b8-%ec%97%94%ec%a7%80%eb%8b%88%ec%96%b4%eb%a7%81%ec%9d%b4%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;프롬프트 엔지니어링은 AI가 최상의 답변을 생성하도록 &lt;strong&gt;입력값(프롬프트)을 설계하고 최적화하는 과정&lt;/strong&gt;입니다. 같은 질문이라도 어떻게 표현하느냐에 따라 LLM의 답변 품질이 극적으로 달라집니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# 나쁜 프롬프트
&amp;#34;요약해줘&amp;#34;

# 좋은 프롬프트
&amp;#34;다음 기술 문서를 비개발자도 이해할 수 있는 수준으로
 3문장 이내 한국어 글머리 목록으로 요약해줘.&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;프롬프트는 일반적으로 4가지 요소로 구성됩니다:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;요소&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
					&lt;th&gt;예시&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Instruction&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;AI에게 수행할 작업 지시&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;다음 텍스트를 감정 분류해줘&amp;rdquo;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Context&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;배경 정보, 제약 조건&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;고객 리뷰 데이터입니다&amp;rdquo;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Input&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;실제 처리할 데이터&lt;/td&gt;
					&lt;td&gt;리뷰 텍스트&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Output Indicator&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;원하는 출력 형식&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;긍정/부정/중립 중 하나로만 답해줘&amp;rdquo;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="1-zero-shot-프롬프팅"&gt;
 1️⃣ Zero-Shot 프롬프팅
 &lt;a class="heading-anchor" href="#1-zero-shot-%ed%94%84%eb%a1%ac%ed%94%84%ed%8c%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Zero-Shot은 &lt;strong&gt;예시(예제) 없이 지시만으로&lt;/strong&gt; AI에게 작업을 수행시키는 방식입니다. &amp;ldquo;영점(0개의 예시)&amp;ldquo;이라는 이름 그대로입니다.&lt;/p&gt;
&lt;p&gt;AI의 사전학습 지식만으로 작업하기 때문에 빠르고 간편하지만, 복잡하거나 특수한 형식의 작업에서는 결과가 불안정할 수 있습니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Zero-Shot 예시 — 감정 분류
&amp;#34;다음 문장의 감정을 긍정, 부정, 중립 중 하나로 분류하세요.

문장: 오늘 배송이 너무 늦어서 실망했어요.&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;# Zero-Shot 예시 — 번역
&amp;#34;다음 문장을 영어로 번역해줘.

문장: 인공지능은 미래를 바꿀 기술입니다.&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;적합한 상황:&lt;/strong&gt; 일반적인 번역, 간단한 요약, 기본 질의응답처럼 명확하고 단순한 작업&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="2-one-shot-프롬프팅"&gt;
 2️⃣ One-Shot 프롬프팅
 &lt;a class="heading-anchor" href="#2-one-shot-%ed%94%84%eb%a1%ac%ed%94%84%ed%8c%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;One-Shot은 &lt;strong&gt;하나의 입출력 예시&lt;/strong&gt;를 제공한 후 같은 패턴으로 답변을 요청하는 방식입니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# One-Shot 예시 — 감정 분류
&amp;#34;다음 형식으로 감정을 분류해줘.

예시:
입력: 배송이 빠르고 포장이 깔끔해서 만족합니다.
출력: 긍정

입력: 제품 색상이 사진과 달라서 당황했어요.
출력:&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;예시 하나만으로도 AI가 원하는 출력 형식을 파악하여 일관된 응답을 생성합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="3-few-shot-프롬프팅"&gt;
 3️⃣ Few-Shot 프롬프팅
 &lt;a class="heading-anchor" href="#3-few-shot-%ed%94%84%eb%a1%ac%ed%94%84%ed%8c%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Few-Shot은 &lt;strong&gt;2~5개의 예시&lt;/strong&gt;를 제공하여 AI가 패턴을 학습하고 일관된 결과를 내도록 유도하는 방식입니다. Zero-Shot보다 훨씬 안정적인 결과를 얻을 수 있습니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Few-Shot 예시 — 신조어 감정 분석
&amp;#34;다음 형식으로 리뷰의 감정을 분류해줘.

입력: 이 카페 분위기 레전드다
출력: 긍정

입력: 음식이 존맛탱이에요
출력: 긍정

입력: 서비스가 별로고 가성비도 구림
출력: 부정

입력: 인테리어는 갓벽한데 가격이 좀 세네요
출력:&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="좋은-예시를-고르는-기준"&gt;
 좋은 예시를 고르는 기준
 &lt;a class="heading-anchor" href="#%ec%a2%8b%ec%9d%80-%ec%98%88%ec%8b%9c%eb%a5%bc-%ea%b3%a0%eb%a5%b4%eb%8a%94-%ea%b8%b0%ec%a4%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;다양성&lt;/strong&gt;: 다양한 케이스를 포함해 AI가 패턴을 일반화하도록 유도&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;명확성&lt;/strong&gt;: 각 입출력이 1:1로 명확하게 대응&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;일관성&lt;/strong&gt;: 모든 예시가 동일한 형식을 따름&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;관련성&lt;/strong&gt;: 실제 요청과 유사한 도메인의 예시 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: Few-Shot에서 예시의 순서도 영향을 줍니다. 가장 관련성 높은 예시를 마지막에 배치하면 효과적입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="4-chain-of-thought-cot--사고의-연쇄"&gt;
 4️⃣ Chain-of-Thought (CoT) — 사고의 연쇄
 &lt;a class="heading-anchor" href="#4-chain-of-thought-cot--%ec%82%ac%ea%b3%a0%ec%9d%98-%ec%97%b0%ec%87%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Chain-of-Thought(CoT)는 AI가 최종 답을 바로 내놓는 대신 &lt;strong&gt;단계별 추론 과정을 거치도록&lt;/strong&gt; 유도하는 기법입니다. 수학 계산, 논리 추론, 복잡한 판단 문제에서 정확도를 비약적으로 향상시킵니다.&lt;/p&gt;
&lt;h3 id="zero-shot-cot"&gt;
 Zero-Shot CoT
 &lt;a class="heading-anchor" href="#zero-shot-cot" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&amp;ldquo;Let&amp;rsquo;s think step by step&amp;rdquo; 또는 &amp;ldquo;단계별로 생각해봐&amp;quot;라는 트리거 문장 하나만 추가해도 모델이 단계적 사고를 시작합니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Zero-Shot CoT 예시
&amp;#34;철수는 사과를 5개 가지고 있었다. 영희에게 2개를 주고,
 마트에서 3개를 더 샀다. 철수에게 사과는 몇 개인가?

단계별로 생각하며 풀어줘.&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;# AI 응답 예시
1단계: 처음 사과 수 = 5개
2단계: 영희에게 준 후 = 5 - 2 = 3개
3단계: 마트에서 구매 후 = 3 + 3 = 6개
정답: 6개&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="few-shot-cot"&gt;
 Few-Shot CoT
 &lt;a class="heading-anchor" href="#few-shot-cot" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;단계별 추론 과정을 포함한 예시를 제공하면 더 복잡한 추론도 정확하게 수행합니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Few-Shot CoT 예시
&amp;#34;다음 문제를 단계별로 풀어줘.

Q: 버스에 승객이 10명 있었다. 정류장에서 3명이 내리고
 5명이 탔다. 버스에는 몇 명이 있는가?
A: 처음 10명에서 3명이 내리면 7명, 거기서 5명이 타면 12명.
 정답: 12명

Q: 상자에 공이 8개 있다. 4개를 꺼내고 2개를 넣었다.
 상자에는 몇 개가 남아있는가?
A:&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;CoT가 효과적인 상황:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;수학 계산 및 수식 풀기&lt;/li&gt;
&lt;li&gt;논리 추론과 인과관계 분석&lt;/li&gt;
&lt;li&gt;복잡한 다단계 의사결정&lt;/li&gt;
&lt;li&gt;코드 디버깅 과정 추적&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="5-기법-비교-한눈에-보기"&gt;
 5️⃣ 기법 비교 한눈에 보기
 &lt;a class="heading-anchor" href="#5-%ea%b8%b0%eb%b2%95-%eb%b9%84%ea%b5%90-%ed%95%9c%eb%88%88%ec%97%90-%eb%b3%b4%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;기법&lt;/th&gt;
					&lt;th&gt;예시 수&lt;/th&gt;
					&lt;th&gt;장점&lt;/th&gt;
					&lt;th&gt;단점&lt;/th&gt;
					&lt;th&gt;적합한 작업&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Zero-Shot&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;0개&lt;/td&gt;
					&lt;td&gt;빠르고 간편&lt;/td&gt;
					&lt;td&gt;복잡한 작업에서 불안정&lt;/td&gt;
					&lt;td&gt;번역, 요약, 단순 QA&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;One-Shot&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;1개&lt;/td&gt;
					&lt;td&gt;형식 가이드 가능&lt;/td&gt;
					&lt;td&gt;패턴 일반화 한계&lt;/td&gt;
					&lt;td&gt;형식이 명확한 작업&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Few-Shot&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;2~5개&lt;/td&gt;
					&lt;td&gt;일관된 결과, 형식 제어&lt;/td&gt;
					&lt;td&gt;프롬프트 길이 증가&lt;/td&gt;
					&lt;td&gt;감정 분류, 데이터 변환&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Zero-Shot CoT&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;0개 + 트리거&lt;/td&gt;
					&lt;td&gt;추론 품질 향상&lt;/td&gt;
					&lt;td&gt;단순 작업에는 과잉&lt;/td&gt;
					&lt;td&gt;수학, 논리, 분석&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Few-Shot CoT&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;추론 과정 포함 예시&lt;/td&gt;
					&lt;td&gt;가장 높은 정확도&lt;/td&gt;
					&lt;td&gt;프롬프트 설계 복잡&lt;/td&gt;
					&lt;td&gt;복잡한 다단계 추론&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-고급-기법-1-tree-of-thought-tot"&gt;
 🌳 고급 기법 1: Tree-of-Thought (ToT)
 &lt;a class="heading-anchor" href="#-%ea%b3%a0%ea%b8%89-%ea%b8%b0%eb%b2%95-1-tree-of-thought-tot" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Tree-of-Thought(ToT)는 CoT를 확장하여 &lt;strong&gt;여러 가능한 추론 경로를 동시에 탐색&lt;/strong&gt;하는 기법입니다. 나무의 가지처럼 여러 방향으로 사고를 전개하고 최적의 경로를 선택합니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Tree-of-Thought 프롬프트 예시
&amp;#34;다음 문제를 풀기 위한 3가지 접근법을 각각 제시하고,
 각 접근법의 장단점을 분석한 후 가장 효과적인 방법을 선택해줘.

문제: 스타트업의 초기 마케팅 예산 100만원을 어떻게 배분해야 할까?&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;적합한 상황:&lt;/strong&gt; 창의적 문제 해결, 전략 수립, 최적 방안 선택이 필요한 복잡한 의사결정&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-고급-기법-2-self-consistency-자기-일관성"&gt;
 🔄 고급 기법 2: Self-Consistency (자기 일관성)
 &lt;a class="heading-anchor" href="#-%ea%b3%a0%ea%b8%89-%ea%b8%b0%eb%b2%95-2-self-consistency-%ec%9e%90%ea%b8%b0-%ec%9d%bc%ea%b4%80%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Self-Consistency는 &lt;strong&gt;동일한 문제를 여러 번 풀게 한 후 가장 많이 나온 답을 선택&lt;/strong&gt;하는 기법입니다. 여러 전문가의 의견을 다수결로 취합하는 앙상블 방식입니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Self-Consistency 활용
&amp;#34;다음 코드의 버그를 3가지 다른 관점(성능, 보안, 가독성)에서
 각각 독립적으로 분석한 후, 공통으로 지적된 문제를 최우선으로 수정해줘.&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;CoT 결과의 신뢰도를 높이는 데 효과적이며, 중요한 판단이 필요할 때 활용합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-고급-기법-3-react-reasoning--acting"&gt;
 ⚡ 고급 기법 3: ReAct (Reasoning + Acting)
 &lt;a class="heading-anchor" href="#-%ea%b3%a0%ea%b8%89-%ea%b8%b0%eb%b2%95-3-react-reasoning--acting" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;ReAct는 &lt;strong&gt;추론(Reasoning)과 행동(Acting)을 반복&lt;/strong&gt;하는 기법으로, 외부 도구(검색, API, 코드 실행 등)와 연동하는 AI 에이전트에 사용됩니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Thought → Action → Observation → Thought → Action → ...&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;# ReAct 흐름 예시 (에이전트)
Thought: 현재 날씨를 알아야 추천이 가능하다.
Action: search(&amp;#34;서울 오늘 날씨&amp;#34;)
Observation: 서울 기온 12도, 비 예보

Thought: 비가 오므로 실내 활동을 추천해야 한다.
Action: search(&amp;#34;서울 실내 주말 여행지&amp;#34;)
Observation: 국립중앙박물관, CGV IMAX...

Final Answer: 오늘 비가 오니 국립중앙박물관 방문을 추천드립니다.&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;LangChain Agent, OpenAI Function Calling 같은 도구 연동 시스템이 이 방식을 기반으로 합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-고급-기법-4-prompt-chaining-프롬프트-체이닝"&gt;
 🔗 고급 기법 4: Prompt Chaining (프롬프트 체이닝)
 &lt;a class="heading-anchor" href="#-%ea%b3%a0%ea%b8%89-%ea%b8%b0%eb%b2%95-4-prompt-chaining-%ed%94%84%eb%a1%ac%ed%94%84%ed%8a%b8-%ec%b2%b4%ec%9d%b4%eb%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;복잡한 작업을 &lt;strong&gt;여러 단계의 프롬프트로 분해&lt;/strong&gt;하여 앞 단계의 출력을 다음 단계의 입력으로 연결하는 방식입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Prompt Chaining 예시 — 블로그 포스트 작성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;step1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;다음 주제로 블로그 목차 5개를 작성해줘: &lt;/span&gt;&lt;span class="si"&gt;{topic}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;step2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;다음 목차로 각 섹션의 핵심 내용 1문장씩 작성해줘:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;step1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;step3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;다음 개요를 바탕으로 전체 포스트를 작성해줘:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;step2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;한 번에 긴 작업을 시키면 품질이 떨어질 때, 단계별로 나눠서 각 단계의 품질을 보장합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-실무-프롬프트-설계-원칙"&gt;
 🛠️ 실무 프롬프트 설계 원칙
 &lt;a class="heading-anchor" href="#-%ec%8b%a4%eb%ac%b4-%ed%94%84%eb%a1%ac%ed%94%84%ed%8a%b8-%ec%84%a4%ea%b3%84-%ec%9b%90%ec%b9%99" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="역할-부여-role-prompting"&gt;
 역할 부여 (Role Prompting)
 &lt;a class="heading-anchor" href="#%ec%97%ad%ed%95%a0-%eb%b6%80%ec%97%ac-role-prompting" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;#34;너는 10년 경력의 시니어 백엔드 개발자야.
 다음 Python 코드를 프로덕션 레벨로 리뷰해줘.&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="출력-형식-명시"&gt;
 출력 형식 명시
 &lt;a class="heading-anchor" href="#%ec%b6%9c%eb%a0%a5-%ed%98%95%ec%8b%9d-%eb%aa%85%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;#34;다음 내용을 분석하고 아래 JSON 형식으로 반환해줘:
{
 &amp;#34;sentiment&amp;#34;: &amp;#34;긍정|부정|중립&amp;#34;,
 &amp;#34;confidence&amp;#34;: 0.0~1.0,
 &amp;#34;key_phrases&amp;#34;: [&amp;#34;키워드1&amp;#34;, &amp;#34;키워드2&amp;#34;]
}&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="제약-조건-설정"&gt;
 제약 조건 설정
 &lt;a class="heading-anchor" href="#%ec%a0%9c%ec%95%bd-%ec%a1%b0%ea%b1%b4-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;#34;다음 조건을 반드시 지켜서 답변해줘:
- 200자 이내로 작성
- 기술 용어 사용 금지
- 번호 목록 형식
- 한국어로만 답변&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="부정형-대신-긍정형-지시"&gt;
 부정형 대신 긍정형 지시
 &lt;a class="heading-anchor" href="#%eb%b6%80%ec%a0%95%ed%98%95-%eb%8c%80%ec%8b%a0-%ea%b8%8d%ec%a0%95%ed%98%95-%ec%a7%80%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# ❌ 부정형 (AI가 헷갈릴 수 있음)
&amp;#34;전문 용어를 사용하지 말고, 너무 길게 쓰지 마세요.&amp;#34;

# ✅ 긍정형 (명확한 지시)
&amp;#34;초등학생도 이해할 수 있는 쉬운 단어로, 3문장 이내로 설명해줘.&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="-기법-선택-가이드"&gt;
 📊 기법 선택 가이드
 &lt;a class="heading-anchor" href="#-%ea%b8%b0%eb%b2%95-%ec%84%a0%ed%83%9d-%ea%b0%80%ec%9d%b4%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;작업이 단순하고 명확한가?
 └─ YES → Zero-Shot
 └─ NO ↓

원하는 출력 형식이 특수한가?
 └─ YES → Few-Shot (예시 2~5개 제공)
 └─ NO ↓

수학/논리/복잡한 추론이 필요한가?
 └─ YES → CoT (Zero-Shot CoT 또는 Few-Shot CoT)
 └─ NO ↓

여러 방안 중 최적을 찾아야 하는가?
 └─ YES → Tree-of-Thought
 └─ NO ↓

외부 도구(검색, API) 연동이 필요한가?
 └─ YES → ReAct
 └─ NO → Prompt Chaining으로 단계 분해&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-zero-shot과-few-shot-중-무엇을-먼저-시도해야-하나요"&gt;
 Q. Zero-Shot과 Few-Shot 중 무엇을 먼저 시도해야 하나요?
 &lt;a class="heading-anchor" href="#q-zero-shot%ea%b3%bc-few-shot-%ec%a4%91-%eb%ac%b4%ec%97%87%ec%9d%84-%eb%a8%bc%ec%a0%80-%ec%8b%9c%eb%8f%84%ed%95%b4%ec%95%bc-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;항상 Zero-Shot부터 시작하세요. 원하는 결과가 나오지 않으면 예시를 1개(One-Shot), 그래도 부족하면 2~5개(Few-Shot)로 늘려가는 방식이 토큰 효율적입니다.&lt;/p&gt;
&lt;h3 id="q-cot는-모든-llm에서-효과가-있나요"&gt;
 Q. CoT는 모든 LLM에서 효과가 있나요?
 &lt;a class="heading-anchor" href="#q-cot%eb%8a%94-%eb%aa%a8%eb%93%a0-llm%ec%97%90%ec%84%9c-%ed%9a%a8%ea%b3%bc%ea%b0%80-%ec%9e%88%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;GPT-4, Claude 3+, Gemini 1.5 같은 대형 모델에서 효과가 뚜렷합니다. 작은 모델(7B 이하)에서는 CoT의 효과가 제한적이거나 오히려 성능을 저하시킬 수 있습니다.&lt;/p&gt;
&lt;h3 id="q-few-shot-예시는-몇-개가-적당한가요"&gt;
 Q. Few-Shot 예시는 몇 개가 적당한가요?
 &lt;a class="heading-anchor" href="#q-few-shot-%ec%98%88%ec%8b%9c%eb%8a%94-%eb%aa%87-%ea%b0%9c%ea%b0%80-%ec%a0%81%eb%8b%b9%ed%95%9c%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;일반적으로 3~5개가 최적입니다. 예시가 너무 많으면 토큰을 낭비하고 프롬프트가 복잡해집니다. 5개를 넘으면 대부분의 경우 큰 성능 향상이 없습니다.&lt;/p&gt;
&lt;h3 id="q-lets-think-step-by-step-외에-cot를-유도하는-문장이-있나요"&gt;
 Q. &amp;ldquo;Let&amp;rsquo;s think step by step&amp;rdquo; 외에 CoT를 유도하는 문장이 있나요?
 &lt;a class="heading-anchor" href="#q-lets-think-step-by-step-%ec%99%b8%ec%97%90-cot%eb%a5%bc-%ec%9c%a0%eb%8f%84%ed%95%98%eb%8a%94-%eb%ac%b8%ec%9e%a5%ec%9d%b4-%ec%9e%88%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;다양한 트리거 문장이 효과적입니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;단계별로 생각해봐&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;풀이 과정을 보여줘&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;이유를 먼저 설명하고 결론을 내려줘&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;틀릴 수 있는 가능성을 먼저 검토하고 답해줘&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="q-프롬프트-길이가-길수록-좋은가요"&gt;
 Q. 프롬프트 길이가 길수록 좋은가요?
 &lt;a class="heading-anchor" href="#q-%ed%94%84%eb%a1%ac%ed%94%84%ed%8a%b8-%ea%b8%b8%ec%9d%b4%ea%b0%80-%ea%b8%b8%ec%88%98%eb%a1%9d-%ec%a2%8b%ec%9d%80%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;아닙니다. 불필요한 미사여구나 중복 설명은 오히려 LLM을 혼란시킬 수 있습니다. 간결하고 명확하게 핵심 지시만 포함하는 것이 원칙입니다.&lt;/p&gt;</description></item><item><title>[Backend] 🚀 Supabase란? Firebase·Appwrite와 차이점 완벽 비교</title><link>https://kyungryeol-yoon.github.io/backend/supabase/supabase-vs-firebase-appwrite/</link><pubDate>Sat, 01 Nov 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/supabase/supabase-vs-firebase-appwrite/</guid><description>&lt;p&gt;Supabase는 PostgreSQL 기반의 오픈소스 BaaS(Backend as a Service) 플랫폼으로, Firebase의 대안으로 설계되었습니다. 인증, 데이터베이스, 실시간 처리, 파일 스토리지, 서버리스 함수를 하나의 패키지로 제공하여 백엔드 인프라 구축 시간을 대폭 단축할 수 있습니다. 이 글에서는 Supabase의 핵심 개념과 Firebase, Appwrite와의 차이점을 실무 관점에서 비교합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-supabase란"&gt;
 🧩 Supabase란?
 &lt;a class="heading-anchor" href="#-supabase%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Supabase는 Google Firebase의 오픈소스 대안으로 2020년 등장한 BaaS(Backend as a Service) 플랫폼입니다. PostgreSQL을 핵심 데이터베이스로 사용하며, 인증·실시간 처리·파일 스토리지·서버리스 함수를 통합 제공합니다.&lt;/p&gt;
&lt;p&gt;Firebase가 NoSQL(Firestore) 기반인 것과 달리, Supabase는 표준 SQL과 관계형 데이터 모델을 사용할 수 있다는 점이 가장 큰 차별점입니다. 오픈소스이기 때문에 클라우드 호스팅뿐만 아니라 자체 서버에서 셀프 호스팅도 가능합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-baasbackend-as-a-service란"&gt;
 🔍 BaaS(Backend as a Service)란?
 &lt;a class="heading-anchor" href="#-baasbackend-as-a-service%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;BaaS는 &amp;ldquo;인증, 데이터베이스, 파일 스토리지 등 공통 백엔드 기능을 서비스로 제공하는 플랫폼&amp;quot;입니다. 개발자가 직접 서버를 구축하거나 API를 개발할 필요 없이, 프론트엔드 코드만으로 전체 애플리케이션을 만들 수 있게 해줍니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: BaaS는 스타트업이나 소규모 팀이 빠른 시장 진입(MVP)이 필요할 때 특히 효과적입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;대표적인 BaaS 플랫폼으로는 Firebase, Supabase, Appwrite가 있으며, 각각 설계 철학이 다릅니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-firebase-vs-supabase-vs-appwrite-비교"&gt;
 ⚡ Firebase vs Supabase vs Appwrite 비교
 &lt;a class="heading-anchor" href="#-firebase-vs-supabase-vs-appwrite-%eb%b9%84%ea%b5%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;Firebase&lt;/th&gt;
					&lt;th&gt;Supabase&lt;/th&gt;
					&lt;th&gt;Appwrite&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;설계 방향&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;완제품 지향&lt;/td&gt;
					&lt;td&gt;통합 데이터 흐름&lt;/td&gt;
					&lt;td&gt;셀프 호스팅 자유도&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;데이터베이스&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;NoSQL (Firestore)&lt;/td&gt;
					&lt;td&gt;SQL (PostgreSQL)&lt;/td&gt;
					&lt;td&gt;SQL/NoSQL 선택&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;제공 방식&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;완전 관리형&lt;/td&gt;
					&lt;td&gt;관리형 + 로컬 개발&lt;/td&gt;
					&lt;td&gt;직접 운영&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;오픈소스&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;❌&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;벤더 락인&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;높음 (Google)&lt;/td&gt;
					&lt;td&gt;낮음&lt;/td&gt;
					&lt;td&gt;없음&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;권한 구조&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;기능별 분리&lt;/td&gt;
					&lt;td&gt;RLS 기반 통합&lt;/td&gt;
					&lt;td&gt;직접 구성&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;AI/벡터 지원&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;별도 솔루션 필요&lt;/td&gt;
					&lt;td&gt;pgvector 기본 지원&lt;/td&gt;
					&lt;td&gt;별도 설정 필요&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;적합 팀&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;MVP/모바일 팀&lt;/td&gt;
					&lt;td&gt;프론트 중심 소규모 팀&lt;/td&gt;
					&lt;td&gt;인프라 운영 가능 팀&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="firebase가-적합한-경우"&gt;
 Firebase가 적합한 경우
 &lt;a class="heading-anchor" href="#firebase%ea%b0%80-%ec%a0%81%ed%95%a9%ed%95%9c-%ea%b2%bd%ec%9a%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Firebase는 &amp;ldquo;모바일 앱 개발과 초고속 MVP 구현&amp;quot;에 최적화된 플랫폼입니다. Google 생태계와의 긴밀한 통합, 실시간 데이터 동기화, Firebase Analytics 등 모바일에 특화된 서비스가 강점입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;모바일(iOS/Android) 앱 개발 중심&lt;/li&gt;
&lt;li&gt;Google 생태계 전반 활용이 필요한 경우&lt;/li&gt;
&lt;li&gt;NoSQL 데이터 구조에 익숙한 팀&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="supabase가-적합한-경우"&gt;
 Supabase가 적합한 경우
 &lt;a class="heading-anchor" href="#supabase%ea%b0%80-%ec%a0%81%ed%95%a9%ed%95%9c-%ea%b2%bd%ec%9a%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Supabase는 &amp;ldquo;SQL에 익숙한 팀이 빠른 개발과 통제권을 동시에 원할 때&amp;rdquo; 최적입니다. 장기 운영을 고려하면서도 빠르게 제품을 출시해야 하는 팀에 어울립니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SQL 및 관계형 데이터베이스에 익숙한 팀&lt;/li&gt;
&lt;li&gt;AI/ML 기능을 앱에 통합할 계획이 있는 경우&lt;/li&gt;
&lt;li&gt;Firebase의 벤더 락인을 피하고 싶은 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="appwrite가-적합한-경우"&gt;
 Appwrite가 적합한 경우
 &lt;a class="heading-anchor" href="#appwrite%ea%b0%80-%ec%a0%81%ed%95%a9%ed%95%9c-%ea%b2%bd%ec%9a%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Appwrite는 &amp;ldquo;인프라를 직접 운영할 수 있는 팀이 완전한 데이터 주권을 원할 때&amp;rdquo; 적합합니다. 셀프 호스팅을 통해 데이터를 완전히 통제할 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;데이터를 자체 서버에서 완전히 통제해야 하는 경우&lt;/li&gt;
&lt;li&gt;인프라 운영 역량이 있는 팀&lt;/li&gt;
&lt;li&gt;오픈소스 커스터마이징이 필요한 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-supabase-핵심-기능"&gt;
 🛠️ Supabase 핵심 기능
 &lt;a class="heading-anchor" href="#-supabase-%ed%95%b5%ec%8b%ac-%ea%b8%b0%eb%8a%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1-database-postgresql"&gt;
 1️⃣ Database (PostgreSQL)
 &lt;a class="heading-anchor" href="#1-database-postgresql" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Supabase의 데이터베이스는 완전한 PostgreSQL입니다. 복잡한 SQL 쿼리, 조인, 트랜잭션, 인덱스를 모두 활용할 수 있으며, Row Level Security(RLS)로 사용자별 데이터 접근 권한을 DB 레벨에서 제어합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- RLS 정책 예시: 사용자가 자신의 데이터만 조회
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;POLICY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;users can view own data&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;profiles&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FOR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;USING&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: RLS를 활성화하면 API에서 별도 권한 체크 없이 DB 자체에서 보안이 처리됩니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="2-auth-인증"&gt;
 2️⃣ Auth (인증)
 &lt;a class="heading-anchor" href="#2-auth-%ec%9d%b8%ec%a6%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Supabase Auth는 이메일/패스워드, 소셜 로그인(Google, GitHub, Apple), OTP, 패스키를 대시보드에서 클릭 몇 번으로 설정할 수 있습니다. JWT 기반의 토큰과 세션 관리는 자동으로 처리됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;@supabase/supabase-js&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SUPABASE_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SUPABASE_ANON_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 소셜 로그인 (GitHub)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signInWithOAuth&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;github&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 이메일 로그인
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signInWithPassword&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;user@example.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;password&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="3-realtime-실시간-처리"&gt;
 3️⃣ Realtime (실시간 처리)
 &lt;a class="heading-anchor" href="#3-realtime-%ec%8b%a4%ec%8b%9c%ea%b0%84-%ec%b2%98%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Supabase Realtime은 PostgreSQL의 변경 사항을 웹소켓으로 클라이언트에 즉시 전달합니다. 별도 폴링 없이 채팅, 알림, 협업 도구를 구현할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 실시간 메시지 구독
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;channel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;messages&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;postgres_changes&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;INSERT&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;public&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;messages&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;새 메시지:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="4-storage-파일-관리"&gt;
 4️⃣ Storage (파일 관리)
 &lt;a class="heading-anchor" href="#4-storage-%ed%8c%8c%ec%9d%bc-%ea%b4%80%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;이미지·동영상 업로드 시 자동 썸네일 변환, CDN 연동, RLS 기반 접근 제어가 기본 내장되어 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 파일 업로드
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;avatars&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;/avatar.png`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 퍼블릭 URL 조회
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;avatars&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPublicUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;/avatar.png`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="5-edge-functions-서버리스"&gt;
 5️⃣ Edge Functions (서버리스)
 &lt;a class="heading-anchor" href="#5-edge-functions-%ec%84%9c%eb%b2%84%eb%a6%ac%ec%8a%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Deno 기반의 서버리스 함수로 인증 체크, 웹훅 처리, 외부 API 호출, AI 연동 등 서버 로직을 빠르게 배포할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Edge Function 예시: OpenAI 연동
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;serve&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;https://deno.land/std@0.177.0/http/server.ts&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://api.openai.com/v1/chat/completions&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;Authorization&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sb"&gt;`Bearer &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;Deno&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;OPENAI_API_KEY&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;application/json&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;body&lt;/span&gt;: &lt;span class="kt"&gt;JSON.stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;gpt-4o&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;user&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;: &lt;span class="kt"&gt;query&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;application/json&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="6-vector-db-pgvector"&gt;
 6️⃣ Vector DB (pgvector)
 &lt;a class="heading-anchor" href="#6-vector-db-pgvector" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Supabase는 pgvector 확장을 기본 지원하여 별도 벡터 데이터베이스 없이 PostgreSQL 안에서 AI 임베딩 저장과 유사도 검색을 처리할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- pgvector 확장 활성화
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;EXTENSION&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;IF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;NOT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;EXISTS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- 임베딩 컬럼이 있는 테이블 생성
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TABLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BIGSERIAL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;PRIMARY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;VECTOR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1536&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- 코사인 유사도 검색
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;query_embedding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;similarity&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;query_embedding&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;LIMIT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: Supabase + pgvector 조합은 RAG(Retrieval-Augmented Generation) 시스템 구축에 매우 효과적입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-요금제-비교"&gt;
 💰 요금제 비교
 &lt;a class="heading-anchor" href="#-%ec%9a%94%ea%b8%88%ec%a0%9c-%eb%b9%84%ea%b5%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;플랜&lt;/th&gt;
					&lt;th&gt;가격&lt;/th&gt;
					&lt;th&gt;DB 용량&lt;/th&gt;
					&lt;th&gt;스토리지&lt;/th&gt;
					&lt;th&gt;MAU&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;strong&gt;Free&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;무료&lt;/td&gt;
					&lt;td&gt;500MB&lt;/td&gt;
					&lt;td&gt;1GB&lt;/td&gt;
					&lt;td&gt;10,000&lt;/td&gt;
					&lt;td&gt;1주 미사용 시 자동 중지, 2개 프로젝트 제한&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Pro&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;$25/월&lt;/td&gt;
					&lt;td&gt;8GB&lt;/td&gt;
					&lt;td&gt;100GB&lt;/td&gt;
					&lt;td&gt;100,000&lt;/td&gt;
					&lt;td&gt;자동 백업, 커스텀 도메인&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Team&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;$599/월&lt;/td&gt;
					&lt;td&gt;커스텀&lt;/td&gt;
					&lt;td&gt;커스텀&lt;/td&gt;
					&lt;td&gt;무제한&lt;/td&gt;
					&lt;td&gt;SOC2, HIPAA, SSO 지원&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;문의&lt;/td&gt;
					&lt;td&gt;커스텀&lt;/td&gt;
					&lt;td&gt;커스텀&lt;/td&gt;
					&lt;td&gt;무제한&lt;/td&gt;
					&lt;td&gt;전용 서버, SLA 보장&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ Free 플랜은 7일 동안 활동이 없으면 프로젝트가 자동 일시정지됩니다. 개인 프로젝트나 테스트 환경에서 주의가 필요합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-supabase-장단점-요약"&gt;
 ✅ Supabase 장단점 요약
 &lt;a class="heading-anchor" href="#-supabase-%ec%9e%a5%eb%8b%a8%ec%a0%90-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="장점"&gt;
 장점
 &lt;a class="heading-anchor" href="#%ec%9e%a5%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SQL 표준 지원&lt;/strong&gt;: 복잡한 관계형 쿼리, 조인, 트랜잭션 완전 지원&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;오픈소스&lt;/strong&gt;: 벤더 락인 없이 자체 호스팅으로 전환 가능&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI 통합 용이&lt;/strong&gt;: pgvector로 벡터 DB를 별도 서비스 없이 활용&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;통합 솔루션&lt;/strong&gt;: 인증·DB·스토리지·실시간·함수가 하나의 패키지&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;비용 예측 가능&lt;/strong&gt;: Firebase의 사용량 기반 과금과 달리 플랜 기반 정액제&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="단점"&gt;
 단점
 &lt;a class="heading-anchor" href="#%eb%8b%a8%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Free 플랜 제약&lt;/strong&gt;: 1주 미사용 시 자동 일시정지, 2개 프로젝트 제한&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Region 고정&lt;/strong&gt;: 프로젝트 생성 후 리전 변경 불가&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PostgreSQL 기본 지식 필요&lt;/strong&gt;: SQL에 익숙하지 않으면 초기 설정이 어려울 수 있음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Firebase 마이그레이션 복잡도&lt;/strong&gt;: NoSQL → 관계형 전환 시 데이터 재설계 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-빠른-시작-가이드"&gt;
 🚀 빠른 시작 가이드
 &lt;a class="heading-anchor" href="#-%eb%b9%a0%eb%a5%b8-%ec%8b%9c%ec%9e%91-%ea%b0%80%ec%9d%b4%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="supabase-cli-설치-및-로컬-개발-환경-구성"&gt;
 Supabase CLI 설치 및 로컬 개발 환경 구성
 &lt;a class="heading-anchor" href="#supabase-cli-%ec%84%a4%ec%b9%98-%eb%b0%8f-%eb%a1%9c%ec%bb%ac-%ea%b0%9c%eb%b0%9c-%ed%99%98%ea%b2%bd-%ea%b5%ac%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Supabase CLI 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;npm install -g supabase
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 로그인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;supabase login
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 새 프로젝트 초기화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;supabase init
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 로컬 개발 서버 시작 (Docker 필요)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;supabase start&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="nextjs--supabase-연동"&gt;
 Next.js + Supabase 연동
 &lt;a class="heading-anchor" href="#nextjs--supabase-%ec%97%b0%eb%8f%99" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;npm install @supabase/supabase-js @supabase/ssr&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// lib/supabase.ts
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createBrowserClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;@supabase/ssr&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createBrowserClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NEXT_PUBLIC_SUPABASE_URL&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NEXT_PUBLIC_SUPABASE_ANON_KEY&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 데이터 조회 예시
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;: &lt;span class="kt"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;posts&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;id, title, created_at&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;created_at&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ascending&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-supabase와-firebase-중-무엇을-선택해야-하나요"&gt;
 Q. Supabase와 Firebase 중 무엇을 선택해야 하나요?
 &lt;a class="heading-anchor" href="#q-supabase%ec%99%80-firebase-%ec%a4%91-%eb%ac%b4%ec%97%87%ec%9d%84-%ec%84%a0%ed%83%9d%ed%95%b4%ec%95%bc-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;SQL과 관계형 데이터에 익숙하거나 AI 기능 통합이 필요하다면 Supabase를 권장합니다. 모바일 앱 개발이 주목적이고 Google 생태계를 적극 활용한다면 Firebase가 더 적합합니다.&lt;/p&gt;
&lt;h3 id="q-supabase는-셀프-호스팅이-가능한가요"&gt;
 Q. Supabase는 셀프 호스팅이 가능한가요?
 &lt;a class="heading-anchor" href="#q-supabase%eb%8a%94-%ec%85%80%ed%94%84-%ed%98%b8%ec%8a%a4%ed%8c%85%ec%9d%b4-%ea%b0%80%eb%8a%a5%ed%95%9c%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;네, 가능합니다. Supabase는 오픈소스이며 Docker Compose로 자체 서버에 배포할 수 있습니다. &lt;code&gt;supabase/supabase&lt;/code&gt; GitHub 리포지토리에서 공식 셀프 호스팅 가이드를 확인할 수 있습니다.&lt;/p&gt;
&lt;h3 id="q-free-플랜의-프로젝트-자동-중지를-방지할-수-있나요"&gt;
 Q. Free 플랜의 프로젝트 자동 중지를 방지할 수 있나요?
 &lt;a class="heading-anchor" href="#q-free-%ed%94%8c%eb%9e%9c%ec%9d%98-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%9e%90%eb%8f%99-%ec%a4%91%ec%a7%80%eb%a5%bc-%eb%b0%a9%ec%a7%80%ed%95%a0-%ec%88%98-%ec%9e%88%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;무료 플랜에서는 7일 연속 미사용 시 자동 일시정지됩니다. 주기적으로 접속하거나, Pro 플랜($25/월)으로 업그레이드하면 이 제한이 사라집니다.&lt;/p&gt;
&lt;h3 id="q-pgvector를-활용한-ai-기능은-어떻게-사용하나요"&gt;
 Q. pgvector를 활용한 AI 기능은 어떻게 사용하나요?
 &lt;a class="heading-anchor" href="#q-pgvector%eb%a5%bc-%ed%99%9c%ec%9a%a9%ed%95%9c-ai-%ea%b8%b0%eb%8a%a5%ec%9d%80-%ec%96%b4%eb%96%bb%ea%b2%8c-%ec%82%ac%ec%9a%a9%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Supabase 대시보드의 &lt;code&gt;Database &amp;gt; Extensions&lt;/code&gt; 탭에서 &lt;code&gt;vector&lt;/code&gt; 확장을 활성화합니다. 이후 VECTOR 타입 컬럼을 가진 테이블을 생성하고 OpenAI 등 임베딩 모델로 생성한 벡터를 저장하면 유사도 검색이 가능합니다.&lt;/p&gt;
&lt;h3 id="q-free-플랜의-프로젝트-개수-제한은"&gt;
 Q. Free 플랜의 프로젝트 개수 제한은?
 &lt;a class="heading-anchor" href="#q-free-%ed%94%8c%eb%9e%9c%ec%9d%98-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ea%b0%9c%ec%88%98-%ec%a0%9c%ed%95%9c%ec%9d%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Free 플랜에서는 최대 2개의 프로젝트를 생성할 수 있습니다. Pro 플랜부터는 제한이 없습니다.&lt;/p&gt;</description></item><item><title>[Python] 🔍 Pylint로 Python 코드 품질 관리하기: 설치부터 CI/CD 연동까지</title><link>https://kyungryeol-yoon.github.io/backend/python/pylint-python-static-analysis/</link><pubDate>Wed, 01 Oct 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/python/pylint-python-static-analysis/</guid><description>&lt;p&gt;Pylint는 Python 코드의 오류 검출, PEP 8 스타일 위반, 코드 복잡도 분석을 수행하는 정적 분석 도구입니다. 단순한 스타일 검사를 넘어 잠재적 버그까지 탐지하며, 10점 만점 품질 점수를 제공합니다. 이 글에서는 Pylint의 기본 사용법부터 &lt;code&gt;.pylintrc&lt;/code&gt; 설정, VSCode 연동, pre-commit CI/CD 통합까지 실무에서 바로 활용할 수 있도록 정리합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-pylint란"&gt;
 🔍 Pylint란?
 &lt;a class="heading-anchor" href="#-pylint%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Pylint는 Python 코드를 실행하지 않고도 품질 문제를 탐지하는 &lt;strong&gt;정적 코드 분석(static analysis) 도구&lt;/strong&gt;입니다. 단순한 스타일 검사기를 넘어, 런타임 이전에 발견하기 어려운 버그와 잠재적 오류까지 잡아냅니다.&lt;/p&gt;
&lt;p&gt;주요 검사 항목은 다음과 같습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;문법 오류 및 잠재적 버그&lt;/strong&gt; — 정의되지 않은 변수, self 누락, 잘못된 import 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PEP 8 코딩 표준 위반&lt;/strong&gt; — 명명 규칙(snake_case, PascalCase), 줄 길이, 공백 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;코드 복잡도&lt;/strong&gt; — 중복 코드, 너무 긴 함수, 지나치게 많은 인자 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;문서화 부재&lt;/strong&gt; — docstring 미작성 경고&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;10점 만점 품질 점수&lt;/strong&gt; — 코드 전체의 상태를 수치로 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: Pylint의 경고가 절대적인 기준은 아닙니다. 의도된 코드가 경고를 받을 수 있으므로, 프로젝트 상황에 맞게 규칙을 조정하는 것이 중요합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-linter-vs-formatter-차이"&gt;
 ⚖️ Linter vs Formatter 차이
 &lt;a class="heading-anchor" href="#-linter-vs-formatter-%ec%b0%a8%ec%9d%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;코드 품질 도구를 처음 접할 때 가장 혼란스러운 부분이 Linter와 Formatter의 차이입니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;구분&lt;/th&gt;
					&lt;th&gt;Linter&lt;/th&gt;
					&lt;th&gt;Formatter&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;역할&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;코드의 논리 오류·잠재적 버그 탐지&lt;/td&gt;
					&lt;td&gt;코드 스타일·레이아웃 자동 정리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;동작&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;문제를 보고하고 수정은 개발자가 직접&lt;/td&gt;
					&lt;td&gt;코드를 자동으로 수정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;예시&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;미사용 변수, import 오류, 명명 규칙 위반&lt;/td&gt;
					&lt;td&gt;들여쓰기 정렬, 따옴표 통일, 줄 바꿈&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;대표 도구&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Pylint, Flake8, Ruff&lt;/td&gt;
					&lt;td&gt;Black, YAPF, Ruff(format)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-python-코드-품질-도구-비교"&gt;
 📊 Python 코드 품질 도구 비교
 &lt;a class="heading-anchor" href="#-python-%ec%bd%94%eb%93%9c-%ed%92%88%ec%a7%88-%eb%8f%84%ea%b5%ac-%eb%b9%84%ea%b5%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;실무에서 자주 함께 언급되는 4가지 도구를 비교합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;도구&lt;/th&gt;
					&lt;th&gt;분류&lt;/th&gt;
					&lt;th&gt;특징&lt;/th&gt;
					&lt;th&gt;속도&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Pylint&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Linter&lt;/td&gt;
					&lt;td&gt;가장 엄격, 품질 점수 제공, 심층 분석&lt;/td&gt;
					&lt;td&gt;느림&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Flake8&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Linter&lt;/td&gt;
					&lt;td&gt;안정적, PEP 8 중심, 설정 간단&lt;/td&gt;
					&lt;td&gt;빠름&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Black&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Formatter&lt;/td&gt;
					&lt;td&gt;설정 없이 일관된 스타일 강제, 팀 협업 최적&lt;/td&gt;
					&lt;td&gt;빠름&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Ruff&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Linter + Formatter&lt;/td&gt;
					&lt;td&gt;Rust 기반, 매우 빠름, Flake8+isort+Black 통합&lt;/td&gt;
					&lt;td&gt;매우 빠름&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Flake8 ─ 스타일 검사 → 오류 보고
Pylint ─ 심층 분석 → 오류 보고 + 개선 제안 + 품질 점수
Black ─ 자동 포맷팅 → 코드 직접 수정
Ruff ─ lint + format → 위 세 도구를 대부분 대체&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: 2026년 현재는 Ruff 단독 사용으로 lint·format·import 정리까지 처리하는 방식이 증가 중입니다. 하지만 Pylint는 Ruff가 탐지하지 못하는 심층 분석(코드 냄새, 복잡도, 품질 점수)에서 여전히 강점이 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-설치-및-기본-사용법"&gt;
 🚀 설치 및 기본 사용법
 &lt;a class="heading-anchor" href="#-%ec%84%a4%ec%b9%98-%eb%b0%8f-%ea%b8%b0%eb%b3%b8-%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="설치"&gt;
 설치
 &lt;a class="heading-anchor" href="#%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pip install pylint&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;가상 환경을 사용하는 경우 환경 활성화 후 설치합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;python -m venv .venv
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate &lt;span class="c1"&gt;# Windows: .venv\Scripts\activate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;pip install pylint&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="파일-분석"&gt;
 파일 분석
 &lt;a class="heading-anchor" href="#%ed%8c%8c%ec%9d%bc-%eb%b6%84%ec%84%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 단일 파일 분석&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;pylint my_script.py
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 모듈 전체 분석&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;pylint my_package/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 여러 파일 동시 분석&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;pylint src/main.py src/utils.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="출력-결과-예시"&gt;
 출력 결과 예시
 &lt;a class="heading-anchor" href="#%ec%b6%9c%eb%a0%a5-%ea%b2%b0%ea%b3%bc-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;my_script.py:5:0: C0304: Final newline missing (missing-final-newline)
my_script.py:10:4: W0611: Unused import os (unused-import)
my_script.py:15:0: E1101: Module &amp;#39;os&amp;#39; has no &amp;#39;pathh&amp;#39; member (no-member)

-----------------------------------
Your code has been rated at 6.50/10&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;출력 형식은 &lt;code&gt;파일명:줄번호:컬럼:메시지코드: 설명 (코드명)&lt;/code&gt; 입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-메시지-유형과-코드-이해하기"&gt;
 📋 메시지 유형과 코드 이해하기
 &lt;a class="heading-anchor" href="#-%eb%a9%94%ec%8b%9c%ec%a7%80-%ec%9c%a0%ed%98%95%ea%b3%bc-%ec%bd%94%eb%93%9c-%ec%9d%b4%ed%95%b4%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Pylint 메시지는 알파벳 접두사로 심각도를 구분합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;접두사&lt;/th&gt;
					&lt;th&gt;유형&lt;/th&gt;
					&lt;th&gt;의미&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;C&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Convention&lt;/td&gt;
					&lt;td&gt;PEP 8 등 코딩 규칙 위반&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;W&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Warning&lt;/td&gt;
					&lt;td&gt;잠재적 문제, 개선 권장&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;E&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Error&lt;/td&gt;
					&lt;td&gt;런타임 오류로 이어질 가능성이 높은 버그&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;R&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Refactor&lt;/td&gt;
					&lt;td&gt;리팩토링이 필요한 코드 구조&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;F&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Fatal&lt;/td&gt;
					&lt;td&gt;분석 자체를 막는 치명적 오류&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="자주-마주치는-메시지-코드"&gt;
 자주 마주치는 메시지 코드
 &lt;a class="heading-anchor" href="#%ec%9e%90%ec%a3%bc-%eb%a7%88%ec%a3%bc%ec%b9%98%eb%8a%94-%eb%a9%94%ec%8b%9c%ec%a7%80-%ec%bd%94%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;코드&lt;/th&gt;
					&lt;th&gt;이름&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;C0301&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;line-too-long&lt;/td&gt;
					&lt;td&gt;줄 길이 초과 (기본 100자)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;C0114&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;missing-module-docstring&lt;/td&gt;
					&lt;td&gt;모듈 docstring 없음&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;C0116&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;missing-function-docstring&lt;/td&gt;
					&lt;td&gt;함수 docstring 없음&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;W0611&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;unused-import&lt;/td&gt;
					&lt;td&gt;사용하지 않는 import&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;W0612&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;unused-variable&lt;/td&gt;
					&lt;td&gt;사용하지 않는 변수&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;W1203&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;logging-fstring&lt;/td&gt;
					&lt;td&gt;로깅에 f-string 사용 (lazy loading 불가)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;E0401&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;import-error&lt;/td&gt;
					&lt;td&gt;모듈을 찾을 수 없음&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;E1101&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;no-member&lt;/td&gt;
					&lt;td&gt;존재하지 않는 속성/메서드 접근&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;R0913&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;too-many-arguments&lt;/td&gt;
					&lt;td&gt;함수 인자 수 초과 (기본 5개)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;R1705&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;no-else-return&lt;/td&gt;
					&lt;td&gt;return 후 불필요한 else 블록&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-pylintrc-설정-파일"&gt;
 ⚙️ .pylintrc 설정 파일
 &lt;a class="heading-anchor" href="#-pylintrc-%ec%84%a4%ec%a0%95-%ed%8c%8c%ec%9d%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;프로젝트 루트에 &lt;code&gt;.pylintrc&lt;/code&gt; 파일을 두면 팀 전체에 일관된 규칙을 적용할 수 있습니다.&lt;/p&gt;
&lt;h3 id="기본-템플릿-생성"&gt;
 기본 템플릿 생성
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ed%85%9c%ed%94%8c%eb%a6%bf-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pylint --generate-rcfile &amp;gt; .pylintrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="주요-설정-항목"&gt;
 주요 설정 항목
 &lt;a class="heading-anchor" href="#%ec%a3%bc%ec%9a%94-%ec%84%a4%ec%a0%95-%ed%95%ad%eb%aa%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[MASTER]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 가상환경, 외부 라이브러리 경로 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;init-hook&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;import sys; sys.path.insert(0, &amp;#34;src&amp;#34;)&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 병렬 처리 (0 = CPU 수에 맞게 자동)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[MESSAGES CONTROL]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 비활성화할 메시지 코드 (쉼표로 구분)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;disable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; C0114, # missing-module-docstring
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; C0115, # missing-class-docstring
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; C0116, # missing-function-docstring
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; W1203 # logging-fstring&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[FORMAT]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 한 줄 최대 길이 (PEP 8 기본값 79, 실무 100~120 권장)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;max-line-length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;120&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 들여쓰기 단위&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;indent-string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39; &amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[DESIGN]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 함수 최대 인자 수&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;max-args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;7&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 함수 최대 줄 수&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;max-statements&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;50&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[TYPECHECK]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 외부 라이브러리 타입 체크 오류 무시&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ignored-modules&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;numpy,pandas,pydantic&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-경고-비활성화-방법"&gt;
 🔕 경고 비활성화 방법
 &lt;a class="heading-anchor" href="#-%ea%b2%bd%ea%b3%a0-%eb%b9%84%ed%99%9c%ec%84%b1%ed%99%94-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;프로젝트 전체가 아닌 특정 코드에만 규칙을 비활성화할 때 인라인 주석을 사용합니다.&lt;/p&gt;
&lt;h3 id="1줄-비활성화"&gt;
 1줄 비활성화
 &lt;a class="heading-anchor" href="#1%ec%a4%84-%eb%b9%84%ed%99%9c%ec%84%b1%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt; &lt;span class="c1"&gt;# pylint: disable=unused-import&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="블록-단위-비활성화"&gt;
 블록 단위 비활성화
 &lt;a class="heading-anchor" href="#%eb%b8%94%eb%a1%9d-%eb%8b%a8%ec%9c%84-%eb%b9%84%ed%99%9c%ec%84%b1%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pylint: disable=too-many-arguments&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;complex_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pylint: enable=too-many-arguments&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="파일-전체-비활성화"&gt;
 파일 전체 비활성화
 &lt;a class="heading-anchor" href="#%ed%8c%8c%ec%9d%bc-%ec%a0%84%ec%b2%b4-%eb%b9%84%ed%99%9c%ec%84%b1%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;파일 최상단에 추가합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pylint: disable=missing-module-docstring,missing-function-docstring&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ 인라인 비활성화를 남용하면 Pylint의 효과가 떨어집니다. 실제로 불필요한 경고만 선택적으로 끄고, 가능하면 &lt;code&gt;.pylintrc&lt;/code&gt;에서 프로젝트 전체 기준을 설정하는 것이 바람직합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-vscode-연동"&gt;
 🖥️ VSCode 연동
 &lt;a class="heading-anchor" href="#-vscode-%ec%97%b0%eb%8f%99" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="settingsjson-설정"&gt;
 settings.json 설정
 &lt;a class="heading-anchor" href="#settingsjson-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;.vscode/settings.json&lt;/code&gt;에 다음을 추가합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;python.linting.enabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;python.linting.pylintEnabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;python.linting.pylintArgs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;--disable&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;C0301&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;--max-line-length&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;120&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="저장-시-자동-검사"&gt;
 저장 시 자동 검사
 &lt;a class="heading-anchor" href="#%ec%a0%80%ec%9e%a5-%ec%8b%9c-%ec%9e%90%eb%8f%99-%ea%b2%80%ec%82%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;editor.formatOnSave&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;python.linting.lintOnSave&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: VSCode의 Python 확장(ms-python.python)을 설치하면 편집 중 실시간으로 Pylint 오류가 표시됩니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-pre-commit으로-cicd-통합"&gt;
 🔗 pre-commit으로 CI/CD 통합
 &lt;a class="heading-anchor" href="#-pre-commit%ec%9c%bc%eb%a1%9c-cicd-%ed%86%b5%ed%95%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;커밋 시점에 Pylint를 자동 실행하면, 오류가 있는 코드는 커밋 자체가 차단됩니다.&lt;/p&gt;
&lt;h3 id="pre-commit-설치"&gt;
 pre-commit 설치
 &lt;a class="heading-anchor" href="#pre-commit-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pip install pre-commit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="pre-commit-configyaml-작성"&gt;
 .pre-commit-config.yaml 작성
 &lt;a class="heading-anchor" href="#pre-commit-configyaml-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://github.com/pycqa/pylint&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rev&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pylint&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;--max-line-length=120&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;--disable=C0114,C0115,C0116&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;additional_dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pydantic&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pyyaml&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;requests&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="훅-설치-및-실행"&gt;
 훅 설치 및 실행
 &lt;a class="heading-anchor" href="#%ed%9b%85-%ec%84%a4%ec%b9%98-%eb%b0%8f-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 훅 설치 (최초 1회)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;pre-commit install
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 전체 파일 수동 실행&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;pre-commit run --all-files&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이후 &lt;code&gt;git commit&lt;/code&gt; 시 자동으로 Pylint가 실행되며, 오류가 있으면 커밋이 차단됩니다.&lt;/p&gt;
&lt;h3 id="github-actions-통합"&gt;
 GitHub Actions 통합
 &lt;a class="heading-anchor" href="#github-actions-%ed%86%b5%ed%95%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Lint&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;push, pull_request]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pylint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;actions/checkout@v4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;actions/setup-python@v5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;python-version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;3.12&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pip install pylint&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pylint src/ --fail-under=8.0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;--fail-under=8.0&lt;/code&gt; 옵션으로 품질 점수가 8점 미만이면 CI가 실패합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-실무-적용-팁"&gt;
 💡 실무 적용 팁
 &lt;a class="heading-anchor" href="#-%ec%8b%a4%eb%ac%b4-%ec%a0%81%ec%9a%a9-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="점진적-도입-전략"&gt;
 점진적 도입 전략
 &lt;a class="heading-anchor" href="#%ec%a0%90%ec%a7%84%ec%a0%81-%eb%8f%84%ec%9e%85-%ec%a0%84%eb%9e%b5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;기존 프로젝트에 Pylint를 도입할 때는 처음부터 모든 규칙을 강제하면 수백 개의 오류가 나올 수 있습니다. 아래 순서로 단계적으로 접근하는 것을 권장합니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;E(Error) 먼저&lt;/strong&gt; — 런타임 오류로 이어지는 치명적 문제 우선 해결&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;W(Warning) 다음&lt;/strong&gt; — 잠재적 버그와 개선 권장 사항 처리&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C/R 마지막&lt;/strong&gt; — 코딩 규칙과 리팩토링은 여유를 두고 개선&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="자주-발생하는-오류-해결"&gt;
 자주 발생하는 오류 해결
 &lt;a class="heading-anchor" href="#%ec%9e%90%ec%a3%bc-%eb%b0%9c%ec%83%9d%ed%95%98%eb%8a%94-%ec%98%a4%eb%a5%98-%ed%95%b4%ea%b2%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;오류&lt;/th&gt;
					&lt;th&gt;원인&lt;/th&gt;
					&lt;th&gt;해결책&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;E0401 import-error&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;모듈을 찾을 수 없음&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;.pylintrc&lt;/code&gt;의 &lt;code&gt;init-hook&lt;/code&gt;으로 경로 추가&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;W1203 logging-fstring&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;로깅에 f-string 사용&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;logger.info(&amp;quot;값: %s&amp;quot;, value)&lt;/code&gt; 형태로 변경&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;R1705 no-else-return&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;return 후 else 블록&lt;/td&gt;
					&lt;td&gt;else 제거 후 들여쓰기 감소&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;C0301 line-too-long&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;줄 길이 초과&lt;/td&gt;
					&lt;td&gt;max-line-length 조정 또는 줄 바꿈&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="pyreverse로-uml-다이어그램-생성"&gt;
 Pyreverse로 UML 다이어그램 생성
 &lt;a class="heading-anchor" href="#pyreverse%eb%a1%9c-uml-%eb%8b%a4%ec%9d%b4%ec%96%b4%ea%b7%b8%eb%9e%a8-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Pylint 패키지에 포함된 &lt;code&gt;pyreverse&lt;/code&gt;로 클래스 구조를 시각화할 수 있습니다. Graphviz 설치 후 실행합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pip install pylint
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;brew install graphviz &lt;span class="c1"&gt;# macOS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;pyreverse -o png -p MyProject my_package/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;classes_MyProject.png&lt;/code&gt;와 &lt;code&gt;packages_MyProject.png&lt;/code&gt; 파일이 생성됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-pylint와-flake8-중-무엇을-써야-하나요"&gt;
 Q. Pylint와 Flake8 중 무엇을 써야 하나요?
 &lt;a class="heading-anchor" href="#q-pylint%ec%99%80-flake8-%ec%a4%91-%eb%ac%b4%ec%97%87%ec%9d%84-%ec%8d%a8%ec%95%bc-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;간단한 스타일 검사가 목적이라면 Flake8이 빠르고 설정이 쉽습니다. 잠재적 버그 탐지, 코드 복잡도 분석, 품질 점수까지 필요하다면 Pylint가 적합합니다. 실무에서는 두 도구를 함께 사용하거나, 최근에는 Ruff로 통합하는 경우가 많습니다.&lt;/p&gt;
&lt;h3 id="q-pylint-점수-10점을-목표로-해야-하나요"&gt;
 Q. Pylint 점수 10점을 목표로 해야 하나요?
 &lt;a class="heading-anchor" href="#q-pylint-%ec%a0%90%ec%88%98-10%ec%a0%90%ec%9d%84-%eb%aa%a9%ed%91%9c%eb%a1%9c-%ed%95%b4%ec%95%bc-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;아닙니다. 10점이 항상 좋은 코드를 의미하지는 않습니다. 팀의 기준(예: 8.0 이상)을 설정하고, 점수보다는 E·W 오류 0건을 목표로 삼는 것이 더 실용적입니다.&lt;/p&gt;
&lt;h3 id="q-외부-라이브러리numpy-pandas-사용-시-e0401-오류가-계속-나옵니다"&gt;
 Q. 외부 라이브러리(numpy, pandas) 사용 시 E0401 오류가 계속 나옵니다.
 &lt;a class="heading-anchor" href="#q-%ec%99%b8%eb%b6%80-%eb%9d%bc%ec%9d%b4%eb%b8%8c%eb%9f%ac%eb%a6%acnumpy-pandas-%ec%82%ac%ec%9a%a9-%ec%8b%9c-e0401-%ec%98%a4%eb%a5%98%ea%b0%80-%ea%b3%84%ec%86%8d-%eb%82%98%ec%98%b5%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;.pylintrc&lt;/code&gt;의 &lt;code&gt;[TYPECHECK]&lt;/code&gt; 섹션에 해당 라이브러리를 추가합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[TYPECHECK]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ignored-modules&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;numpy,pandas,torch,tensorflow&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="q-pre-commit-사용-시-가상환경-패키지를-인식하지-못합니다"&gt;
 Q. pre-commit 사용 시 가상환경 패키지를 인식하지 못합니다.
 &lt;a class="heading-anchor" href="#q-pre-commit-%ec%82%ac%ec%9a%a9-%ec%8b%9c-%ea%b0%80%ec%83%81%ed%99%98%ea%b2%bd-%ed%8c%a8%ed%82%a4%ec%a7%80%eb%a5%bc-%ec%9d%b8%ec%8b%9d%ed%95%98%ec%a7%80-%eb%aa%bb%ed%95%a9%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;.pre-commit-config.yaml&lt;/code&gt;의 &lt;code&gt;additional_dependencies&lt;/code&gt;에 프로젝트에서 사용하는 패키지를 명시해야 합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;additional_dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pydantic&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sqlalchemy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;fastapi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] 🛡️ OPA Gatekeeper vs Kyverno: 쿠버네티스 정책 관리 완전 가이드</title><link>https://kyungryeol-yoon.github.io/kubernetes/security/kubernetes-opa-gatekeeper-vs-kyverno/</link><pubDate>Fri, 26 Sep 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/security/kubernetes-opa-gatekeeper-vs-kyverno/</guid><description>&lt;p&gt;쿠버네티스 클러스터를 운영하다 보면 &amp;ldquo;모든 Pod에 리소스 제한을 설정해야 한다&amp;rdquo;, &amp;ldquo;승인된 레지스트리의 이미지만 사용해야 한다&amp;quot;처럼 조직 차원의 정책을 강제해야 하는 상황이 생깁니다.
이를 코드 리뷰에만 의존하면 누락이 발생하기 쉽습니다.
&lt;strong&gt;OPA Gatekeeper&lt;/strong&gt;와 &lt;strong&gt;Kyverno&lt;/strong&gt;는 이런 정책을 클러스터 레벨에서 자동으로 강제하는 대표적인 도구입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-kubernetes-정책-관리란"&gt;
 🔑 Kubernetes 정책 관리란?
 &lt;a class="heading-anchor" href="#-kubernetes-%ec%a0%95%ec%b1%85-%ea%b4%80%eb%a6%ac%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;쿠버네티스는 리소스 생성·수정·삭제 요청이 API 서버에 도달했을 때 이를 검사하는 &lt;strong&gt;Admission Controller&lt;/strong&gt; 플러그인을 제공합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;API Server
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;Authentication → Authorization → Admission Control → etcd 저장
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; ↑
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; Mutating / Validating Webhook
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt; (Gatekeeper / Kyverno 가 여기서 동작)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;두 도구 모두 Webhook 형태로 동작하며 요청을 가로채 정책 준수 여부를 검사합니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: 쿠버네티스 1.25에서 Pod Security Policy(PSP)가 제거된 이후 OPA Gatekeeper와 Kyverno가 PSP의 실질적인 대안으로 자리잡았습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-opa-gatekeeper"&gt;
 🔵 OPA Gatekeeper
 &lt;a class="heading-anchor" href="#-opa-gatekeeper" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="개념-및-아키텍처"&gt;
 개념 및 아키텍처
 &lt;a class="heading-anchor" href="#%ea%b0%9c%eb%85%90-%eb%b0%8f-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;OPA(Open Policy Agent)&lt;/strong&gt; 는 CNCF에서 관리하는 범용 정책 엔진입니다.
&lt;strong&gt;Gatekeeper&lt;/strong&gt;는 OPA를 쿠버네티스 Admission Webhook과 연결하는 브리지 역할을 합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;API Server
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; │ AdmissionReview 요청
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;Gatekeeper Webhook
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; │ Rego 정책 평가
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;OPA (정책 평가 엔진)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; │ allow / deny 반환
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;API Server (요청 허용 or 거부)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Gatekeeper v3.0부터는 &lt;strong&gt;OPA Constraint Framework&lt;/strong&gt;를 기반으로 CRD(Custom Resource Definition)를 통해 정책을 선언적으로 관리합니다.&lt;/p&gt;
&lt;h3 id="constrainttemplate--정책-템플릿-정의"&gt;
 ConstraintTemplate — 정책 템플릿 정의
 &lt;a class="heading-anchor" href="#constrainttemplate--%ec%a0%95%ec%b1%85-%ed%85%9c%ed%94%8c%eb%a6%bf-%ec%a0%95%ec%9d%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ConstraintTemplate&lt;/code&gt;은 정책의 로직(Rego)과 파라미터 스키마를 정의하는 청사진입니다.
한 번 정의하면 여러 클러스터, 여러 네임스페이스에 재사용할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;templates.gatekeeper.sh/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ConstraintTemplate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;k8srequiredlabels&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;crd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;names&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;K8sRequiredLabels&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;openAPIV3Schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;array&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;admission.k8s.gatekeeper.sh&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rego&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; package k8srequiredlabels
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; deny[{&amp;#34;msg&amp;#34;: msg, &amp;#34;details&amp;#34;: {&amp;#34;missing_labels&amp;#34;: missing}}] {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; provided := {label | input.review.object.metadata.labels[label]}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; required := {label | label := input.parameters.labels[_]}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; missing := required - provided
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; count(missing) &amp;gt; 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; msg := sprintf(&amp;#34;필수 레이블이 누락되었습니다: %v&amp;#34;, [missing])
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="constraint--정책-인스턴스-생성"&gt;
 Constraint — 정책 인스턴스 생성
 &lt;a class="heading-anchor" href="#constraint--%ec%a0%95%ec%b1%85-%ec%9d%b8%ec%8a%a4%ed%84%b4%ec%8a%a4-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ConstraintTemplate&lt;/code&gt;으로 만들어진 CRD를 인스턴스화하여 실제 정책을 적용합니다.
&lt;code&gt;match&lt;/code&gt; 필드로 적용 대상을 세밀하게 지정할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;constraints.gatekeeper.sh/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;K8sRequiredLabels&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ns-must-have-owner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kinds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kinds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Namespace&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;owner&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;env&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;위 정책 적용 후 &lt;code&gt;owner&lt;/code&gt;, &lt;code&gt;env&lt;/code&gt; 레이블 없이 네임스페이스를 생성하면 아래처럼 거부됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Error from server ([ns-must-have-owner] 필수 레이블이 누락되었습니다: {&amp;#34;env&amp;#34;, &amp;#34;owner&amp;#34;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="설치"&gt;
 설치
 &lt;a class="heading-anchor" href="#%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Helm으로 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;helm install gatekeeper/gatekeeper &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; --name-template&lt;span class="o"&gt;=&lt;/span&gt;gatekeeper &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; --namespace gatekeeper-system &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; --create-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 또는 manifest로 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;설치 후 &lt;code&gt;gatekeeper-system&lt;/code&gt; 네임스페이스에 컨트롤러 파드가 생성됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods -n gatekeeper-system
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# NAME READY STATUS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# gatekeeper-audit-xxxxxxxxx 1/1 Running&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# gatekeeper-controller-manager-xxxxxxxxx 1/1 Running&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="audit-기능"&gt;
 Audit 기능
 &lt;a class="heading-anchor" href="#audit-%ea%b8%b0%eb%8a%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Gatekeeper는 &lt;strong&gt;Audit&lt;/strong&gt; 기능을 통해 이미 배포된 리소스도 정책 위반 여부를 감사합니다.
정책 적용 시점 이전에 생성된 리소스까지 소급 검사할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 정책 위반 리소스 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl get k8srequiredlabels ns-must-have-owner -o yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# status.violations 필드에 위반 리소스 목록이 표시됩니다&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;또한 클러스터 내 리소스를 Gatekeeper에 복제하여 정책 간 데이터 참조가 가능합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;config.gatekeeper.sh/v1alpha1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gatekeeper-system&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;syncOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;v1&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Namespace&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-kyverno"&gt;
 🟢 Kyverno
 &lt;a class="heading-anchor" href="#-kyverno" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="개념-및-아키텍처-1"&gt;
 개념 및 아키텍처
 &lt;a class="heading-anchor" href="#%ea%b0%9c%eb%85%90-%eb%b0%8f-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Kyverno는 &lt;strong&gt;Kubernetes Native&lt;/strong&gt; 정책 엔진입니다.
정책을 Rego 같은 별도 언어 없이 순수 YAML(CR)로 표현할 수 있어 학습 곡선이 낮습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;API Server
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; │ AdmissionReview 요청
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;Kyverno Webhook
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; │ ClusterPolicy / Policy 평가
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; ├── Mutate → 리소스 자동 수정 후 허용
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; ├── Validate → 검증 실패 시 거부
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt; └── Generate → 새 리소스 자동 생성&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Kyverno는 4개의 컨트롤러로 구성됩니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;컨트롤러&lt;/th&gt;
					&lt;th&gt;역할&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Webhook&lt;/td&gt;
					&lt;td&gt;AdmissionReview 요청 처리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Monitor&lt;/td&gt;
					&lt;td&gt;필수 설정(웹훅 등) 유지 관리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PolicyController&lt;/td&gt;
					&lt;td&gt;정책 CR 변경 감시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GenerateController&lt;/td&gt;
					&lt;td&gt;Generate 정책으로 생성된 리소스 관리&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="설치-1"&gt;
 설치
 &lt;a class="heading-anchor" href="#%ec%84%a4%ec%b9%98-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Helm으로 설치 (권장)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;helm repo add kyverno https://kyverno.github.io/kyverno/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;helm install kyverno kyverno/kyverno &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; -n kyverno &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; --create-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 또는 manifest로 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl create -f https://raw.githubusercontent.com/kyverno/kyverno/main/config/install.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ Kyverno는 Kubernetes 1.14 이상이 필요합니다. 고가용성 환경에서는 &lt;code&gt;replicaCount=3&lt;/code&gt;으로 설정을 권장합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="정책-유형"&gt;
 정책 유형
 &lt;a class="heading-anchor" href="#%ec%a0%95%ec%b1%85-%ec%9c%a0%ed%98%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Kyverno 정책은 &lt;code&gt;ClusterPolicy&lt;/code&gt;(클러스터 전체) 또는 &lt;code&gt;Policy&lt;/code&gt;(네임스페이스 범위) 두 가지 스코프로 생성합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;유형&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
					&lt;th&gt;실행 시점&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Validate&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;리소스가 정책을 준수하는지 검증&lt;/td&gt;
					&lt;td&gt;생성·수정 시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Mutate&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;리소스를 자동으로 수정&lt;/td&gt;
					&lt;td&gt;생성·수정 시 (Validate 전)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Generate&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;새로운 리소스를 자동 생성&lt;/td&gt;
					&lt;td&gt;트리거 리소스 생성 시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Cleanup&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;불필요한 리소스를 자동 삭제&lt;/td&gt;
					&lt;td&gt;주기적 실행&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="validate-예제-필수-레이블-강제"&gt;
 Validate 예제: 필수 레이블 강제
 &lt;a class="heading-anchor" href="#validate-%ec%98%88%ec%a0%9c-%ed%95%84%ec%88%98-%eb%a0%88%ec%9d%b4%eb%b8%94-%ea%b0%95%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kyverno.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterPolicy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;require-app-label&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;validationFailureAction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Enforce &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Audit으로 변경하면 감사 모드&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;check-app-label&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;any&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kinds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;Pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;레이블 &amp;#39;app.kubernetes.io/name&amp;#39; 이 필요합니다.&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;?*&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;정책 위반 시 아래 메시지와 함께 거부됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Error from server: admission webhook &amp;#34;validate.kyverno.svc-fail&amp;#34; denied the request:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;resource Pod was blocked due to the following policies: require-app-label&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="mutate-예제-리소스-제한-자동-주입"&gt;
 Mutate 예제: 리소스 제한 자동 주입
 &lt;a class="heading-anchor" href="#mutate-%ec%98%88%ec%a0%9c-%eb%a6%ac%ec%86%8c%ec%8a%a4-%ec%a0%9c%ed%95%9c-%ec%9e%90%eb%8f%99-%ec%a3%bc%ec%9e%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;레이블이나 리소스 제한이 없는 Pod에 기본값을 자동으로 삽입합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kyverno.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterPolicy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;add-default-resources&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;add-resource-limits&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;any&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kinds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;Pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mutate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;patchStrategicMerge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;(name)&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;+(memory)&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;256Mi&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;+(cpu)&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;500m&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: &lt;code&gt;+()&lt;/code&gt; 표기는 해당 필드가 없을 때만 값을 추가합니다. 기존 설정을 덮어쓰지 않습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="generate-예제-네임스페이스-생성-시-networkpolicy-자동-생성"&gt;
 Generate 예제: 네임스페이스 생성 시 NetworkPolicy 자동 생성
 &lt;a class="heading-anchor" href="#generate-%ec%98%88%ec%a0%9c-%eb%84%a4%ec%9e%84%ec%8a%a4%ed%8e%98%ec%9d%b4%ec%8a%a4-%ec%83%9d%ec%84%b1-%ec%8b%9c-networkpolicy-%ec%9e%90%eb%8f%99-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;새 네임스페이스가 생성될 때 기본 NetworkPolicy를 자동으로 생성합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kyverno.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterPolicy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default-network-policy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default-deny-ingress&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;any&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kinds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;Namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;networking.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NetworkPolicy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default-deny-ingress&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{{request.object.metadata.name}}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;synchronize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;policyTypes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;Ingress&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-opa-gatekeeper-vs-kyverno-비교"&gt;
 ⚖️ OPA Gatekeeper vs Kyverno 비교
 &lt;a class="heading-anchor" href="#-opa-gatekeeper-vs-kyverno-%eb%b9%84%ea%b5%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;OPA Gatekeeper&lt;/th&gt;
					&lt;th&gt;Kyverno&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;정책 언어&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Rego (전용 DSL)&lt;/td&gt;
					&lt;td&gt;YAML (Kubernetes 네이티브)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;학습 곡선&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;높음 (Rego 학습 필요)&lt;/td&gt;
					&lt;td&gt;낮음&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;적용 범위&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;멀티 플랫폼 (쿠버네티스 외 지원)&lt;/td&gt;
					&lt;td&gt;쿠버네티스 전용&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;정책 유형&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Validate, Audit&lt;/td&gt;
					&lt;td&gt;Validate, Mutate, Generate, Cleanup&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Mutate 지원&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;제한적&lt;/td&gt;
					&lt;td&gt;강력한 기본 지원&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Generate 지원&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;✗&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Audit&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;✅ (내장)&lt;/td&gt;
					&lt;td&gt;✅ (내장)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;CLI 도구&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;OPA CLI&lt;/td&gt;
					&lt;td&gt;Kyverno CLI&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;CNCF 등급&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Graduated&lt;/td&gt;
					&lt;td&gt;Incubating&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;커뮤니티 성숙도&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;높음&lt;/td&gt;
					&lt;td&gt;빠르게 성장 중&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-어떤-것을-선택할까"&gt;
 🎯 어떤 것을 선택할까?
 &lt;a class="heading-anchor" href="#-%ec%96%b4%eb%96%a4-%ea%b2%83%ec%9d%84-%ec%84%a0%ed%83%9d%ed%95%a0%ea%b9%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;OPA Gatekeeper를 선택해야 할 때:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;쿠버네티스 외 다른 시스템(Terraform, API 서버 등)에도 동일한 정책 엔진을 사용하고 싶은 경우&lt;/li&gt;
&lt;li&gt;정책 로직이 복잡하여 Rego의 표현력이 필요한 경우&lt;/li&gt;
&lt;li&gt;이미 OPA 생태계를 사용 중인 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Kyverno를 선택해야 할 때:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;쿠버네티스 전용 정책 관리가 목적인 경우&lt;/li&gt;
&lt;li&gt;Rego 학습 없이 빠르게 도입하고 싶은 경우&lt;/li&gt;
&lt;li&gt;Mutate, Generate 등 다양한 정책 유형이 필요한 경우&lt;/li&gt;
&lt;li&gt;GitOps 환경에서 YAML 기반으로 정책을 관리하고 싶은 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: 두 도구를 함께 사용하는 것도 가능합니다. 예를 들어 복잡한 검증 정책은 OPA Gatekeeper로, 리소스 자동 변형·생성은 Kyverno로 역할을 분담할 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[AI] 🤝 CrewAI: 멀티 에이전트 AI 협업 프레임워크 완벽 가이드</title><link>https://kyungryeol-yoon.github.io/ai/llm/crewai-multi-agent-framework-guide/</link><pubDate>Thu, 21 Aug 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/ai/llm/crewai-multi-agent-framework-guide/</guid><description>&lt;p&gt;&lt;strong&gt;CrewAI&lt;/strong&gt;는 여러 AI Agent가 인간 팀처럼 역할을 나누고 협력하여 복잡한 작업을 처리하는 멀티 에이전트 오케스트레이션 프레임워크입니다.
단일 LLM 호출로는 해결하기 어려운 리서치·작성·분석·코딩 등 다단계 작업을 Agent 팀이 분업하여 처리합니다.
이 글에서는 핵심 구성요소, 프로세스 유형, 메모리 시스템, Python 코드 예제를 실무 기준으로 정리합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-crewai란"&gt;
 🤝 CrewAI란?
 &lt;a class="heading-anchor" href="#-crewai%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;CrewAI는 &lt;strong&gt;역할 기반 AI Agent 협업 플랫폼&lt;/strong&gt;입니다.
각 Agent는 특정 전문 역할(리서처, 작가, 분석가 등)을 부여받고, 독립적으로 작업을 수행하거나 다른 Agent에게 위임하면서 팀 목표를 달성합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;사용자 입력 (목표)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; Crew 오케스트레이터
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; ┌────┴────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;Agent A Agent B Agent C
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;(리서처) (작가) (검수자)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; └────┬────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt; 최종 결과물&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;단일 LLM&lt;/th&gt;
					&lt;th&gt;CrewAI 멀티 에이전트&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;작업 복잡도&lt;/td&gt;
					&lt;td&gt;단순 단발성&lt;/td&gt;
					&lt;td&gt;다단계·복합 작업&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;전문화&lt;/td&gt;
					&lt;td&gt;범용&lt;/td&gt;
					&lt;td&gt;역할별 전문화&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;컨텍스트&lt;/td&gt;
					&lt;td&gt;단일 대화&lt;/td&gt;
					&lt;td&gt;에이전트 간 공유·누적&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;확장성&lt;/td&gt;
					&lt;td&gt;제한적&lt;/td&gt;
					&lt;td&gt;Agent 추가로 수평 확장&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-핵심-구성요소"&gt;
 🧱 핵심 구성요소
 &lt;a class="heading-anchor" href="#-%ed%95%b5%ec%8b%ac-%ea%b5%ac%ec%84%b1%ec%9a%94%ec%86%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="agent--자율-작업-단위"&gt;
 Agent — 자율 작업 단위
 &lt;a class="heading-anchor" href="#agent--%ec%9e%90%ec%9c%a8-%ec%9e%91%ec%97%85-%eb%8b%a8%ec%9c%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Agent는 특정 역할과 목표를 가진 자율적 AI 소프트웨어입니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;파라미터&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;role&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Agent의 기능/직책 정의&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;goal&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;개별 목표로 의사결정 방향 제시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;backstory&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;배경 스토리로 역할 맥락 강화&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;tools&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;사용 가능한 도구 목록&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;llm&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;사용할 LLM (기본값: OpenAI GPT-4)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;verbose&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;True&lt;/code&gt; 설정 시 실행 로그 출력&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;allow_delegation&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;True&lt;/code&gt;면 다른 Agent에게 작업 위임 가능&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;memory&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;True&lt;/code&gt;면 메모리 시스템 활성화&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;max_iter&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;최대 반복 횟수 (기본값: 15)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="task--구체적-작업-단위"&gt;
 Task — 구체적 작업 단위
 &lt;a class="heading-anchor" href="#task--%ea%b5%ac%ec%b2%b4%ec%a0%81-%ec%9e%91%ec%97%85-%eb%8b%a8%ec%9c%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Agent가 수행할 명확한 과제를 정의합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;파라미터&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;description&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;작업 내용과 수행 방법&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;agent&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;담당 Agent 지정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;expected_output&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;기대 결과물 형식 설명&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;tools&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;해당 Task에만 사용되는 도구&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;context&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;이전 Task 출력을 컨텍스트로 전달&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;output_file&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;결과를 파일로 저장&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="tool--agent의-외부-능력"&gt;
 Tool — Agent의 외부 능력
 &lt;a class="heading-anchor" href="#tool--agent%ec%9d%98-%ec%99%b8%eb%b6%80-%eb%8a%a5%eb%a0%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Agent가 실제 데이터를 수집하거나 외부 서비스와 상호작용하는 함수입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;crewai_tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SerperDevTool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ScrapeWebsiteTool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WebsiteSearchTool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;search_tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SerperDevTool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# Google 검색&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;scrape_tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ScrapeWebsiteTool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 웹 페이지 스크래핑&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;rag_tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebsiteSearchTool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 웹 콘텐츠 RAG 검색&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="process--작업-흐름-조율-방식"&gt;
 Process — 작업 흐름 조율 방식
 &lt;a class="heading-anchor" href="#process--%ec%9e%91%ec%97%85-%ed%9d%90%eb%a6%84-%ec%a1%b0%ec%9c%a8-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;프로세스&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Process.sequential&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;작업을 순서대로 실행, 앞 결과가 다음 컨텍스트가 됨&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Process.hierarchical&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;매니저 Agent가 작업을 하위 Agent에게 위임·검수&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="crew--최상위-오케스트레이터"&gt;
 Crew — 최상위 오케스트레이터
 &lt;a class="heading-anchor" href="#crew--%ec%b5%9c%ec%83%81%ec%9c%84-%ec%98%a4%ec%bc%80%ec%8a%a4%ed%8a%b8%eb%a0%88%ec%9d%b4%ed%84%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Agent와 Task를 모아서 실행 계획을 관리하는 최상위 구조입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-설치"&gt;
 📦 설치
 &lt;a class="heading-anchor" href="#-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pip install crewai
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;pip install &lt;span class="s1"&gt;&amp;#39;crewai[tools]&amp;#39;&lt;/span&gt; &lt;span class="c1"&gt;# 기본 도구 모음 포함&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;환경 변수 설정 (&lt;code&gt;.env&lt;/code&gt; 파일):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sk-...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;SERPER_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;... &lt;span class="c1"&gt;# SerperDevTool 사용 시 필요&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-빠른-시작-블로그-글-자동-작성-에이전트"&gt;
 🚀 빠른 시작: 블로그 글 자동 작성 에이전트
 &lt;a class="heading-anchor" href="#-%eb%b9%a0%eb%a5%b8-%ec%8b%9c%ec%9e%91-%eb%b8%94%eb%a1%9c%ea%b7%b8-%ea%b8%80-%ec%9e%90%eb%8f%99-%ec%9e%91%ec%84%b1-%ec%97%90%ec%9d%b4%ec%a0%84%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;리서처 Agent가 주제를 조사하고, 에디터 Agent가 블로그 글을 작성하는 2인 팀 예제입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;crewai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Crew&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Process&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;crewai_tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SerperDevTool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ScrapeWebsiteTool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;OPENAI_MODEL_NAME&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;gpt-4o&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ── Tools ────────────────────────────────────────&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;search_tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SerperDevTool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;scrape_tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ScrapeWebsiteTool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ── Agents ───────────────────────────────────────&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;researcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;시니어 리서처&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;goal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;주어진 주제에 대해 웹에서 최신 정보를 수집하고 핵심 인사이트를 정리한다&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;backstory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;다양한 기술 문서와 블로그를 분석하여 최고의 리서치 결과를 만드는 전문가&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;search_tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scrape_tool&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;allow_delegation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;editor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;IT 블로거 / 에디터&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;goal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;리서치 결과를 바탕으로 읽기 쉽고 실용적인 블로그 글을 작성한다&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;backstory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;개발자 독자를 위해 명확하고 유익한 기술 콘텐츠를 작성하는 전문 블로거&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ── Tasks ────────────────────────────────────────&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;research_task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{topic}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;에 관한 최신 정보를 웹에서 검색하고 분석하세요.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 핵심 개념, 주요 기능, 실제 활용 사례를 정리하세요.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;researcher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;expected_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;주제의 핵심 내용, 주요 기능, 활용 사례를 포함한 리서치 보고서&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;writing_task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;리서치 결과를 바탕으로 &amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{topic}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;에 대한 블로그 포스트를 작성하세요.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 도입부, 주요 3개 섹션, 실용적 예시, 결론으로 구성하세요.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;expected_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;마크다운 형식의 블로그 포스트 (도입부, 3개 섹션, 결론 포함)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;research_task&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# 리서치 결과를 컨텍스트로 전달&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;output_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;output_blog.md&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ── Crew ─────────────────────────────────────────&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;crew&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Crew&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;researcher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;research_task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;writing_task&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sequential&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;crew&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kickoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;topic&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;CrewAI 멀티 에이전트 프레임워크&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-프로세스-유형"&gt;
 ⚙️ 프로세스 유형
 &lt;a class="heading-anchor" href="#-%ed%94%84%eb%a1%9c%ec%84%b8%ec%8a%a4-%ec%9c%a0%ed%98%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="sequential-순차-처리"&gt;
 Sequential (순차 처리)
 &lt;a class="heading-anchor" href="#sequential-%ec%88%9c%ec%b0%a8-%ec%b2%98%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;작업 목록 순서대로 실행하며, 앞 Task의 출력이 다음 Task의 컨텍스트가 됩니다.
가장 단순하고 예측 가능한 흐름입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;crew&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Crew&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;researcher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reviewer&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;research_task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;writing_task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;review_task&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sequential&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;research_task → writing_task → review_task
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; (출력) → (컨텍스트) → (컨텍스트)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="hierarchical-계층-처리"&gt;
 Hierarchical (계층 처리)
 &lt;a class="heading-anchor" href="#hierarchical-%ea%b3%84%ec%b8%b5-%ec%b2%98%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;매니저 Agent가 자동 생성되어 작업을 하위 Agent에게 위임하고 결과를 검수합니다.
복잡하고 동적인 워크플로에 적합합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;crew&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Crew&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;researcher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reviewer&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;complex_task&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hierarchical&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;manager_llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;# 매니저 LLM 지정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Manager Agent (자동 생성)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; ├── researcher 에게 조사 위임
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; ├── editor 에게 작성 위임
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; └── 결과 검수 후 최종 승인&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-메모리-시스템"&gt;
 🧠 메모리 시스템
 &lt;a class="heading-anchor" href="#-%eb%a9%94%eb%aa%a8%eb%a6%ac-%ec%8b%9c%ec%8a%a4%ed%85%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;CrewAI v1.10+ 에서는 통합 메모리 시스템을 제공합니다.
Agent가 이전 실행 맥락을 기억하고 중복 작업을 줄일 수 있습니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;메모리 유형&lt;/th&gt;
					&lt;th&gt;범위&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Short-term&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;현재 Crew 실행 내&lt;/td&gt;
					&lt;td&gt;대화 중 컨텍스트 유지&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Long-term&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;실행 간 영속&lt;/td&gt;
					&lt;td&gt;벡터 스토어에 저장, 재실행 시 활용&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Entity&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;현재 실행 내&lt;/td&gt;
					&lt;td&gt;언급된 인물·조직·개념 추적&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;researcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;리서처&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;goal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;정보 수집&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;backstory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 메모리 활성화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;crew&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Crew&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;researcher&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Crew 레벨 메모리 활성화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-커스텀-tool-구현"&gt;
 🔧 커스텀 Tool 구현
 &lt;a class="heading-anchor" href="#-%ec%bb%a4%ec%8a%a4%ed%85%80-tool-%ea%b5%ac%ed%98%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;@tool&lt;/code&gt; 데코레이터로 Python 함수를 Agent가 사용할 수 있는 도구로 등록합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;crewai.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;naver_news_search&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_naver_news&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;네이버 뉴스 API에서 최신 기사 URL을 검색합니다.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 실제 API 호출 구현&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;https://openapi.naver.com/v1/search/news.json&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;display&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;X-Naver-Client-Id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;NAVER_CLIENT_ID&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;X-Naver-Client-Secret&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;NAVER_CLIENT_SECRET&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;items&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;link&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: docstring이 Tool의 설명으로 사용됩니다. Agent가 언제 이 Tool을 써야 하는지 명확히 작성하면 호출 정확도가 높아집니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-yaml-설정-방식-대규모-프로젝트-권장"&gt;
 📋 YAML 설정 방식 (대규모 프로젝트 권장)
 &lt;a class="heading-anchor" href="#-yaml-%ec%84%a4%ec%a0%95-%eb%b0%a9%ec%8b%9d-%eb%8c%80%ea%b7%9c%eb%aa%a8-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ea%b6%8c%ec%9e%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Agent와 Task 정의를 YAML 파일로 분리하면 코드와 설정을 분리하여 관리하기 쉽습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;config/agents.yaml&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;researcher&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;시니어 리서처&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;goal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;주어진 주제의 최신 정보를 수집하고 핵심 인사이트를 정리한다&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;backstory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;다양한 기술 문서를 분석하여 최고의 리서치 결과를 만드는 전문가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;IT 블로거 에디터&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;goal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;리서치 결과를 읽기 쉬운 블로그 글로 작성한다&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;backstory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;개발자 독자를 위해 명확한 기술 콘텐츠를 작성하는 전문 블로거&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;config/tasks.yaml&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;research_task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{topic}&amp;#34;&lt;/span&gt;&lt;span class="l"&gt;에 관한 최신 정보를 수집하고 핵심 내용을 정리하세요.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;expected_output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;핵심 개념, 주요 기능, 활용 사례를 포함한 리서치 보고서&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;researcher&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;writing_task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;리서치 결과를 바탕으로 &amp;#34;{topic}&amp;#34; 블로그 포스트를 작성하세요.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;expected_output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;마크다운 블로그 포스트&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;editor&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;research_task&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;crew.py&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;crewai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Crew&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Process&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;crewai.project&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CrewBase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;crew&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@CrewBase&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogCrew&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agents_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;config/agents.yaml&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tasks_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;config/tasks.yaml&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nd"&gt;@agent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;researcher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;researcher&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;search_tool&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nd"&gt;@agent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;editor&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nd"&gt;@task&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;research_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tasks_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;research_task&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nd"&gt;@task&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;writing_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tasks_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;writing_task&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nd"&gt;@crew&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;crew&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Crew&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Crew&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sequential&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-실전-예제-뉴스-리서치-멀티-에이전트"&gt;
 🏗️ 실전 예제: 뉴스 리서치 멀티 에이전트
 &lt;a class="heading-anchor" href="#-%ec%8b%a4%ec%a0%84-%ec%98%88%ec%a0%9c-%eb%89%b4%ec%8a%a4-%eb%a6%ac%ec%84%9c%ec%b9%98-%eb%a9%80%ed%8b%b0-%ec%97%90%ec%9d%b4%ec%a0%84%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;검색 → 내용 추출 → 요약 응답을 3개 Agent가 분담하는 파이프라인입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;crewai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Crew&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Process&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;crewai.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;fetch_article&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_article&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;주어진 URL의 기사 본문을 추출합니다.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;newspaper&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Article&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Agents&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;searcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;뉴스 검색 전문가&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;goal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;사용자 질문에 맞는 최신 뉴스 URL을 수집한다&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;backstory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;다양한 뉴스 소스에서 정확한 기사를 찾는 리서치 전문가&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;search_tool&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;analyzer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;콘텐츠 분석가&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;goal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;기사 URL에서 본문을 추출하고 핵심 내용을 분석한다&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;backstory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;복잡한 기사를 빠르게 파악하고 핵심을 추출하는 분석가&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fetch_article&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;answerman&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;최종 응답 작성자&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;goal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;분석된 정보를 바탕으로 사용자에게 명확한 답변을 제공한다&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;backstory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;복잡한 정보를 쉽고 정확하게 전달하는 커뮤니케이션 전문가&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Tasks&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;search_task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{query}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;에 관한 최신 뉴스 기사 URL 5개를 수집하세요.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;searcher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;expected_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;관련 뉴스 기사 URL 목록 (최소 5개)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;analysis_task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;수집된 URL에서 기사 본문을 추출하고 핵심 내용을 정리하세요.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;analyzer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;expected_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;각 기사의 핵심 내용 요약&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;search_task&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;answer_task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;분석 결과를 바탕으로 &amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{query}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;에 대한 종합 답변을 작성하세요.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;answerman&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;expected_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;출처와 근거를 포함한 명확한 답변&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;analysis_task&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Crew 실행&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;crew&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Crew&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;57&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;searcher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;analyzer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;answerman&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;58&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;search_task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;analysis_task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;answer_task&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;59&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sequential&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;61&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;crew&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kickoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2026년 AI Agent 트렌드&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-crewai와-langchain의-차이는"&gt;
 Q. CrewAI와 LangChain의 차이는?
 &lt;a class="heading-anchor" href="#q-crewai%ec%99%80-langchain%ec%9d%98-%ec%b0%a8%ec%9d%b4%eb%8a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;LangChain은 LLM 체이닝과 도구 통합을 위한 범용 라이브러리입니다.
CrewAI는 멀티 에이전트 협업 오케스트레이션에 특화되어 있으며, LangChain 위에서 동작할 수 있습니다.&lt;/p&gt;
&lt;h3 id="q-openai-외에-다른-llm을-사용할-수-있나요"&gt;
 Q. OpenAI 외에 다른 LLM을 사용할 수 있나요?
 &lt;a class="heading-anchor" href="#q-openai-%ec%99%b8%ec%97%90-%eb%8b%a4%eb%a5%b8-llm%ec%9d%84-%ec%82%ac%ec%9a%a9%ed%95%a0-%ec%88%98-%ec%9e%88%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;네, &lt;code&gt;llm&lt;/code&gt; 파라미터로 Anthropic Claude, Google Gemini, Ollama(로컬 LLM) 등을 지정할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_anthropic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatAnthropic&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;분석가&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;goal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;backstory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatAnthropic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;claude-sonnet-4-6&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="q-sequential과-hierarchical-중-어떤-걸-써야-하나요"&gt;
 Q. Sequential과 Hierarchical 중 어떤 걸 써야 하나요?
 &lt;a class="heading-anchor" href="#q-sequential%ea%b3%bc-hierarchical-%ec%a4%91-%ec%96%b4%eb%96%a4-%ea%b1%b8-%ec%8d%a8%ec%95%bc-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;단계별 흐름이 명확하고 예측 가능하면 &lt;strong&gt;Sequential&lt;/strong&gt;, 작업의 복잡도가 높고 동적 위임이 필요하면 &lt;strong&gt;Hierarchical&lt;/strong&gt;을 선택하세요.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📚 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.crewai.com/"&gt;CrewAI 공식 문서&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/crewaiinc/crewai"&gt;CrewAI GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Containerd 기반 쿠버네티스 고가용성(HA) 클러스터 완벽 구축 가이드</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubernetes-ha-cluster-containerd/</link><pubDate>Wed, 06 Aug 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubernetes-ha-cluster-containerd/</guid><description>&lt;h2 id="1--클러스터-아키텍처-및-환경"&gt;
 1. 🏗️ 클러스터 아키텍처 및 환경
 &lt;a class="heading-anchor" href="#1--%ed%81%b4%eb%9f%ac%ec%8a%a4%ed%84%b0-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98-%eb%b0%8f-%ed%99%98%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;고가용성 클러스터는 마스터 노드(Control Plane)를 여러 대 두어, 특정 노드에 장애가 발생해도 서비스가 중단되지 않도록 설계합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Container Runtime&lt;/strong&gt;: Containerd (Docker 대체 표준)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Load Balancer&lt;/strong&gt;: HAProxy + Keepalived (Virtual IP 사용)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nodes&lt;/strong&gt;: Master 3대, Worker N대 권장&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="2--사전-준비-모든-노드-공통"&gt;
 2. ⚙️ 사전 준비 (모든 노드 공통)
 &lt;a class="heading-anchor" href="#2--%ec%82%ac%ec%a0%84-%ec%a4%80%eb%b9%84-%eb%aa%a8%eb%93%a0-%eb%85%b8%eb%93%9c-%ea%b3%b5%ed%86%b5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;가장 먼저 모든 노드에서 쿠버네티스가 구동될 수 있는 기초 공사를 진행합니다.&lt;/p&gt;
&lt;h3 id="21-swap-비활성화-및-네트워크-설정"&gt;
 2.1 Swap 비활성화 및 네트워크 설정
 &lt;a class="heading-anchor" href="#21-swap-%eb%b9%84%ed%99%9c%ec%84%b1%ed%99%94-%eb%b0%8f-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;쿠버네티스는 메모리 관리를 위해 &lt;strong&gt;Swap 비활성화&lt;/strong&gt;가 필수입니다. 🛑&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. Swap 끄기&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;sudo swapoff -a
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;sudo sed -i &lt;span class="s1"&gt;&amp;#39;/swap/s/^/#/&amp;#39;&lt;/span&gt; /etc/fstab
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 커널 모듈 로드 (Containerd 필수 모듈)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF | sudo tee /etc/modules-load.d/k8s.conf
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;overlay
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;br_netfilter
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;sudo modprobe overlay
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;sudo modprobe br_netfilter
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. sysctl 파라미터 설정 (IP 포워딩 활성화)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF | sudo tee /etc/sysctl.d/k8s.conf
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;net.bridge.bridge-nf-call-iptables = 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;net.bridge.bridge-nf-call-ip6tables = 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;net.ipv4.ip_forward = 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;sudo sysctl --system&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="3--containerd-설치-및-최적화"&gt;
 3. 📦 Containerd 설치 및 최적화
 &lt;a class="heading-anchor" href="#3--containerd-%ec%84%a4%ec%b9%98-%eb%b0%8f-%ec%b5%9c%ec%a0%81%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;도커 없이 가볍고 빠른 &lt;strong&gt;Containerd&lt;/strong&gt;를 직접 설치합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt-get install -y containerd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 기본 설정 생성 및 SystemdCgroup 활성화 (중요!)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;sudo mkdir -p /etc/containerd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;containerd config default &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/containerd/config.toml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;sudo sed -i &lt;span class="s1"&gt;&amp;#39;s/SystemdCgroup \= false/SystemdCgroup \= true/g&amp;#39;&lt;/span&gt; /etc/containerd/config.toml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl restart containerd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="4--load-balancer-구성-lb-노드"&gt;
 4. ⚖️ Load Balancer 구성 (LB 노드)
 &lt;a class="heading-anchor" href="#4--load-balancer-%ea%b5%ac%ec%84%b1-lb-%eb%85%b8%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;마스터 노드들을 하나로 묶어줄 대표 주소인 **VIP(Virtual IP)**를 설정합니다. (예: &lt;code&gt;192.168.0.100&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HAProxy 설정 예시 (&lt;code&gt;/etc/haproxy/haproxy.cfg&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-haproxy" data-lang="haproxy"&gt;frontend k8s-api
 bind *:6443
 mode tcp
 default_backend k8s-api-nodes

backend k8s-api-nodes
 mode tcp
 balance roundrobin
 server master1 192.168.0.11:6443 check
 server master2 192.168.0.12:6443 check
 server master3 192.168.0.13:6443 check&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="5--클러스터-초기화-master-1"&gt;
 5. 🚩 클러스터 초기화 (Master 1)
 &lt;a class="heading-anchor" href="#5--%ed%81%b4%eb%9f%ac%ec%8a%a4%ed%84%b0-%ec%b4%88%ea%b8%b0%ed%99%94-master-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="-필독-vip-설정을-빠뜨리면-안-되는-이유"&gt;
 ⚠️ [필독] VIP 설정을 빠뜨리면 안 되는 이유!
 &lt;a class="heading-anchor" href="#-%ed%95%84%eb%8f%85-vip-%ec%84%a4%ec%a0%95%ec%9d%84-%eb%b9%a0%eb%9c%a8%eb%a6%ac%eb%a9%b4-%ec%95%88-%eb%90%98%eb%8a%94-%ec%9d%b4%ec%9c%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;kubeadm init&lt;/code&gt; 실행 시 &lt;code&gt;--control-plane-endpoint&lt;/code&gt; 옵션을 &lt;strong&gt;빠뜨리는(빼는)&lt;/strong&gt; 실수를 가장 많이 합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;만약 빠뜨린다면?&lt;/strong&gt; 😱 클러스터가 로드밸런서가 아닌 **&amp;lsquo;첫 번째 마스터의 IP&amp;rsquo;**를 대표 주소로 기억합니다. 나중에 마스터를 추가해도, 첫 번째 노드가 죽으면 클러스터 전체가 먹통이 되어 HA 구성의 의미가 사라집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 로드밸런서 VIP를 엔드포인트로 지정하여 시작!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm init &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; --control-plane-endpoint &lt;span class="s2"&gt;&amp;#34;192.168.0.100:6443&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; --upload-certs &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; --pod-network-cidr&lt;span class="o"&gt;=&lt;/span&gt;10.244.0.0/16 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; --cri-socket unix:///run/containerd/containerd.sock&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="6--노드-조인-join"&gt;
 6. 🤝 노드 조인 (Join)
 &lt;a class="heading-anchor" href="#6--%eb%85%b8%eb%93%9c-%ec%a1%b0%ec%9d%b8-join" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;초기화 완료 후 출력되는 토큰을 사용하여 나머지 노드들을 연결합니다.&lt;/p&gt;
&lt;h3 id="61-추가-마스터-노드-master-2-3-조인"&gt;
 6.1 추가 마스터 노드 (Master 2, 3) 조인
 &lt;a class="heading-anchor" href="#61-%ec%b6%94%ea%b0%80-%eb%a7%88%ec%8a%a4%ed%84%b0-%eb%85%b8%eb%93%9c-master-2-3-%ec%a1%b0%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm join 192.168.0.100:6443 --token &amp;lt;TOKEN&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; --discovery-token-ca-cert-hash sha256:&amp;lt;HASH&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; --control-plane --certificate-key &amp;lt;KEY&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="62-워커-노드-worker-조인"&gt;
 6.2 워커 노드 (Worker) 조인
 &lt;a class="heading-anchor" href="#62-%ec%9b%8c%ec%bb%a4-%eb%85%b8%eb%93%9c-worker-%ec%a1%b0%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm join 192.168.0.100:6443 --token &amp;lt;TOKEN&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; --discovery-token-ca-cert-hash sha256:&amp;lt;HASH&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="7--설치-확인-및-마무리"&gt;
 7. ✅ 설치 확인 및 마무리
 &lt;a class="heading-anchor" href="#7--%ec%84%a4%ec%b9%98-%ed%99%95%ec%9d%b8-%eb%b0%8f-%eb%a7%88%eb%ac%b4%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;모든 노드가 정상적으로 연결되었는지 확인해 볼까요?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get nodes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;STATUS&lt;/strong&gt;가 모두 &lt;code&gt;Ready&lt;/code&gt;라면 축하드립니다! 🎉 이제 어떤 마스터 노드 하나가 장애가 나더라도 끄떡없는 견고한 쿠버네티스 클러스터가 완성되었습니다.&lt;/p&gt;
&lt;h3 id="-요약하자면"&gt;
 💡 요약하자면:
 &lt;a class="heading-anchor" href="#-%ec%9a%94%ec%95%bd%ed%95%98%ec%9e%90%eb%a9%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Swap 오프&lt;/strong&gt;는 기본!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Containerd&lt;/strong&gt; 설정 시 &lt;code&gt;SystemdCgroup&lt;/code&gt;을 꼭 &lt;code&gt;true&lt;/code&gt;로!&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kubeadm init&lt;/code&gt; 시 &lt;strong&gt;LB VIP&lt;/strong&gt;를 절대 &lt;strong&gt;빠뜨리지 말 것!&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>[Kubernetes] eBPF + Cilium로 클러스터 심층 모니터링</title><link>https://kyungryeol-yoon.github.io/observability/ebpf/kubernetes-ebpf-cilium/</link><pubDate>Wed, 02 Jul 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/observability/ebpf/kubernetes-ebpf-cilium/</guid><description>&lt;h2 id="-ebpf--cilium-개발자-관점에서-보는-심층-모니터링"&gt;
 🔍 eBPF + Cilium: 개발자 관점에서 보는 심층 모니터링
 &lt;a class="heading-anchor" href="#-ebpf--cilium-%ea%b0%9c%eb%b0%9c%ec%9e%90-%ea%b4%80%ec%a0%90%ec%97%90%ec%84%9c-%eb%b3%b4%eb%8a%94-%ec%8b%ac%ec%b8%b5-%eb%aa%a8%eb%8b%88%ed%84%b0%eb%a7%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;쿠버네티스에서 &lt;strong&gt;애플리케이션 + 클러스터 호스트 수준&lt;/strong&gt; Observability를 확보하려면&lt;br&gt;
OTel과 eBPF를 활용하는 것이 효과적입니다.&lt;br&gt;
특히 eBPF 기반 네트워크 모니터링 도구인 &lt;strong&gt;Cilium&lt;/strong&gt;을 활용하면 실전 환경에서 강력한 가시성을 제공합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-ebpf란"&gt;
 1️⃣ eBPF란?
 &lt;a class="heading-anchor" href="#1-ebpf%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;eBPF = extended Berkeley Packet Filter&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;리눅스 커널 내부에서 안전하게 코드 실행 가능&lt;/li&gt;
&lt;li&gt;주요 활용:
&lt;ul&gt;
&lt;li&gt;커널 이벤트 트레이싱&lt;/li&gt;
&lt;li&gt;네트워크 패킷 분석&lt;/li&gt;
&lt;li&gt;성능 분석&lt;/li&gt;
&lt;li&gt;보안 이벤트 감지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;요약: &lt;strong&gt;커널 레벨에서 실시간 데이터를 수집하고 분석하는 기술&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="2-cilium이란"&gt;
 2️⃣ Cilium이란?
 &lt;a class="heading-anchor" href="#2-cilium%ec%9d%b4%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cilium&lt;/strong&gt;은 eBPF 기반 &lt;strong&gt;Kubernetes 네트워크 및 보안&lt;/strong&gt; 솔루션&lt;/li&gt;
&lt;li&gt;기능:
&lt;ul&gt;
&lt;li&gt;Pod-to-Pod, Pod-to-Service 트래픽 관찰&lt;/li&gt;
&lt;li&gt;네트워크 정책(enforcement) 적용&lt;/li&gt;
&lt;li&gt;L7 로깅, 트레이싱&lt;/li&gt;
&lt;li&gt;eBPF를 활용한 고성능 패킷 필터링과 모니터링&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;개발자 관점 핵심:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;네트워크 수준 Observability&lt;/strong&gt;와 &lt;strong&gt;보안&lt;/strong&gt;을 동시에 제공&lt;/li&gt;
&lt;li&gt;OTel과 함께 사용하면 &lt;strong&gt;애플리케이션 + 네트워크 + 커널 이벤트 통합&lt;/strong&gt; 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="3-otel과-ebpf-cilium-통합-아키텍처"&gt;
 3️⃣ OTel과 eBPF (Cilium) 통합 아키텍처
 &lt;a class="heading-anchor" href="#3-otel%ea%b3%bc-ebpf-cilium-%ed%86%b5%ed%95%a9-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Application / Container → OTel SDK → OTel Collector → Backend (Loki/Prometheus/Tempo)
Host Kernel → eBPF Agent (Cilium) → OTel Collector → Backend&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;OTel Collector가 애플리케이션 로그/트레이스와 eBPF 이벤트 모두 수집&lt;/li&gt;
&lt;li&gt;Loki, Prometheus, Tempo 등 백엔드로 통합 전송&lt;/li&gt;
&lt;li&gt;시각화/알람/분석을 한 곳에서 관리 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="4-개발자-관점-통합-전략"&gt;
 4️⃣ 개발자 관점 통합 전략
 &lt;a class="heading-anchor" href="#4-%ea%b0%9c%eb%b0%9c%ec%9e%90-%ea%b4%80%ec%a0%90-%ed%86%b5%ed%95%a9-%ec%a0%84%eb%9e%b5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Cilium 설치&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;DaemonSet 형태로 클러스터 전체 배포&lt;/li&gt;
&lt;li&gt;eBPF로 Pod-to-Pod 트래픽 관찰, L7 로깅 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OTel Collector 연계&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Collector OTLP Receiver로 Cilium에서 수집한 이벤트 전송&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;백엔드 설정&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Loki → 로그/이벤트 시각화&lt;/li&gt;
&lt;li&gt;Prometheus → 메트릭 수집&lt;/li&gt;
&lt;li&gt;Tempo/Jaeger → 트레이스 시각화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;운영 체크&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Liveness/Readiness Probe&lt;/li&gt;
&lt;li&gt;eBPF 오버헤드 모니터링&lt;/li&gt;
&lt;li&gt;Cilium Hubble UI/CLI 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="5-실전-예시-daemonset--collector-연계"&gt;
 5️⃣ 실전 예시 (DaemonSet + Collector 연계)
 &lt;a class="heading-anchor" href="#5-%ec%8b%a4%ec%a0%84-%ec%98%88%ec%8b%9c-daemonset--collector-%ec%97%b0%ea%b3%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;DaemonSet&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cilium&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kube-system&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;k8s-app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cilium&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;k8s-app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cilium&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serviceAccountName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cilium&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cilium&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cilium/cilium:v1.16&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;privileged&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;OTEL_COLLECTOR_ENDPOINT&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;http://otel-collector.observability.svc.cluster.local:4317&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Cilium(eBPF Agent) → OTLP로 Collector 전송&lt;/li&gt;
&lt;li&gt;Collector에서 앱 로그와 함께 백엔드 전송&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="6-개발자-관점-팁"&gt;
 6️⃣ 개발자 관점 팁
 &lt;a class="heading-anchor" href="#6-%ea%b0%9c%eb%b0%9c%ec%9e%90-%ea%b4%80%ec%a0%90-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;데이터 수집 레이어 명확화&lt;/strong&gt;: 앱 로그 vs 네트워크/커널 이벤트&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;오버헤드 주의&lt;/strong&gt;: eBPF 스크립트 과도하게 사용 시 CPU 증가&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;보안&lt;/strong&gt;: eBPF Agent(Cilium)는 Host 권한 필요 → RBAC 최소화&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;통합 시각화&lt;/strong&gt;: Loki/Prometheus/Tempo에서 모든 이벤트 연계 확인&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hubble 활용&lt;/strong&gt;: Cilium의 시각화/CLI 도구로 네트워크 트래픽 추적&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="7-요약"&gt;
 7️⃣ 요약
 &lt;a class="heading-anchor" href="#7-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;내용&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;목적&lt;/td&gt;
					&lt;td&gt;앱 + 네트워크 + 호스트 통합 Observability&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;핵심 기술&lt;/td&gt;
					&lt;td&gt;OTel Collector, eBPF Agent (Cilium)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;배포&lt;/td&gt;
					&lt;td&gt;OTel Collector (Deployment/DaemonSet), Cilium (DaemonSet)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;장점&lt;/td&gt;
					&lt;td&gt;전체 클러스터 가시성, 실시간 모니터링, 트레이스/로그/메트릭 통합, 네트워크 보안 관측&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;운영 포인트&lt;/td&gt;
					&lt;td&gt;Liveness/Readiness, eBPF 오버헤드 관리, RBAC 최소화, 백엔드 연결 확인, Hubble 활용&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;💡 &lt;strong&gt;한 줄 기억:&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;OTel + Cilium = “앱·네트워크·커널 통합 Observability + 보안까지 확보하는 실전 도구”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] Kubestr: 스토리지 성능과 상태 점검 도구</title><link>https://kyungryeol-yoon.github.io/kubernetes/storage/kubernetes-kubestr/</link><pubDate>Thu, 05 Jun 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/storage/kubernetes-kubestr/</guid><description>&lt;h2 id="-kubestr란"&gt;
 📦 Kubestr란?
 &lt;a class="heading-anchor" href="#-kubestr%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Kubestr&lt;/strong&gt;는 쿠버네티스 클러스터에서 &lt;strong&gt;스토리지(Storage) 리소스의 성능과 상태를 점검&lt;/strong&gt;하는 도구입니다.&lt;br&gt;
Persistent Volume, StorageClass, PVC 등을 대상으로 &lt;strong&gt;벤치마크와 분석&lt;/strong&gt;을 수행할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-주요-기능"&gt;
 1️⃣ 주요 기능
 &lt;a class="heading-anchor" href="#1-%ec%a3%bc%ec%9a%94-%ea%b8%b0%eb%8a%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;스토리지 클래스 분석&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;StorageClass, PVC, PV 구조 및 매칭 상태 확인&lt;/li&gt;
&lt;li&gt;권장 구성 준수 여부 점검&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;성능 벤치마크&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IOPS, Throughput, Latency 측정&lt;/li&gt;
&lt;li&gt;다양한 볼륨 타입(NFS, CSI, Local PV 등) 비교&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;보고서 제공&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CLI, YAML, JSON 형식 제공&lt;/li&gt;
&lt;li&gt;성능 병목이나 문제점을 쉽게 확인 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;쿠버네티스 친화적&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Helm chart 또는 kubectl로 배포 가능&lt;/li&gt;
&lt;li&gt;Pod 기반 벤치마크 → 클러스터 안전하게 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="2-설치-및-실행-예시"&gt;
 2️⃣ 설치 및 실행 예시
 &lt;a class="heading-anchor" href="#2-%ec%84%a4%ec%b9%98-%eb%b0%8f-%ec%8b%a4%ed%96%89-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Helm으로 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;helm repo add kubestr https://kubestr.io/helm-charts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;helm install kubestr kubestr/kubestr
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 스토리지 성능 벤치마크&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;kubestr storageclass ls &lt;span class="c1"&gt;# 클러스터의 StorageClass 목록 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;kubestr benchmark sc my-sc &lt;span class="c1"&gt;# 특정 StorageClass 벤치마크&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="3-사용-목적"&gt;
 3️⃣ 사용 목적
 &lt;a class="heading-anchor" href="#3-%ec%82%ac%ec%9a%a9-%eb%aa%a9%ec%a0%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;스토리지 성능 비교 및 최적화&lt;/li&gt;
&lt;li&gt;클러스터 스토리지 상태 점검&lt;/li&gt;
&lt;li&gt;Persistent Volume 병목 또는 구성 문제 사전 탐지&lt;/li&gt;
&lt;li&gt;DevOps/Platform 팀에서 클러스터 안정성 확보&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="4-요약"&gt;
 4️⃣ 요약
 &lt;a class="heading-anchor" href="#4-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;내용&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;이름&lt;/td&gt;
					&lt;td&gt;Kubestr&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;역할&lt;/td&gt;
					&lt;td&gt;쿠버네티스 클러스터 스토리지 점검 &amp;amp; 성능 벤치마크&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;대상&lt;/td&gt;
					&lt;td&gt;StorageClass, PersistentVolume, PVC 등&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;장점&lt;/td&gt;
					&lt;td&gt;클러스터 친화적, IOPS/Throughput/Latency 측정, 보고서 제공&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;💡 &lt;strong&gt;한 줄 기억:&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Kubestr = 쿠버네티스 스토리지의 건강검진 + 성능 테스트 도구&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] Velero: 클러스터 백업, 복구, 마이그레이션 도구</title><link>https://kyungryeol-yoon.github.io/kubernetes/storage/kubernetes-velero/</link><pubDate>Mon, 02 Jun 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/storage/kubernetes-velero/</guid><description>&lt;h2 id="-velero란"&gt;
 🛡️ Velero란?
 &lt;a class="heading-anchor" href="#-velero%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Velero&lt;/strong&gt;는 쿠버네티스 클러스터의 &lt;strong&gt;리소스와 데이터를 백업/복원하고, 클러스터 간 마이그레이션&lt;/strong&gt;을 지원하는 도구입니다.&lt;br&gt;
재해 복구(Disaster Recovery)와 테스트/스테이징 환경 관리에 유용합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-주요-기능"&gt;
 1️⃣ 주요 기능
 &lt;a class="heading-anchor" href="#1-%ec%a3%bc%ec%9a%94-%ea%b8%b0%eb%8a%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;백업 (Backup)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;전체 클러스터 또는 특정 네임스페이스 단위 백업&lt;/li&gt;
&lt;li&gt;리소스 + Persistent Volume 데이터 포함 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;복원 (Restore)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;특정 시점으로 클러스터 또는 네임스페이스 복원&lt;/li&gt;
&lt;li&gt;선택적 리소스 복원 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;마이그레이션 (Migration)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;클러스터 간 애플리케이션 이전&lt;/li&gt;
&lt;li&gt;테스트/스테이징 환경 배포 용이&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;클라우드 스토리지 연동&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AWS S3, GCP GCS, Azure Blob 등 외부 오브젝트 스토리지 활용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="2-설치-및-사용-예시"&gt;
 2️⃣ 설치 및 사용 예시
 &lt;a class="heading-anchor" href="#2-%ec%84%a4%ec%b9%98-%eb%b0%8f-%ec%82%ac%ec%9a%a9-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Velero CLI 설치 (Mac 예시)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;brew install velero
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 클러스터에 Velero 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;velero install &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; --provider aws &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; --bucket my-backup-bucket &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; --secret-file ./credentials-velero
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 백업 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;velero backup create my-backup --include-namespaces default
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 백업 목록 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;velero backup get
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 백업 복원&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;velero restore create --from-backup my-backup&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="3-사용-목적"&gt;
 3️⃣ 사용 목적
 &lt;a class="heading-anchor" href="#3-%ec%82%ac%ec%9a%a9-%eb%aa%a9%ec%a0%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;쿠버네티스 클러스터 &lt;strong&gt;재해 복구 준비&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;선택적 &lt;strong&gt;Namespace/리소스 백업 및 복원&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;클러스터 간 &lt;strong&gt;데이터 및 리소스 마이그레이션&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;테스트 환경/스테이징 환경 구성 자동화&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="4-요약"&gt;
 4️⃣ 요약
 &lt;a class="heading-anchor" href="#4-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;내용&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;이름&lt;/td&gt;
					&lt;td&gt;Velero&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;역할&lt;/td&gt;
					&lt;td&gt;Kubernetes 리소스 &amp;amp; 데이터 백업, 복구, 마이그레이션&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;대상&lt;/td&gt;
					&lt;td&gt;Namespace, PV, CRD 등&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;장점&lt;/td&gt;
					&lt;td&gt;클라우드 연동, 선택적 백업, 재해 복구/마이그레이션 용이&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;💡 &lt;strong&gt;한 줄 기억:&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Velero = 쿠버네티스 클러스터용 “백업 + 복구 + 마이그레이션 매니저”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] Steady Load on Kubernetes Node Using Stress</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/steady-load-on-kubernetes-node-using-stress/</link><pubDate>Mon, 19 May 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/steady-load-on-kubernetes-node-using-stress/</guid><description>&lt;h2 id="stress-설치"&gt;
 stress 설치
 &lt;a class="heading-anchor" href="#stress-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;RUN apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get install -y stress bc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="configmap-설정"&gt;
 ConfigMap 설정
 &lt;a class="heading-anchor" href="#configmap-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ConfigMap&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;stress-script&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;chip-analyzer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stress-control.sh&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; #!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; TARGET_CPU_USAGE=$TARGET_CPU
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;TARGET_CPU_USAGE = $TARGET_CPU_USAGE&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; TARGET_MEMORY_USAGE=$TARGET_MEM
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;TARGET_MEMORY_USAGE = $TARGET_MEMORY_USAGE&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; TIMEOUT=$TIMEOUT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;TIMEOUT = $TIMEOUT&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; while true; do
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;##### CPU Check #####&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; TOTAL_CORES=$(nproc)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;TOTAL_CORES = $TOTAL_CORES&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; CURRENT_IDLE=$(top -bn1 | grep &amp;#34;Cpu(s)&amp;#34; | sed &amp;#34;s/.*, *\([0-9.]*\)%* id.*/\1/&amp;#34; | awk &amp;#39;{print $1}&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;CURRENT_IDLE = $CURRENT_IDLE&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; CURRENT_CPU_USAGE=$(echo &amp;#34;100 - $CURRENT_IDLE&amp;#34; | bc -l)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;CURRENT_CPU_USAGE = $CURRENT_CPU_USAGE&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; NEEDED_CPU_USAGE=$(echo &amp;#34;$TARGET_CPU_USAGE - $CURRENT_CPU_USAGE&amp;#34; | bc -l)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;NEEDED_CPU_USAGE = $NEEDED_CPU_USAGE&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; TARGET_CPU_CORES=$(echo &amp;#34;$NEEDED_CPU_USAGE * $TOTAL_CORES / 100&amp;#34; | bc -l)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;TARGET_CPU_CORES = $TARGET_CPU_CORES&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; TARGET_CPU_CORES_ROUNDED=$(echo &amp;#34;($TARGET_CPU_CORES+0.5)/1&amp;#34; | bc)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;TARGET_CPU_CORES_ROUNDED = $TARGET_CPU_CORES_ROUNDED&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;##### Memory Check #####&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; TOTAL_MEMORY=$(grep MemTotal /proc/meminfo | awk &amp;#39;{print $2}&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;TOTAL_MEMORY = $TOTAL_MEMORY&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; FREE_MEMORY=$(grep MemFree /proc/meminfo | awk &amp;#39;{print $2}&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;FREE_MEMORY = $FREE_MEMORY&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; BUFFERS=$(grep Buffers /proc/meminfo | awk &amp;#39;{print $2}&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;BUFFERS = $BUFFERS&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; CACHED=$(grep &amp;#34;^Cached&amp;#34; /proc/meminfo | awk &amp;#39;{print $2}&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;CACHED = $CACHED&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; USED_MEMORY=$((TOTAL_MEMORY - FREE_MEMORY - BUFFERS - CACHED))
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;USED_MEMORY = $USED_MEMORY&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; TARGET_MEMORY=$(echo &amp;#34;$TOTAL_MEMORY * $TARGET_MEMORY_USAGE / 100&amp;#34; | bc)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;TARGET_MEMORY = $TARGET_MEMORY&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; NEEDED_MEMORY=$((TARGET_MEMORY - USED_MEMORY))
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;NEEDED_MEMORY = $NEEDED_MEMORY&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # MB로 계산하고 싶을 때(반올림 추가)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; NEEDED_MEMORY_ROUNDED=$(echo &amp;#34;($NEEDED_MEMORY + 1023) / 1024&amp;#34; | bc)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;NEEDED_MEMORY_ROUNDED = $NEEDED_MEMORY_ROUNDED&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; if (( $(echo &amp;#34;$TARGET_CPU_CORES_ROUNDED &amp;gt; 0&amp;#34; | bc -l) )) &amp;amp;&amp;amp; (( NEEDED_MEMORY &amp;gt; 1023 )); then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Adding Stress CPU: $TARGET_CPU_CORES_ROUNDED / Memory: $NEEDED_MEMORY KB.&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; stress --cpu $TARGET_CPU_CORES_ROUNDED --vm 1 --vm-bytes ${NEEDED_MEMORY}k --vm-hang 0 --verbose --timeout ${TIMEOUT}s
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; elif (( $(echo &amp;#34;$TARGET_CPU_CORES_ROUNDED &amp;gt; 0&amp;#34; | bc -l) )) &amp;amp;&amp;amp; (( NEEDED_MEMORY &amp;lt;= 1023 )); then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Adding Stress CPU: $TARGET_CPU_CORES_ROUNDED.&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; stress --cpu $TARGET_CPU_CORES_ROUNDED --vm-hang 0 --verbose --timeout ${TIMEOUT}s
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; elif (( $(echo &amp;#34;$TARGET_CPU_CORES_ROUNDED &amp;lt;= 0&amp;#34; | bc -l) )) &amp;amp;&amp;amp; (( NEEDED_MEMORY &amp;gt; 1023 )); then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Adding Stress Memory: $NEEDED_MEMORY KB.&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; stress --vm 1 --vm-bytes ${NEEDED_MEMORY}k --vm-hang 0 --verbose --timeout ${TIMEOUT}s
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; else
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;No Stress Needed.&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; wait
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; sleep 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; done&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="daemonset-설정"&gt;
 DaemonSet 설정
 &lt;a class="heading-anchor" href="#daemonset-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;DaemonSet&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;chip-analyzer-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;chip-analyzer-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;chip-analyzer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;updateStrategy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;RollingUpdate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rollingUpdate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;maxUnavailable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;maxSurge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;chip-analyzer-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;chip-analyzer-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;affinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeAffinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeSelectorTerms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;matchExpressions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;node-role.kubernetes.io/control-plane&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Exists&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tolerations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;node-role.kubernetes.io/control-plane&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Exists&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;effect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NoSchedule&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;node-role.kubernetes.io/master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Exists&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;effect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NoSchedule&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TARGET_CPU&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;50&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TARGET_MEM&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;50&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TIMEOUT&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;300&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;stress:v1.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/bin/bash&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/scripts/stress-control.sh&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;script-volume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/scripts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;imagePullPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Always&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;chip-analyzer-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restartPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Always&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;script-volume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;stress-script&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;defaultMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0775&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Linux] Stress</title><link>https://kyungryeol-yoon.github.io/linux/process/linux-stress/</link><pubDate>Sat, 17 May 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/process/linux-stress/</guid><description>&lt;h2 id="stress-설치"&gt;
 stress 설치
 &lt;a class="heading-anchor" href="#stress-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;stress는 다양한 스트레스 테스트를 지원하는 도구&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;apt install -y stress&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="stress-옵션"&gt;
 stress 옵션
 &lt;a class="heading-anchor" href="#stress-%ec%98%b5%ec%85%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;Usage: stress &lt;span class="o"&gt;[&lt;/span&gt;OPTION &lt;span class="o"&gt;[&lt;/span&gt;ARG&lt;span class="o"&gt;]]&lt;/span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; -?, --help show this &lt;span class="nb"&gt;help&lt;/span&gt; statement
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; --version show version statement
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; -v, --verbose be verbose
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; -q, --quiet be quiet
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; -n, --dry-run show what would have been &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; -t, --timeout N timeout after N seconds
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; --backoff N &lt;span class="nb"&gt;wait&lt;/span&gt; factor of N microseconds before work starts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; -c, --cpu N spawn N workers spinning on sqrt&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; -i, --io N spawn N workers spinning on sync&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; -m, --vm N spawn N workers spinning on malloc&lt;span class="o"&gt;()&lt;/span&gt;/free&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; --vm-bytes B malloc B bytes per vm worker &lt;span class="o"&gt;(&lt;/span&gt;default is 256MB&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; --vm-stride B touch a byte every B bytes &lt;span class="o"&gt;(&lt;/span&gt;default is 4096&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; --vm-hang N sleep N secs before free &lt;span class="o"&gt;(&lt;/span&gt;default none, &lt;span class="m"&gt;0&lt;/span&gt; is inf&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; --vm-keep redirty memory instead of freeing and reallocating
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; -d, --hdd N spawn N workers spinning on write&lt;span class="o"&gt;()&lt;/span&gt;/unlink&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; --hdd-bytes B write B bytes per hdd worker &lt;span class="o"&gt;(&lt;/span&gt;default is 1GB&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="example"&gt;
 Example
 &lt;a class="heading-anchor" href="#example" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;stress --cpu &lt;span class="m"&gt;8&lt;/span&gt; --io &lt;span class="m"&gt;4&lt;/span&gt; --vm &lt;span class="m"&gt;2&lt;/span&gt; --vm-bytes 128M --timeout 10s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cpu-부하"&gt;
 CPU 부하
 &lt;a class="heading-anchor" href="#cpu-%eb%b6%80%ed%95%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;stress -c &amp;lt;Core 수&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="memory-부하"&gt;
 Memory 부하
 &lt;a class="heading-anchor" href="#memory-%eb%b6%80%ed%95%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;사용할 크기의 단위 : b(byte) ,k(killo byte) , m(mega byte) , g(giga byte)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;stress –vm &amp;lt;프로세스 수&amp;gt; –vm-bytes &amp;lt;사용할 크기&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;ex&lt;span class="o"&gt;)&lt;/span&gt;stress -vm &lt;span class="m"&gt;2&lt;/span&gt; –vm-bytes 2048m&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="hdd-write-부하"&gt;
 HDD write 부하
 &lt;a class="heading-anchor" href="#hdd-write-%eb%b6%80%ed%95%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;stress –hdd &amp;lt;write에 사용할 worker 수&amp;gt; –hdd-bytes &amp;lt;사용할 크기&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;ex&lt;span class="o"&gt;)&lt;/span&gt; stress –hdd &lt;span class="m"&gt;3&lt;/span&gt; -hdd-bytes 1024m&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="io--부하"&gt;
 I/O 부하
 &lt;a class="heading-anchor" href="#io--%eb%b6%80%ed%95%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;stress -i &amp;lt;sync를 사용하여 i/o 부하를 발생 시킬 worker의수&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Steady Load on Kubernetes Node Using Stress-ng</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/steady-load-on-kubernetes-node-using-stress-ng/</link><pubDate>Mon, 12 May 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/steady-load-on-kubernetes-node-using-stress-ng/</guid><description>&lt;h2 id="stress-ng-설치"&gt;
 stress-ng 설치
 &lt;a class="heading-anchor" href="#stress-ng-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;stress-ng는 다양한 스트레스 테스트를 지원하는 도구&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;apt install -y stress-ng&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Linux] Stress-ng</title><link>https://kyungryeol-yoon.github.io/linux/process/linux-stress-ng/</link><pubDate>Sat, 10 May 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/process/linux-stress-ng/</guid><description>&lt;h2 id="stress-ng-설치"&gt;
 stress-ng 설치
 &lt;a class="heading-anchor" href="#stress-ng-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;stress-ng는 다양한 스트레스 테스트를 지원하는 도구&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;apt install -y stress-ng&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cpu-스트레스-테스트-실행"&gt;
 CPU 스트레스 테스트 실행
 &lt;a class="heading-anchor" href="#cpu-%ec%8a%a4%ed%8a%b8%eb%a0%88%ec%8a%a4-%ed%85%8c%ec%8a%a4%ed%8a%b8-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;설치 후, 아래 명령어를 사용해 CPU 스트레스 테스트를 실행할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;stress-ng --cpu &lt;span class="m"&gt;1&lt;/span&gt; --cpu-load &lt;span class="m"&gt;70&lt;/span&gt; --timeout 10m --metrics --times --verify&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--cpu&lt;/code&gt; 1: CPU 코어 1개를 사용해 스트레스 테스트를 수행&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--cpu-load&lt;/code&gt; 70: CPU 사용률을 70%로 설정&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--timeout&lt;/code&gt; 10m: 테스트를 10분 동안 실행&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--metrics&lt;/code&gt;: 테스트 결과에 대한 성능 메트릭스를 표시&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--times&lt;/code&gt;: 테스트 완료 후 실행 시간과 관련된 통계를 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--verify&lt;/code&gt;: 테스트 중 계산 결과가 정확한지 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="실행-결과-예시"&gt;
 실행 결과 예시
 &lt;a class="heading-anchor" href="#%ec%8b%a4%ed%96%89-%ea%b2%b0%ea%b3%bc-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;테스트를 실행하면 다음과 비슷한 결과를 볼 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;stress-ng: info: &lt;span class="o"&gt;[&lt;/span&gt;1234&lt;span class="o"&gt;]&lt;/span&gt; Setting up &lt;span class="m"&gt;1&lt;/span&gt; CPU worker&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt; to run 70% load
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;stress-ng: info: &lt;span class="o"&gt;[&lt;/span&gt;1234&lt;span class="o"&gt;]&lt;/span&gt; Successful run completed in 600.00s &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt; mins&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;stress-ng: info: &lt;span class="o"&gt;[&lt;/span&gt;1234&lt;span class="o"&gt;]&lt;/span&gt; Metrics: bogo-ops: 1000000, real-time: 600.00s, user-time: 420.00s, system-time: 0.05s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;stress-ng: info: &lt;span class="o"&gt;[&lt;/span&gt;1234&lt;span class="o"&gt;]&lt;/span&gt; Verification passed: 100.0% correct&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="테스트-후-모니터링"&gt;
 테스트 후 모니터링
 &lt;a class="heading-anchor" href="#%ed%85%8c%ec%8a%a4%ed%8a%b8-%ed%9b%84-%eb%aa%a8%eb%8b%88%ed%84%b0%eb%a7%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;다음 명령어를 사용해 CPU 사용량을 확인할 수 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;▼ top 명령어:CPU, 메모리 사용률을 실시간으로 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;top&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;▼ htop (더 보기 편리한 대안):CPU 사용량과 프로세스를 시각적으로 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;htop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="테스트-종료"&gt;
 테스트 종료
 &lt;a class="heading-anchor" href="#%ed%85%8c%ec%8a%a4%ed%8a%b8-%ec%a2%85%eb%a3%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;테스트가 완료되면 자동으로 종료되지만, 수동으로 종료하려면 다음 명령을 사용할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;pkill stress-ng&lt;/code&gt;: 실행 중인 stress-ng 프로세스를 종료합니다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pkill stress-ng&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Upgrade Kubernetes(v1.32.x) using Kubekey(v3.1.9) Artifact</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/upgrade-kubernetesv1.32.x-using-kubekeyv3.1.9-artifact/</link><pubDate>Fri, 02 May 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/upgrade-kubernetesv1.32.x-using-kubekeyv3.1.9-artifact/</guid><description>&lt;blockquote&gt;
&lt;p&gt;offline 설치 위한 artifact 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;version 참고
&lt;ul&gt;
&lt;li&gt;kubernetes와 관련된 image는 &lt;a href="https://github.com/kubesphere/ks-installer/releases"&gt;https://github.com/kubesphere/ks-installer/releases&lt;/a&gt;에서 주요 release에만 포함되는 image-list.txt파일을 참고&lt;/li&gt;
&lt;li&gt;kubekey의 버전별로 kubernetes, kubesphere의 최신 지원 버전이 있음
&lt;ul&gt;
&lt;li&gt;kubekey/version/components.json&lt;/li&gt;
&lt;li&gt;kubekey/cmd/kk/pkg/version/kubesphere/version_enum.go&lt;/li&gt;
&lt;li&gt;kubekey/cmd/kk/pkg/version/kubernetes/version_enum.go&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;default 버전에 대한 설정은 kubekey/cmd/kk/apis/kubekey/v1alpha2/default.go 파일에 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/kubekey/blob/v3.1.9/docs/manifest_and_artifact.md"&gt;https://github.com/kubesphere/kubekey/blob/v3.1.9/docs/manifest_and_artifact.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/ks-installer/releases/download/v3.4.1/images-list.txt"&gt;https://github.com/kubesphere/ks-installer/releases/download/v3.4.1/images-list.txt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubesphere.io/docs/v3.4/installing-on-linux/introduction/air-gapped-installation"&gt;https://kubesphere.io/docs/v3.4/installing-on-linux/introduction/air-gapped-installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/kubekey/blob/v3.1.9/docs/manifest-example.md"&gt;https://github.com/kubesphere/kubekey/blob/v3.1.9/docs/manifest-example.md&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="script-다운로드"&gt;
 script 다운로드
 &lt;a class="heading-anchor" href="#script-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -sfL https://get-kk.kubesphere.io &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v3.1.9 sh -&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="ubuntu-2004-debs-amd64iso-다운로드"&gt;
 ubuntu-20.04-debs-amd64.iso 다운로드
 &lt;a class="heading-anchor" href="#ubuntu-2004-debs-amd64iso-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;wget https://github.com/kubesphere/kubekey/releases/download/v3.1.9/ubuntu-20.04-debs-amd64.iso&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="artifact-319yaml-작성"&gt;
 artifact-3.1.9.yaml 작성
 &lt;a class="heading-anchor" href="#artifact-319yaml-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubekey.kubesphere.io/v1alpha2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Manifest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;artifact-v3.1.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;arches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;amd64&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operatingSystems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;arch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;amd64&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;linux&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ubuntu&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;20.04&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;osImage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Ubuntu 20.04.4 LTS&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;iso&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;localPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/home/ubuntu/kk_install/ubuntu-20.04-debs-amd64.iso&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# url: &amp;#34;https://github.com/kubesphere/kubekey/releases/download/v3.1.1/ubuntu-20.04-debs-amd64.iso&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubernetesDistributions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.32.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;helm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.14.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cni&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;etcd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.5.13&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;calicoctl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.27.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerRuntimes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;containerd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1.7.13&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;crictl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.29.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;harbor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v2.10.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;docker-compose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v2.26.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;images&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-apiserver:v1.30.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-apiserver:v1.31.8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-apiserver:v1.32.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-controller-manager:v1.30.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-controller-manager:v1.31.8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-controller-manager:v1.32.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-scheduler:v1.30.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-scheduler:v1.31.8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-scheduler:v1.32.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-proxy:v1.30.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-proxy:v1.31.8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-proxy:v1.32.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/pause:3.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/coredns/coredns:1.9.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/cni:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/cni:v3.27.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/kube-controllers:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/kube-controllers:v3.27.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/node:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/node:v3.27.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/pod2daemon-flexvol:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/pod2daemon-flexvol:v3.27.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/typha:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/typha:v3.27.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/flannel:v0.12.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/openebs/provisioner-localpv:3.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/openebs/linux-utils:3.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/haproxy:2.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/nfs-subdir-external-provisioner:v4.0.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/k8s-dns-node-cache:1.15.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;docker.io&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;username&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;password&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="components-version-확인지원하는-version이-없을-시-아래와-같이-error"&gt;
 components version 확인(지원하는 version이 없을 시 아래와 같이 Error)
 &lt;a class="heading-anchor" href="#components-version-%ed%99%95%ec%9d%b8%ec%a7%80%ec%9b%90%ed%95%98%eb%8a%94-version%ec%9d%b4-%ec%97%86%ec%9d%84-%ec%8b%9c-%ec%95%84%eb%9e%98%ec%99%80-%ea%b0%99%ec%9d%b4-error" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Failed to download docker binary: curl -L -o /home/ubuntu/kk_install/kubekey/artifact/docker/20.10.8/amd64/docker-20.10.8.tgz https://download.docker.com/linux/static/stable/x86_64/docker-20.10.8.tgz error: No SHA256 found for docker. 20.10.8 is not supported.
17:40:24 KST failed: [LocalHost]
error: Pipeline[ArtifactExportPipeline] execute failed: Module[ArtifactBinariesModule] exec failed:
failed: [LocalHost] [DownloadBinaries] exec failed after 1 retries: Failed to download docker binary: curl -L -o /home/ubuntu/kk_install/kubekey/artifact/docker/20.10.8/amd64/docker-20.10.8.tgz https://download.docker.com/linux/static/stable/x86_64/docker-20.10.8.tgz error: No SHA256 found for docker. 20.10.8 is not supported.&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;Components 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/kubekey/blob/v3.1.9/version/components.json"&gt;https://github.com/kubesphere/kubekey/blob/v3.1.9/version/components.json&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="export-artifact"&gt;
 Export Artifact
 &lt;a class="heading-anchor" href="#export-artifact" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk artifact &lt;span class="nb"&gt;export&lt;/span&gt; -m artifact-3.1.9.yaml -o artifact-3.1.9.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cluster-업그레이드를-위한-config-파일-생성-및-작성"&gt;
 Cluster 업그레이드를 위한 config 파일 생성 및 작성
 &lt;a class="heading-anchor" href="#cluster-%ec%97%85%ea%b7%b8%eb%a0%88%ec%9d%b4%eb%93%9c%eb%a5%bc-%ec%9c%84%ed%95%9c-config-%ed%8c%8c%ec%9d%bc-%ec%83%9d%ec%84%b1-%eb%b0%8f-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk create config --with-kubesphere v3.3.2 --with-kubernetes v1.32.4 -f config-v1.32.4.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi config-v1.32.4.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubekey.kubesphere.io/v1alpha2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;sample&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: kk-repo, address: 192.168.0.100, internalAddress: 192.168.0.100, privateKeyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/home/ubuntu/.ssh/id_rsa_multipass&amp;#34;&lt;/span&gt;}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: kk-master, address: 192.168.0.101, internalAddress: 192.168.0.101, privateKeyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/home/ubuntu/.ssh/id_rsa_multipass&amp;#34;&lt;/span&gt;}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: kk-worker-1, address: 192.168.0.102, internalAddress: 192.168.0.102, privateKeyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/home/ubuntu/.ssh/id_rsa_multipass&amp;#34;&lt;/span&gt;}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: kk-worker-2, address: 192.168.0.103, internalAddress: 192.168.0.103, privateKeyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/home/ubuntu/.ssh/id_rsa_multipass&amp;#34;&lt;/span&gt;}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;roleGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;etcd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;kk-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;control-plane&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;kk-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;kk-worker-1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;kk-worker-2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;kk-repo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;controlPlaneEndpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## Internal loadbalancer for apiservers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# internalLoadbalancer: haproxy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;lb.kubesphere.local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# domain: 192.168.0.101&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;192.168.0.101&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubernetes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.29.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;imageRepo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubesphere&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;clusterName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster.local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;masqueradeAll&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;maxPods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;150&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeCidrMaskSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;24&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;proxyMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ipvs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;autoRenewCerts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerManager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;containerd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;featureGates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;RotateKubeletServerCertificate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiserverArgs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;default-not-ready-toleration-seconds=30&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;default-unreachable-toleration-seconds=30&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;controllerManagerArgs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;node-monitor-period=2s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;node-monitor-grace-period=16s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubeletConfiguration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeStatusUpdateFrequency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;4s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# etcd:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# type: kubekey&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;calico&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;calico&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ipipMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Always&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;vxianMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Never&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;vethMTU&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1440&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubePodsCIDR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10.233.64.0&lt;/span&gt;&lt;span class="l"&gt;/18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubeServiceCIDR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10.233.0.0&lt;/span&gt;&lt;span class="l"&gt;/18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## multus support. https://github.com/k8snetworkplumbingwg/multus-cni&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;multusCNI&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;harbor&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cr.harbor.kubekey.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;admin&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Harbor12345&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;privateRegistry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cr.harbor.kubekey.com&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespaceOverride&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;kubesphereio&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registryMirrors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecureRegistries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cr.harbor.kubekey.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;addons&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="upgrade"&gt;
 Upgrade
 &lt;a class="heading-anchor" href="#upgrade" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk upgrade cluster -f config-v1.32.4.yaml -a artifact-3.1.9.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;--skip-dependency-check&lt;/code&gt;를 추가하면 Kubernetes 및 KubeSphere 버전 의존성 검사를 생략할 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk upgrade cluster -f config-v1.32.4.yaml -a artifact-3.1.9.tar.gz --skip-dependency-check&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-tip }&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;image 별도로 push 방법&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk artifact image push -f config-v1.32.4.yaml -a artifact-3.1.9.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-tip }&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[ERROR] Harbor에 image push 할 때 Unauthorized 에러 발생 때&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;다시 로그인&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker login &lt;span class="o"&gt;[&lt;/span&gt;your.host.com&lt;span class="o"&gt;]&lt;/span&gt;:port -u username -p password
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo docker login https://cr.harbor.kubekey.com -u admin -p Harbor12345&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-danger }&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;kubekey command 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/kubekey/blob/master/docs/commands/kk-upgrade.md"&gt;https://github.com/kubesphere/kubekey/blob/master/docs/commands/kk-upgrade.md&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="upgrade-log-확인"&gt;
 Upgrade log 확인
 &lt;a class="heading-anchor" href="#upgrade-log-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl logs -n kubesphere-system &lt;span class="k"&gt;$(&lt;/span&gt;kubectl get pod -n kubesphere-system -l &lt;span class="s1"&gt;&amp;#39;app in (ks-install, ks-installer)&amp;#39;&lt;/span&gt; -o &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{.items[0].metadata.name}&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt; -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Install Kubernetes(v1.29.x) using Kubekey(v3.1.1) Artifact on Multipass</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-kubernetesv1.29.x-using-kubekeyv3.1.1-artifact-on-multipass/</link><pubDate>Mon, 28 Apr 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-kubernetesv1.29.x-using-kubekeyv3.1.1-artifact-on-multipass/</guid><description>&lt;blockquote&gt;
&lt;p&gt;offline 설치 위한 artifact 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;version 참고
&lt;ul&gt;
&lt;li&gt;kubernetes와 관련된 image는 &lt;a href="https://github.com/kubesphere/ks-installer/releases"&gt;https://github.com/kubesphere/ks-installer/releases&lt;/a&gt;에서 주요 release에만 포함되는 image-list.txt파일을 참고&lt;/li&gt;
&lt;li&gt;kubekey의 버전별로 kubernetes, kubesphere의 최신 지원 버전이 있음
&lt;ul&gt;
&lt;li&gt;kubekey/version/components.json&lt;/li&gt;
&lt;li&gt;kubekey/cmd/kk/pkg/version/kubesphere/version_enum.go&lt;/li&gt;
&lt;li&gt;kubekey/cmd/kk/pkg/version/kubernetes/version_enum.go&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;default 버전에 대한 설정은 kubekey/cmd/kk/apis/kubekey/v1alpha2/default.go 파일에 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/kubekey/blob/v3.1.1/docs/manifest_and_artifact.md"&gt;https://github.com/kubesphere/kubekey/blob/v3.1.1/docs/manifest_and_artifact.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/ks-installer/releases/download/v3.4.1/images-list.txt"&gt;https://github.com/kubesphere/ks-installer/releases/download/v3.4.1/images-list.txt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubesphere.io/docs/v3.4/installing-on-linux/introduction/air-gapped-installation"&gt;https://kubesphere.io/docs/v3.4/installing-on-linux/introduction/air-gapped-installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/kubekey/blob/v3.1.1/docs/manifest-example.md"&gt;https://github.com/kubesphere/kubekey/blob/v3.1.1/docs/manifest-example.md&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="multipass-접속을-위한-ssh-key-생성"&gt;
 Multipass 접속을 위한 ssh key 생성
 &lt;a class="heading-anchor" href="#multipass-%ec%a0%91%ec%86%8d%ec%9d%84-%ec%9c%84%ed%95%9c-ssh-key-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ssh-keygen -t rsa -b &lt;span class="m"&gt;2048&lt;/span&gt; -f ~/.ssh/id_rsa_multipass&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cloud-init-구성"&gt;
 cloud-init 구성
 &lt;a class="heading-anchor" href="#cloud-init-%ea%b5%ac%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;cloud-init 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi cloud-init.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;cloud-init 작성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;root&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;sudo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ALL=(ALL) NOPASSWD:ALL&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ssh_authorized_keys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;&amp;lt;content of YOUR public key&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ubuntu&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;sudo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ALL=(ALL) NOPASSWD:ALL&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ssh_authorized_keys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;&amp;lt;content of YOUR public key&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;runcmd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo apt-get update&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo timedatectl set-timezone &amp;#34;Asia/Seoul&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo swapoff -a&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo sed -i &amp;#34;/swap/d&amp;#34; /etc/fstab&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo apt-get install -y conntrack&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo apt-get install -y socat&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="cloud-init의-ssh_authorized_keys-설정을-하지-않았을-시"&gt;
 cloud-init의 ssh_authorized_keys 설정을 하지 않았을 시
 &lt;a class="heading-anchor" href="#cloud-init%ec%9d%98-ssh_authorized_keys-%ec%84%a4%ec%a0%95%ec%9d%84-%ed%95%98%ec%a7%80-%ec%95%8a%ec%95%98%ec%9d%84-%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;각 Node의 &lt;code&gt;~/.ssh&lt;/code&gt; 경로의 있는 &lt;code&gt;authorized_keys&lt;/code&gt;에 &lt;code&gt;id_rsa_multipass.pub&lt;/code&gt; 내용 붙여넣기&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cat &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.ssh/id_rsa_multipass.pub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;root 계정일 때&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# root 접속&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo -i
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 수정 또는 .ssh 폴더 생성 후 authorized_keys 작성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;vi .ssh/authorized_keys&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="multipass-생성"&gt;
 Multipass 생성
 &lt;a class="heading-anchor" href="#multipass-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Repository 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass launch focal --name kk-repo --memory 8G --disk 100G --cpus &lt;span class="m"&gt;4&lt;/span&gt; --network &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multipass,mode&lt;span class="o"&gt;=&lt;/span&gt;manual --cloud-init cloud-init.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Master 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass launch focal --name kk-master --memory 8G --disk 50G --cpus &lt;span class="m"&gt;4&lt;/span&gt; --network &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multipass,mode&lt;span class="o"&gt;=&lt;/span&gt;manual --cloud-init cloud-init.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Worker-1 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass launch focal --name kk-worker-1 --memory 8G --disk 50G --cpus &lt;span class="m"&gt;4&lt;/span&gt; --network &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multipass,mode&lt;span class="o"&gt;=&lt;/span&gt;manual --cloud-init cloud-init.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Worker-2 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass launch focal --name kk-worker-2 --memory 8G --disk 50G --cpus &lt;span class="m"&gt;4&lt;/span&gt; --network &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multipass,mode&lt;span class="o"&gt;=&lt;/span&gt;manual --cloud-init cloud-init.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="multipass-접속"&gt;
 Multipass 접속
 &lt;a class="heading-anchor" href="#multipass-%ec%a0%91%ec%86%8d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;kk-repo&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ssh -i &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.ssh/id_rsa_multipass ubuntu@192.168.0.100&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass shell kk-repo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;kk-master&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ssh -i &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.ssh/id_rsa_multipass ubuntu@192.168.0.101&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass shell kk-master&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;kk-worker-1&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ssh -i &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.ssh/id_rsa_multipass ubuntu@192.168.0.102&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass shell kk-worker-1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;kk-worker-2&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ssh -i &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.ssh/id_rsa_multipass ubuntu@192.168.0.103&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass shell kk-worker-2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="각-node별로-static-ip-설정"&gt;
 각 Node별로 Static IP 설정
 &lt;a class="heading-anchor" href="#%ea%b0%81-node%eb%b3%84%eb%a1%9c-static-ip-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo vi /etc/netplan/50-cloud-init.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;kk-repo&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ethernets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eth0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;macaddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;52&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;54&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="l"&gt;6b:21&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;set-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;eth0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;추가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eth1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;192.168.0.100&lt;/span&gt;&lt;span class="l"&gt;/24]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gateway4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.0.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;no&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;kk-master&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ethernets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eth0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;macaddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;52&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;54&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="l"&gt;6b:21&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;set-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;eth0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;추가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eth1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;192.168.0.101&lt;/span&gt;&lt;span class="l"&gt;/24]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gateway4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.0.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;no&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;kk-worker-1&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ethernets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eth0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;macaddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;52&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;54&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="l"&gt;6b:21&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;set-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;eth0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;추가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eth1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;192.168.0.102&lt;/span&gt;&lt;span class="l"&gt;/24]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gateway4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.0.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;no&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;kk-worker-2&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ethernets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eth0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;macaddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;52&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;54&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="l"&gt;6b:21&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;set-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;eth0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;추가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eth1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;192.168.0.103&lt;/span&gt;&lt;span class="l"&gt;/24]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gateway4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.0.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;no&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="kubekey-artifact-구성-및-설치"&gt;
 kubekey artifact 구성 및 설치
 &lt;a class="heading-anchor" href="#kubekey-artifact-%ea%b5%ac%ec%84%b1-%eb%b0%8f-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="script-다운로드"&gt;
 script 다운로드
 &lt;a class="heading-anchor" href="#script-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -sfL https://get-kk.kubesphere.io &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v3.1.1 sh -&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="ubuntu-2004-debs-amd64iso-다운로드"&gt;
 ubuntu-20.04-debs-amd64.iso 다운로드
 &lt;a class="heading-anchor" href="#ubuntu-2004-debs-amd64iso-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;wget https://github.com/kubesphere/kubekey/releases/download/v3.1.1/ubuntu-20.04-debs-amd64.iso&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="artifact-311yaml-작성"&gt;
 artifact-3.1.1.yaml 작성
 &lt;a class="heading-anchor" href="#artifact-311yaml-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubekey.kubesphere.io/v1alpha2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Manifest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;artifact-v3.1.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;arches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;amd64&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operatingSystems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;arch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;amd64&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;linux&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ubuntu&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;20.04&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;osImage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Ubuntu 20.04.4 LTS&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;iso&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;localPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/home/ubuntu/kk_install/ubuntu-20.04-debs-amd64.iso&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# url: &amp;#34;https://github.com/kubesphere/kubekey/releases/download/v3.1.1/ubuntu-20.04-debs-amd64.iso&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubernetesDistributions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.29.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;helm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.14.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cni&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;etcd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.5.13&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;calicoctl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.27.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## For now, if your cluster container runtime is containerd, KubeKey will add a docker 20.10.8 container runtime in the below list.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## The reason is KubeKey creates a cluster with containerd by installing a docker first and making kubelet connect the socket file of containerd which docker contained.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerRuntimes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;docker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;24.0.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;containerd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1.7.13&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;crictl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.29.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;docker-registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;harbor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v2.10.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;docker-compose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v2.26.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;images&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-apiserver:v1.29.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-controller-manager:v1.29.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-scheduler:v1.29.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-proxy:v1.29.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/pause:3.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/coredns/coredns:1.9.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/cni:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/cni:v3.27.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/kube-controllers:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/kube-controllers:v3.27.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/node:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/node:v3.27.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/pod2daemon-flexvol:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/typha:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/flannel:v0.12.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/openebs/provisioner-localpv:3.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/openebs/linux-utils:3.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/haproxy:2.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/nfs-subdir-external-provisioner:v4.0.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/k8s-dns-node-cache:1.22.20&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/k8s-dns-node-cache:1.15.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# https://github.com/kubesphere/ks-installer/releases/download/v3.3.2/images-list.txt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##kubesphere-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-installer:v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-apiserver:v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-console:v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-controller-manager:v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kubectl:v1.22.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kubefed:v0.8.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/tower:v0.2.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/minio/minio:RELEASE.2019-08-07T01-59-21Z&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/minio/mc:RELEASE.2019-08-07T23-14-43Z&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/csiplugin/snapshot-controller:v4.0.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/nginx-ingress-controller:v1.3.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/mirrorgooglecontainers/defaultbackend-amd64:1.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/metrics-server:v0.4.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/redis:5.0.14-alpine&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/haproxy:2.0.25-alpine&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/alpine:3.14&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/osixia/openldap:1.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/netshoot:v1.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##kubeedge-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubeedge/cloudcore:v1.13.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/iptables-manager:v1.13.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubeedge/iptables-manager:v1.9.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/edgeservice:v0.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/edgeservice:v0.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##gatekeeper-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/openpolicyagent/gatekeeper:v3.5.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##openpitrix-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/openpitrix-jobs:v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##kubesphere-devops-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/devops-apiserver:ks-v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/devops-controller:ks-v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/devops-tools:ks-v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-jenkins:v3.4.0-2.319.3-1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jenkins/inbound-agent:4.10-2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-base:v3.2.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-nodejs:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-maven:v3.2.1-jdk11&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-maven:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-python:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;108&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.2-1.18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;109&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.2-1.17&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;110&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.2-1.16&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;111&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;112&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-base:v3.2.2-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;113&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-nodejs:v3.2.0-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;114&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-maven:v3.2.1-jdk11-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;115&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-maven:v3.2.0-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;116&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-python:v3.2.0-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;117&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.0-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;118&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.2-1.18-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;119&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.2-1.17-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;120&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.2-1.16-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;121&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/s2ioperator:v3.2.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;122&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/s2irun:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;123&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/s2i-binary:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;124&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/tomcat85-java11-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;125&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/tomcat85-java11-runtime:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;126&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/tomcat85-java8-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;127&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/tomcat85-java8-runtime:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;128&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/java-11-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;129&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/java-11-runtime:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;130&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/java-8-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;131&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/java-8-runtime:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;132&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/nodejs-8-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;133&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/nodejs-6-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;134&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/nodejs-4-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;135&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/python-36-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;136&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/python-35-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;137&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/python-34-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;138&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/python-27-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;139&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;quay.io/argoproj/argocd:v2.3.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;140&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;quay.io/argoproj/argocd-applicationset:v0.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;141&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ghcr.io/dexidp/dex:v2.30.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;142&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/redis:6.2.6-alpine&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;143&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##kubesphere-monitoring-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;144&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jimmidyson/configmap-reload:v0.7.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;145&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/prom/prometheus:v2.39.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;146&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/prometheus-config-reloader:v0.55.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;147&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/prometheus-operator:v0.55.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;148&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-rbac-proxy:v0.11.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;149&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-state-metrics:v2.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;150&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/prom/node-exporter:v1.3.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;151&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/prom/alertmanager:v0.23.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;152&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/thanosio/thanos:v0.31.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;153&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/grafana/grafana:8.3.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;154&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-rbac-proxy:v0.11.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;155&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/notification-manager-operator:v2.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;156&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/notification-manager:v2.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;157&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/notification-tenant-sidecar:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;158&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##kubesphere-logging-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;159&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/elasticsearch-curator:v5.7.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;160&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/opensearch-curator:v0.0.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;161&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/elasticsearch-oss:6.8.22&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;162&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/opensearchproject/opensearch:2.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;163&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/opensearchproject/opensearch-dashboards:2.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;164&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/fluentbit-operator:v0.14.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;165&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/docker:19.03&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;166&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/fluent-bit:v1.9.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;167&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/log-sidecar-injector:v1.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;168&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/elastic/filebeat:6.7.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;169&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-events-operator:v0.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;170&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-events-ruler:v0.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;171&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-auditing-operator:v0.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;172&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-auditing-webhook:v0.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;173&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##istio-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;174&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/istio/pilot:1.14.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;175&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/istio/proxyv2:1.14.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;176&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jaegertracing/jaeger-operator:1.29&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;177&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jaegertracing/jaeger-agent:1.29&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;178&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jaegertracing/jaeger-collector:1.29&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;179&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jaegertracing/jaeger-query:1.29&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;180&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jaegertracing/jaeger-es-index-cleaner:1.29&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;181&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kiali-operator:v1.50.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;182&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kiali:v1.50&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;183&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ##example-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;184&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/library/busybox:1.31.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;185&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/library/nginx:1.14-alpine&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;186&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/joosthofman/wget:1.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;187&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/nginxdemos/hello:plain-text&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;188&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/library/wordpress:4.8-apache&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;189&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/mirrorgooglecontainers/hpa-example:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;190&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/fluent/fluentd:v1.4.2-2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;191&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/library/perl:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;192&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/examples-bookinfo-productpage-v1:1.16.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;193&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/examples-bookinfo-reviews-v1:1.16.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;194&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/examples-bookinfo-reviews-v2:1.16.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;195&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/examples-bookinfo-details-v1:1.16.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;196&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/examples-bookinfo-ratings-v1:1.16.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;197&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ##weave-scope-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;198&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/weaveworks/scope:1.13.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;199&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;200&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;201&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;docker.io&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;202&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;username&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;203&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;password&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="components-version-확인지원하는-version이-없을-시-아래와-같이-error"&gt;
 components version 확인(지원하는 version이 없을 시 아래와 같이 Error)
 &lt;a class="heading-anchor" href="#components-version-%ed%99%95%ec%9d%b8%ec%a7%80%ec%9b%90%ed%95%98%eb%8a%94-version%ec%9d%b4-%ec%97%86%ec%9d%84-%ec%8b%9c-%ec%95%84%eb%9e%98%ec%99%80-%ea%b0%99%ec%9d%b4-error" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Failed to download docker binary: curl -L -o /home/ubuntu/kk_install/kubekey/artifact/docker/20.10.8/amd64/docker-20.10.8.tgz https://download.docker.com/linux/static/stable/x86_64/docker-20.10.8.tgz error: No SHA256 found for docker. 20.10.8 is not supported.
17:40:24 KST failed: [LocalHost]
error: Pipeline[ArtifactExportPipeline] execute failed: Module[ArtifactBinariesModule] exec failed:
failed: [LocalHost] [DownloadBinaries] exec failed after 1 retries: Failed to download docker binary: curl -L -o /home/ubuntu/kk_install/kubekey/artifact/docker/20.10.8/amd64/docker-20.10.8.tgz https://download.docker.com/linux/static/stable/x86_64/docker-20.10.8.tgz error: No SHA256 found for docker. 20.10.8 is not supported.&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;Components 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/kubekey/blob/v3.1.1/version/components.json"&gt;https://github.com/kubesphere/kubekey/blob/v3.1.1/version/components.json&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="export-artifact"&gt;
 Export Artifact
 &lt;a class="heading-anchor" href="#export-artifact" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk artifact &lt;span class="nb"&gt;export&lt;/span&gt; -m artifact-3.1.1.yaml -o artifact-3.1.1.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="cluster-설치를-위한-config-파일-생성-및-작성"&gt;
 Cluster 설치를 위한 config 파일 생성 및 작성
 &lt;a class="heading-anchor" href="#cluster-%ec%84%a4%ec%b9%98%eb%a5%bc-%ec%9c%84%ed%95%9c-config-%ed%8c%8c%ec%9d%bc-%ec%83%9d%ec%84%b1-%eb%b0%8f-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;config 파일 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk create config --with-kubesphere v3.3.2 --with-kubernetes v1.29.3 -f config-v1.29.3.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;config 파일 편집&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi config-v1.29.3.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;config 파일 작성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubekey.kubesphere.io/v1alpha2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;sample&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: kk-repo, address: 192.168.0.100, internalAddress: 192.168.0.100, privateKeyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/home/ubuntu/.ssh/id_rsa_multipass&amp;#34;&lt;/span&gt;}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: kk-master, address: 192.168.0.101, internalAddress: 192.168.0.101, privateKeyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/home/ubuntu/.ssh/id_rsa_multipass&amp;#34;&lt;/span&gt;}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: kk-worker-1, address: 192.168.0.102, internalAddress: 192.168.0.102, privateKeyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/home/ubuntu/.ssh/id_rsa_multipass&amp;#34;&lt;/span&gt;}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: kk-worker-2, address: 192.168.0.103, internalAddress: 192.168.0.103, privateKeyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/home/ubuntu/.ssh/id_rsa_multipass&amp;#34;&lt;/span&gt;}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;roleGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;etcd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;kk-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;control-plane&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;kk-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;kk-worker-1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;kk-worker-2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;kk-repo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;controlPlaneEndpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## Internal loadbalancer for apiservers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# internalLoadbalancer: haproxy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;lb.kubesphere.local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# domain: 192.168.0.101&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;192.168.0.101&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubernetes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.29.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;imageRepo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubesphere&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;clusterName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster.local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;masqueradeAll&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;maxPods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;150&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeCidrMaskSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;24&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;proxyMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ipvs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;autoRenewCerts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerManager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;containerd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;featureGates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;RotateKubeletServerCertificate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiserverArgs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;default-not-ready-toleration-seconds=30&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;default-unreachable-toleration-seconds=30&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;controllerManagerArgs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;node-monitor-period=2s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;node-monitor-grace-period=16s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubeletConfiguration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeStatusUpdateFrequency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;4s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# etcd:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# type: kubekey&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;calico&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;calico&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ipipMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Always&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;vxianMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Never&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;vethMTU&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1440&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubePodsCIDR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10.233.64.0&lt;/span&gt;&lt;span class="l"&gt;/18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubeServiceCIDR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10.233.0.0&lt;/span&gt;&lt;span class="l"&gt;/18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## multus support. https://github.com/k8snetworkplumbingwg/multus-cni&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;multusCNI&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;harbor&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cr.harbor.kubekey.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;admin&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Harbor12345&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;privateRegistry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cr.harbor.kubekey.com&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespaceOverride&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;kubesphereio&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registryMirrors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecureRegistries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cr.harbor.kubekey.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;addons&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;installer.kubesphere.io/v1alpha1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterConfiguration&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ks-installer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubesphere-system&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persistence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;authentication&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jwtSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;zone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;local_registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace_override&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# dev_tag: &amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;etcd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;monitoring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpointIps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;localhost&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2379&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tlsEnable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;common&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;core&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enableMultiLogin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;30880&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NodePort&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# apiserver:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# controllerManager:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;2Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;108&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;openldap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;109&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;110&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;2Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;111&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;minio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;112&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;20Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;113&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;monitoring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;114&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# type: external&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;115&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://prometheus-operated.kubesphere-monitoring-system.svc:9090&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;116&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;GPUMonitoring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;117&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;118&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;119&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kinds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;120&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;resourceName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;nvidia.com/gpu&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;121&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resourceType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;GPU&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;122&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;123&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;es&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;124&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# master:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;125&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# volumeSize: 4Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;126&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;127&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;128&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# data:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;129&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# volumeSize: 20Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;130&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;131&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;132&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logMaxAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;133&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;elkPrefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;logstash&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;134&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;basicAuth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;135&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;136&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;137&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;138&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;externalElasticsearchHost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;139&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;externalElasticsearchPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;140&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;alerting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;141&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;142&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# thanosruler:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;143&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;144&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;145&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auditing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;146&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;147&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# operator:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;148&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;149&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# webhook:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;150&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;151&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;devops&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;152&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;153&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;154&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jenkinsMemoryLim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;8Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;155&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jenkinsMemoryReq&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;4Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;156&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jenkinsVolumeSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;8Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;157&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;158&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;159&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# operator:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;160&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;161&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# exporter:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;162&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;163&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ruler:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;164&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# enabled: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;165&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;166&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;167&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;168&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;169&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logsidecar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;170&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;171&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;172&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;173&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics_server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;174&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;175&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;monitoring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;176&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;177&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;node_exporter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;178&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;179&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;180&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# kube_rbac_proxy:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;181&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;182&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# kube_state_metrics:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;183&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;184&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# prometheus:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;185&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;186&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# volumeSize: 20Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;187&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;188&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# operator:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;189&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;190&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# alertmanager:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;191&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;192&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;193&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# notification_manager:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;194&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;195&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# operator:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;196&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;197&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# proxy:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;198&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;199&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;200&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nvidia_dcgm_exporter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;201&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;202&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;203&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;multicluster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;204&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;clusterRole&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;none&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;205&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;206&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;networkpolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;207&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;208&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ippool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;209&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;none&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;210&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;topology&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;211&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;none&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;212&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;openpitrix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;213&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;214&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;215&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;servicemesh&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;216&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;217&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;istio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;218&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;219&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ingressGateways&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;220&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;istio-ingressgateway&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;221&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;222&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cni&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;223&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;224&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;edgeruntime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;225&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;226&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubeedge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;227&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;228&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudCore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;229&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudHub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;230&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;advertiseAddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;231&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;232&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;233&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudhubNodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30000&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;234&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudhubQuicNodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30001&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;235&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudhubHttpsNodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30002&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;236&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudstreamNodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30003&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;237&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tunnelNodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30004&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;238&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;239&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# hostNetWork: false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;240&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;iptables-manager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;241&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;242&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;external&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;243&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;244&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# edgeService:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;245&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;246&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;terminal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;247&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="repo에서-각-node-접속을-위해-id_rsa_multipass-파일-복사"&gt;
 Repo에서 각 Node 접속을 위해 &lt;code&gt;id_rsa_multipass&lt;/code&gt; 파일 복사
 &lt;a class="heading-anchor" href="#repo%ec%97%90%ec%84%9c-%ea%b0%81-node-%ec%a0%91%ec%86%8d%ec%9d%84-%ec%9c%84%ed%95%b4-id_rsa_multipass-%ed%8c%8c%ec%9d%bc-%eb%b3%b5%ec%82%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass copy-files &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.ssh/id_rsa_multipass kk-repo:/home/ubuntu/.ssh/id_rsa_multipass&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="registry-설치"&gt;
 Registry 설치
 &lt;a class="heading-anchor" href="#registry-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk init registry -f config-v1.29.3.yaml -a artifact-3.1.1.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;harbor 주소 : [harbor 설치한 ip]:80
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[ERROR] ssh error&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;각 node 별로 ssh가 안될시 root passwd가 맞지 않아 발생함.&lt;/li&gt;
&lt;li&gt;Multipass에서 vm이 생성되면 root 비번을 설정해줘야 하는 듯&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo passwd root&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-danger }&lt;/p&gt;
&lt;h3 id="harbor-인증서-복사-및-업데이트-harbor-curl-60-ssl-certificate-problem-unable-to-get-local-issuer-certificate"&gt;
 Harbor 인증서 복사 및 업데이트 (&lt;code&gt;harbor curl: (60) SSL certificate problem: unable to get local issuer certificate&lt;/code&gt;)
 &lt;a class="heading-anchor" href="#harbor-%ec%9d%b8%ec%a6%9d%ec%84%9c-%eb%b3%b5%ec%82%ac-%eb%b0%8f-%ec%97%85%eb%8d%b0%ec%9d%b4%ed%8a%b8-harbor-curl-60-ssl-certificate-problem-unable-to-get-local-issuer-certificate" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;인증서 업데이트를 하지 않았을 시, 아래와 같이 Error&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[WARNING ImagePull]: failed to pull image cr.harbor.kubekey.com/kubesphereio/kube-apiserver:v1.29.3: output: E0501 22:53:12.616927 4525 remote_image.go:180] &amp;#34;PullImage from image service failed&amp;#34; err=&amp;#34;rpc error: code = Unknown desc = failed to pull and unpack image \&amp;#34;cr.harbor.kubekey.com/kubesphereio/kube-apiserver:v1.29.3\&amp;#34;: failed to resolve reference \&amp;#34;cr.harbor.kubekey.com/kubesphereio/kube-apiserver:v1.29.3\&amp;#34;: failed to do request: Head \&amp;#34;https://cr.harbor.kubekey.com:443/v2/kubesphereio/kube-apiserver/manifests/v1.29.3\&amp;#34;: tls: failed to verify certificate: x509: certificate signed by unknown authority&amp;#34; image=&amp;#34;cr.harbor.kubekey.com/kubesphereio/kube-apiserver:v1.29.3&amp;#34;
time=&amp;#34;2025-05-01T22:53:12+09:00&amp;#34; level=fatal msg=&amp;#34;pulling image: failed to pull and unpack image \&amp;#34;cr.harbor.kubekey.com/kubesphereio/kube-apiserver:v1.29.3\&amp;#34;: failed to resolve reference \&amp;#34;cr.harbor.kubekey.com/kubesphereio/kube-apiserver:v1.29.3\&amp;#34;: failed to do request: Head \&amp;#34;https://cr.harbor.kubekey.com:443/v2/kubesphereio/kube-apiserver/manifests/v1.29.3\&amp;#34;: tls: failed to verify certificate: x509: certificate signed by unknown authority&amp;#34;
, error: exit status 1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;{: .prompt-danger }&lt;/p&gt;
&lt;h4 id="repo-및-각-node의-인증서-복사"&gt;
 Repo 및 각 Node의 인증서 복사
 &lt;a class="heading-anchor" href="#repo-%eb%b0%8f-%ea%b0%81-node%ec%9d%98-%ec%9d%b8%ec%a6%9d%ec%84%9c-%eb%b3%b5%ec%82%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo cp /etc/docker/certs.d/cr.harbor.kubekey.com/ca.crt /usr/local/share/ca-certificates/harbor-ca.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo scp -i /home/ubuntu/.ssh/id_rsa_multipass /usr/local/share/ca-certificates/harbor-ca.crt root@192.168.0.101:/usr/local/share/ca-certificates/harbor-ca.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo scp -i /home/ubuntu/.ssh/id_rsa_multipass /usr/local/share/ca-certificates/harbor-ca.crt root@192.168.0.102:/usr/local/share/ca-certificates/harbor-ca.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;sudo scp -i /home/ubuntu/.ssh/id_rsa_multipass /usr/local/share/ca-certificates/harbor-ca.crt root@192.168.0.103:/usr/local/share/ca-certificates/harbor-ca.crt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="각-node-별로-인증서-업데이트"&gt;
 각 Node 별로 인증서 업데이트
 &lt;a class="heading-anchor" href="#%ea%b0%81-node-%eb%b3%84%eb%a1%9c-%ec%9d%b8%ec%a6%9d%ec%84%9c-%ec%97%85%eb%8d%b0%ec%9d%b4%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo update-ca-certificates&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="인증서-적용-확인"&gt;
 인증서 적용 확인
 &lt;a class="heading-anchor" href="#%ec%9d%b8%ec%a6%9d%ec%84%9c-%ec%a0%81%ec%9a%a9-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ls -lrt /etc/ssl/certs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;- harbor-ca.pem -&amp;gt; /usr/local/share/ca-certificates/harbor-ca.crt
- ca-certificates.crt&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="container-restart"&gt;
 Container Restart
 &lt;a class="heading-anchor" href="#container-restart" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl restart containerd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="harbor-project-생성"&gt;
 Harbor Project 생성
 &lt;a class="heading-anchor" href="#harbor-project-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="sample-bash-파일-다운로드"&gt;
 Sample Bash 파일 다운로드
 &lt;a class="heading-anchor" href="#sample-bash-%ed%8c%8c%ec%9d%bc-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -O https://raw.githubusercontent.com/kubesphere/ks-installer/master/scripts/create_project_harbor.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="harbor-프로젝트-수정-및-url-수정"&gt;
 Harbor 프로젝트 수정 및 url 수정(&lt;a href="https://dockerhub.kubekey.local"&gt;https://dockerhub.kubekey.local&lt;/a&gt;)
 &lt;a class="heading-anchor" href="#harbor-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%88%98%ec%a0%95-%eb%b0%8f-url-%ec%88%98%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;파일 편집&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi create_project_harbor.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;url 수정(&lt;a href="https://dockerhub.kubekey.local"&gt;https://dockerhub.kubekey.local&lt;/a&gt;)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Copyright 2018 The KubeSphere Authors.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Licensed under the Apache License, Version 2.0 (the &amp;#34;License&amp;#34;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# you may not use this file except in compliance with the License.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# You may obtain a copy of the License at&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# http://www.apache.org/licenses/LICENSE-2.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Unless required by applicable law or agreed to in writing, software&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# distributed under the License is distributed on an &amp;#34;AS IS&amp;#34; BASIS,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# See the License for the specific language governing permissions and&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# limitations under the License.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://cr.harbor.kubekey.com&amp;#34;&lt;/span&gt; &lt;span class="c1"&gt;#Change the value of url to https://cr.harbor.kubekey.com.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;passwd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Harbor12345&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;harbor_projects&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;library
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; kubesphereio
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; kubesphere
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; argoproj
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; calico
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; coredns
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; openebs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; csiplugin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; minio
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; mirrorgooglecontainers
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt; osixia
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt; prom
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt; thanosio
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt; jimmidyson
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt; grafana
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt; elastic
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt; istio
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt; jaegertracing
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt; jenkins
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt; weaveworks
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt; openpitrix
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt; joosthofman
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt; nginxdemos
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt; fluent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt; kubeedge
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt; openpolicyagent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; project in &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;harbor_projects&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;creating &lt;/span&gt;&lt;span class="nv"&gt;$project&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt; curl -u &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;passwd&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -X POST -H &lt;span class="s2"&gt;&amp;#34;Content-Type: application/json&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/api/v2.0/projects&amp;#34;&lt;/span&gt; -d &lt;span class="s2"&gt;&amp;#34;{ \&amp;#34;project_name\&amp;#34;: \&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;project&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\&amp;#34;, \&amp;#34;public\&amp;#34;: true}&amp;#34;&lt;/span&gt; -k &lt;span class="c1"&gt;#Add -k at the end of the curl command.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="파일-권한-변경"&gt;
 파일 권한 변경
 &lt;a class="heading-anchor" href="#%ed%8c%8c%ec%9d%bc-%ea%b6%8c%ed%95%9c-%eb%b3%80%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chmod +x create_project_harbor.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="실행"&gt;
 실행
 &lt;a class="heading-anchor" href="#%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;./create_project_harbor.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="cluster-설치"&gt;
 Cluster 설치
 &lt;a class="heading-anchor" href="#cluster-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk create cluster -f config-v1.29.3.yaml -a artifact-3.1.1.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Install operating system packages&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk create cluster -f config-v1.29.3.yaml -a artifact-3.1.1.tar.gz --with-packages&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-tip }&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;image 별도로 push 방법&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk artifact image push -f config-v1.29.3.yaml -a artifact-3.1.1.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-tip }&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;--skip-push-images&lt;/code&gt;를 추가하면 harbor에 image를 push하는 과정으로 생략할 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk create cluster -f config-v1.29.3.yaml -a artifact-3.1.1.tar.gz --skip-push-images&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-tip }&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[ERROR] Harbor에 image push 할 때 Unauthorized 에러 발생 때&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;다시 로그인&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker login &lt;span class="o"&gt;[&lt;/span&gt;your.host.com&lt;span class="o"&gt;]&lt;/span&gt;:port -u username -p password
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo docker login https://cr.harbor.kubekey.com -u admin -p Harbor12345&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-danger }&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;kubekey command 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/kubekey/blob/master/docs/commands/kk-upgrade.md"&gt;https://github.com/kubesphere/kubekey/blob/master/docs/commands/kk-upgrade.md&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="cluster-설치하면서-log-확인"&gt;
 Cluster 설치하면서 log 확인
 &lt;a class="heading-anchor" href="#cluster-%ec%84%a4%ec%b9%98%ed%95%98%eb%a9%b4%ec%84%9c-log-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl logs -n kubesphere-system &lt;span class="k"&gt;$(&lt;/span&gt;kubectl get pod -n kubesphere-system -l &lt;span class="s1"&gt;&amp;#39;app in (ks-install, ks-installer)&amp;#39;&lt;/span&gt; -o &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{.items[0].metadata.name}&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt; -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="kubernetes-일반-유저-일-때"&gt;
 Kubernetes 일반 유저 일 때
 &lt;a class="heading-anchor" href="#kubernetes-%ec%9d%bc%eb%b0%98-%ec%9c%a0%ec%a0%80-%ec%9d%bc-%eb%95%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mkdir -p &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo cp -i /etc/kubernetes/admin.conf &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo chown &lt;span class="k"&gt;$(&lt;/span&gt;id -u&lt;span class="k"&gt;)&lt;/span&gt;:&lt;span class="k"&gt;$(&lt;/span&gt;id -g&lt;span class="k"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;만약 일반 계정에서 아래와 sudo 명령어 없이 kubectl 명령어 사용시 아래와 같은 오류가 발생하면&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;[ERROR] error loading config file &lt;code&gt;/etc/kubernetes/admin.conf&lt;/code&gt;: open /etc/kubernetes/admin.conf: permission denied
&lt;ul&gt;
&lt;li&gt;아래 명령어를 입력하면 sudo 없이 사용 가능하다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;{: .prompt-danger }&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[ERROR] error making pod data directories: mkdir /var/lib/kubelet/pods/86cfe394-ba32-4a9f-ad65-1fb21f98a4ba: read-only file system&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chown -R kubelet:kubelet /var/lib/kubelet/pods
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;750&lt;/span&gt; /var/lib/kubelet/pods
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;systemctl restart kubelet&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-danger }&lt;/p&gt;
&lt;h3 id="cluster-설치-완료"&gt;
 Cluster 설치 완료
 &lt;a class="heading-anchor" href="#cluster-%ec%84%a4%ec%b9%98-%ec%99%84%eb%a3%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#####################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;### Welcome to KubeSphere! ###&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#####################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;Console: http://192.168.0.101:30880
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;Account: admin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;Password: P@88w0rd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;NOTES：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; 1. After you log into the console, please check the
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; monitoring status of service components in
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Cluster Management&amp;#34;&lt;/span&gt;. If any service is not
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; ready, please &lt;span class="nb"&gt;wait&lt;/span&gt; patiently &lt;span class="k"&gt;until&lt;/span&gt; all components
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; are up and running.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; 2. Please change the default password after login.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#####################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;https://kubesphere.io 2025-05-01 22:32:53
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#####################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;22:32:54 KST success: &lt;span class="o"&gt;[&lt;/span&gt;kk-master&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;22:32:54 KST Pipeline&lt;span class="o"&gt;[&lt;/span&gt;CreateClusterPipeline&lt;span class="o"&gt;]&lt;/span&gt; execute successfully
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;Installation is complete.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;Please check the result using the command:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; kubectl logs -n kubesphere-system &lt;span class="k"&gt;$(&lt;/span&gt;kubectl get pod -n kubesphere-system -l &lt;span class="s1"&gt;&amp;#39;app in (ks-install, ks-installer)&amp;#39;&lt;/span&gt; -o &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{.items[0].metadata.name}&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt; -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="설치-후-이상-증세"&gt;
 설치 후, 이상 증세
 &lt;a class="heading-anchor" href="#%ec%84%a4%ec%b9%98-%ed%9b%84-%ec%9d%b4%ec%83%81-%ec%a6%9d%ec%84%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="cluster-재시작-이후-연결이-되지-않을-때"&gt;
 Cluster 재시작 이후, 연결이 되지 않을 때
 &lt;a class="heading-anchor" href="#cluster-%ec%9e%ac%ec%8b%9c%ec%9e%91-%ec%9d%b4%ed%9b%84-%ec%97%b0%ea%b2%b0%ec%9d%b4-%eb%90%98%ec%a7%80-%ec%95%8a%ec%9d%84-%eb%95%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Unable to connect to the server: dial tcp: lookup lb.kubesphere.local on 127.0.0.53:53: server misbehaving&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;kk-master, kk-worker-1, kk-worker-2 각 Node의 &lt;code&gt;/etc/hosts&lt;/code&gt; 수정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo vi /etc/hosts&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;아래와 같이 추가&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;192.168.0.100 cr.harbor.kubekey.com&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;192.168.0.101 lb.kubesphere.local&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Your system has configured &amp;#39;manage_etc_hosts&amp;#39; as True.
# As a result, if you wish for changes to this file to persist
# then you will need to either
# a.) make changes to the master file in /etc/cloud/templates/hosts.debian.tmpl
# b.) change or remove the value of &amp;#39;manage_etc_hosts&amp;#39; in
# /etc/cloud/cloud.cfg or cloud-config from user-data
#
127.0.1.1 kk-worker-1 kk-worker-1
127.0.0.1 localhost

## 추가
192.168.0.100 cr.harbor.kubekey.com
192.168.0.101 lb.kubesphere.local
##

# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="다만-재시작하면-다시-초기화-됨"&gt;
 다만, 재시작하면 다시 초기화 됨
 &lt;a class="heading-anchor" href="#%eb%8b%a4%eb%a7%8c-%ec%9e%ac%ec%8b%9c%ec%9e%91%ed%95%98%eb%a9%b4-%eb%8b%a4%ec%8b%9c-%ec%b4%88%ea%b8%b0%ed%99%94-%eb%90%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/etc/cloud/templates/hosts.debian.tmpl&lt;/code&gt; 해당 파일을 수정해야 다시 시작하더라도 변경됨&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo vi /etc/cloud/templates/hosts.debian.tmpl&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;아래와 같이 추가&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;192.168.0.100 cr.harbor.kubekey.com&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;192.168.0.101 lb.kubesphere.local&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Your system has configured &amp;#39;manage_etc_hosts&amp;#39; as True.
# As a result, if you wish for changes to this file to persist
# then you will need to either
# a.) make changes to the master file in /etc/cloud/templates/hosts.debian.tmpl
# b.) change or remove the value of &amp;#39;manage_etc_hosts&amp;#39; in
# /etc/cloud/cloud.cfg or cloud-config from user-data
#
127.0.1.1 kk-worker-1 kk-worker-1
127.0.0.1 localhost

## 추가
192.168.0.100 cr.harbor.kubekey.com
192.168.0.101 lb.kubesphere.local
##

# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="harbor-login-실패-또는-cluster에서-image를-가져오지-못할-때"&gt;
 Harbor Login 실패 또는 Cluster에서 Image를 가져오지 못할 때
 &lt;a class="heading-anchor" href="#harbor-login-%ec%8b%a4%ed%8c%a8-%eb%98%90%eb%8a%94-cluster%ec%97%90%ec%84%9c-image%eb%a5%bc-%ea%b0%80%ec%a0%b8%ec%98%a4%ec%a7%80-%eb%aa%bb%ed%95%a0-%eb%95%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;아래와 같이 docker-compose 재시작&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo -i
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /opt/harbor
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;docker-compose restart&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] CIS Benchmark와 kube-bench 소개</title><link>https://kyungryeol-yoon.github.io/kubernetes/security/kube-bench/</link><pubDate>Wed, 09 Apr 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/security/kube-bench/</guid><description>&lt;h2 id="-cis-kubernetes-benchmark와-kube-bench란"&gt;
 🔒 CIS Kubernetes Benchmark와 kube-bench란?
 &lt;a class="heading-anchor" href="#-cis-kubernetes-benchmark%ec%99%80-kube-bench%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;쿠버네티스 클러스터의 &lt;strong&gt;보안 상태를 점검하고 규정을 준수&lt;/strong&gt;하기 위한 도구와 기준입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-cis란"&gt;
 1️⃣ CIS란?
 &lt;a class="heading-anchor" href="#1-cis%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CIS (Center for Internet Security)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;전 세계적으로 보안 벤치마크와 가이드를 제공하는 기관&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;쿠버네티스용 &lt;strong&gt;CIS Kubernetes Benchmark&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;클러스터 설정이 보안 기준을 만족하는지 점검&lt;/li&gt;
&lt;li&gt;점검 항목 예: 인증, RBAC, 네트워크 정책, etcd 암호화 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="2-kube-bench란"&gt;
 2️⃣ kube-bench란?
 &lt;a class="heading-anchor" href="#2-kube-bench%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;kube-bench&lt;/strong&gt; = CIS Kubernetes Benchmark 체크 자동화 도구&lt;/li&gt;
&lt;li&gt;제공: &lt;strong&gt;Aqua Security (aquasec/kube-bench)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;역할:
&lt;ul&gt;
&lt;li&gt;쿠버네티스 클러스터 검사&lt;/li&gt;
&lt;li&gt;CIS 기준 준수 여부 확인&lt;/li&gt;
&lt;li&gt;마스터/워커 노드, 컨트롤 플레인 구성 체크&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="3-설치-및-실행-예시"&gt;
 3️⃣ 설치 및 실행 예시
 &lt;a class="heading-anchor" href="#3-%ec%84%a4%ec%b9%98-%eb%b0%8f-%ec%8b%a4%ed%96%89-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Docker로 실행&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;docker run --rm --net host --pid host --userns host &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; -v /etc:/etc:ro -v /var:/var:ro -v /usr/bin:/usr/local/bin:ro &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; aquasec/kube-bench:latest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;검사 결과: &lt;strong&gt;PASS / WARN / FAIL&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PASS&lt;/code&gt;: 보안 기준 준수&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WARN&lt;/code&gt;: 권장하지만 필수 아님&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FAIL&lt;/code&gt;: 보안 위험 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="4-사용-목적"&gt;
 4️⃣ 사용 목적
 &lt;a class="heading-anchor" href="#4-%ec%82%ac%ec%9a%a9-%eb%aa%a9%ec%a0%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;쿠버네티스 클러스터 &lt;strong&gt;보안 점검&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;CIS Benchmark 기준 &lt;strong&gt;규정 준수 확인&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;DevSecOps 환경에서 &lt;strong&gt;자동화된 감사&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="5-요약"&gt;
 5️⃣ 요약
 &lt;a class="heading-anchor" href="#5-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;내용&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;CIS&lt;/td&gt;
					&lt;td&gt;Center for Internet Security, 보안 벤치마크 제공 기관&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;kube-bench&lt;/td&gt;
					&lt;td&gt;CIS Kubernetes Benchmark 자동 검사 도구 (AquaSec)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;용도&lt;/td&gt;
					&lt;td&gt;클러스터 보안 점검, 규정 준수 확인, DevSecOps&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;출력&lt;/td&gt;
					&lt;td&gt;PASS / WARN / FAIL&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 한 줄 요약:
&lt;strong&gt;kube-bench = 쿠버네티스 클러스터를 CIS 보안 기준으로 “건강검진” 해주는 도구&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Docker-Compose] Install Docker-Compose(2.33.1)</title><link>https://kyungryeol-yoon.github.io/docker/install-docker-compose2.33.1/</link><pubDate>Wed, 12 Mar 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/docker/install-docker-compose2.33.1/</guid><description>&lt;h2 id="도커-docker-설치"&gt;
 도커 (Docker) 설치
 &lt;a class="heading-anchor" href="#%eb%8f%84%ec%bb%a4-docker-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="시스템-업데이트"&gt;
 시스템 업데이트
 &lt;a class="heading-anchor" href="#%ec%8b%9c%ec%8a%a4%ed%85%9c-%ec%97%85%eb%8d%b0%ec%9d%b4%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get update -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get upgrade -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="의존성-패키지-설치"&gt;
 의존성 패키지 설치
 &lt;a class="heading-anchor" href="#%ec%9d%98%ec%a1%b4%ec%84%b1-%ed%8c%a8%ed%82%a4%ec%a7%80-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt install apt-transport-https ca-certificates curl software-properties-common -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="도커-gpg-키-추가"&gt;
 도커 GPG 키 추가
 &lt;a class="heading-anchor" href="#%eb%8f%84%ec%bb%a4-gpg-%ed%82%a4-%ec%b6%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -fsSL https://download.docker.com/linux/ubuntu/gpg &lt;span class="p"&gt;|&lt;/span&gt; sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="도커-레포지토리-설정"&gt;
 도커 레포지토리 설정
 &lt;a class="heading-anchor" href="#%eb%8f%84%ec%bb%a4-%eb%a0%88%ed%8f%ac%ec%a7%80%ed%86%a0%eb%a6%ac-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deb [arch=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;dpkg --print-architecture&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;lsb_release -cs&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; stable&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="도커-설치"&gt;
 도커 설치
 &lt;a class="heading-anchor" href="#%eb%8f%84%ec%bb%a4-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo apt install docker-ce docker-ce-cli containerd.io&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="도커-시작-및-활성화"&gt;
 도커 시작 및 활성화
 &lt;a class="heading-anchor" href="#%eb%8f%84%ec%bb%a4-%ec%8b%9c%ec%9e%91-%eb%b0%8f-%ed%99%9c%ec%84%b1%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl start docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; docker&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="도커-상태-확인"&gt;
 도커 상태 확인
 &lt;a class="heading-anchor" href="#%eb%8f%84%ec%bb%a4-%ec%83%81%ed%83%9c-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl status docker&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="도커-컴포즈-docker-compose-설치"&gt;
 도커 컴포즈 (Docker-Compose) 설치
 &lt;a class="heading-anchor" href="#%eb%8f%84%ec%bb%a4-%ec%bb%b4%ed%8f%ac%ec%a6%88-docker-compose-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="도커-컴포즈-다운로드-및-설치"&gt;
 도커 컴포즈 다운로드 및 설치
 &lt;a class="heading-anchor" href="#%eb%8f%84%ec%bb%a4-%ec%bb%b4%ed%8f%ac%ec%a6%88-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c-%eb%b0%8f-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo curl -L &lt;span class="s2"&gt;&amp;#34;https://github.com/docker/compose/releases/download/v2.33.1/docker-compose-&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;uname -s&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;uname -m&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -o /usr/local/bin/docker-compose&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="도커-컴포즈-실행-권한-부여"&gt;
 도커 컴포즈 실행 권한 부여
 &lt;a class="heading-anchor" href="#%eb%8f%84%ec%bb%a4-%ec%bb%b4%ed%8f%ac%ec%a6%88-%ec%8b%a4%ed%96%89-%ea%b6%8c%ed%95%9c-%eb%b6%80%ec%97%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo chmod +x /usr/local/bin/docker-compose&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="도커-컴포즈-설치-확인"&gt;
 도커 컴포즈 설치 확인
 &lt;a class="heading-anchor" href="#%eb%8f%84%ec%bb%a4-%ec%bb%b4%ed%8f%ac%ec%a6%88-%ec%84%a4%ec%b9%98-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker-compose --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="도커-컴포즈-curl-오류-발생-시"&gt;
 도커 컴포즈 CURL 오류 발생 시
 &lt;a class="heading-anchor" href="#%eb%8f%84%ec%bb%a4-%ec%bb%b4%ed%8f%ac%ec%a6%88-curl-%ec%98%a4%eb%a5%98-%eb%b0%9c%ec%83%9d-%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;우분투 22.04 서버에서 도커 컴포즈 &lt;code&gt;CURL&lt;/code&gt; 설치 시 아래와 같은 오류가 발생하는 경우가 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="오류-코드를-살펴보면-아래와-같다"&gt;
 오류 코드를 살펴보면 아래와 같다.
 &lt;a class="heading-anchor" href="#%ec%98%a4%eb%a5%98-%ec%bd%94%eb%93%9c%eb%a5%bc-%ec%82%b4%ed%8e%b4%eb%b3%b4%eb%a9%b4-%ec%95%84%eb%9e%98%ec%99%80-%ea%b0%99%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Failed to create the file /usr/local/bin/docker-compose: No such file or directory
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;curl: &lt;span class="o"&gt;(&lt;/span&gt;23&lt;span class="o"&gt;)&lt;/span&gt; Failure writing output to destination 오류 발생&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;위 오류는 설치하려는 대상 디렉토리인 &lt;code&gt;/usr/local/bin&lt;/code&gt; 폴더가 없어서 나는 오류이므로 폴더를 만들어주면 간단히 해결된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="usrlocalbin-폴더-생성"&gt;
 &lt;code&gt;/usr/local/bin&lt;/code&gt; 폴더 생성
 &lt;a class="heading-anchor" href="#usrlocalbin-%ed%8f%b4%eb%8d%94-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo mkdir -p /usr/local/bin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;이후 다시 &lt;code&gt;CURL&lt;/code&gt; 명령어를 실행하면 잘 설치가 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="도커-권한-부여"&gt;
 도커 권한 부여
 &lt;a class="heading-anchor" href="#%eb%8f%84%ec%bb%a4-%ea%b6%8c%ed%95%9c-%eb%b6%80%ec%97%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;도커를 &lt;code&gt;sudo&lt;/code&gt; 없이 실행시키려면 아래 명령어를 통해 모든 유저가 도커에 접근할 수 있도록 해주면 된다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo chmod &lt;span class="m"&gt;666&lt;/span&gt; /var/run/docker.sock&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;위 명령어를 실행하면 &lt;code&gt;super user&lt;/code&gt;가 아니더라도 &lt;code&gt;sudo&lt;/code&gt; 없이 실행할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Kafbat - Kafka UI(1.1.0)</title><link>https://kyungryeol-yoon.github.io/data-streaming/kafka/kubernetes-install-kafbat-ui1.1.0/</link><pubDate>Sat, 08 Mar 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/data-streaming/kafka/kubernetes-install-kafbat-ui1.1.0/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="add-repo-the-helm-charts"&gt;
 Add Repo the Helm charts
 &lt;a class="heading-anchor" href="#add-repo-the-helm-charts" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo add kafbat-ui https://kafbat.github.io/helm-charts&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="values-수정---kafka-연결-세팅"&gt;
 values 수정 - kafka 연결 세팅
 &lt;a class="heading-anchor" href="#values-%ec%88%98%ec%a0%95---kafka-%ec%97%b0%ea%b2%b0-%ec%84%b8%ed%8c%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;yamlApplicationConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kafka&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;clusters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;yaml&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bootstrapServers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kafka-cluster-broker-endpoints:9092&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;disabled&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;management&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;health&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ldap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="values-수정---nodeport-설정"&gt;
 values 수정 - NodePort 설정
 &lt;a class="heading-anchor" href="#values-%ec%88%98%ec%a0%95---nodeport-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;yamlApplicationConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kafka&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;clusters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;yaml&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bootstrapServers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;disabled&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;management&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;health&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ldap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## @param service.type Kafka-UI service type&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NodePort&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## @param service.port Kafka-UI pod port number&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# In case of service type LoadBalancer, you can specify reserved static IP&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# loadBalancerIP: 10.11.12.13&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# if you want to force a specific nodePort. Must be use with service.type=NodePort&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;30092&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="install-kafka-ui"&gt;
 Install kafka UI
 &lt;a class="heading-anchor" href="#install-kafka-ui" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE&lt;span class="o"&gt;]&lt;/span&gt; kafbat-ui kafbat-ui/kafka-ui -f values.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;kafbat helm 참고 - &lt;a href="https://github.com/kafbat/helm-charts"&gt;https://github.com/kafbat/helm-charts&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE&lt;span class="o"&gt;]&lt;/span&gt; kafka-ui charts/kafka-ui -f charts/kafka-ui/values.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-info }&lt;/p&gt;</description></item><item><title>[Kubernetes] Strimzi Operator(0.45.0)</title><link>https://kyungryeol-yoon.github.io/data-streaming/kafka/kubernetes-install-strimzi-operator0.45.0/</link><pubDate>Sat, 08 Mar 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/data-streaming/kafka/kubernetes-install-strimzi-operator0.45.0/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="설치-방법"&gt;
 설치 방법
 &lt;a class="heading-anchor" href="#%ec%84%a4%ec%b9%98-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Operator Yaml (&lt;code&gt;strimzi-cluster-operator-0.45.0.yaml&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Helm (&lt;code&gt;strimzi-kafka-operator-helm-3-chart-0.45.0.tgz&lt;/code&gt;)
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/strimzi/strimzi-kafka-operator/tree/main/helm-charts/helm3/strimzi-kafka-operator"&gt;https://github.com/strimzi/strimzi-kafka-operator/tree/main/helm-charts/helm3/strimzi-kafka-operator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;cluster-operator Yaml 파일 (&lt;a href="https://github.com/strimzi/strimzi-kafka-operator/tree/main/install/cluster-operator"&gt;https://github.com/strimzi/strimzi-kafka-operator/tree/main/install/cluster-operator&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Strimzi Release 참고 - &lt;a href="https://github.com/strimzi/strimzi-kafka-operator/releases"&gt;https://github.com/strimzi/strimzi-kafka-operator/releases&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="operator-yaml로-설치"&gt;
 Operator Yaml로 설치
 &lt;a class="heading-anchor" href="#operator-yaml%eb%a1%9c-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="namespace-kafka에-설치"&gt;
 Namespace kafka에 설치
 &lt;a class="heading-anchor" href="#namespace-kafka%ec%97%90-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create -f &lt;span class="s1"&gt;&amp;#39;https://strimzi.io/install/latest?namespace=kafka&amp;#39;&lt;/span&gt; -n kafka&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="특정-namespace-또는-여러-namespace-관리"&gt;
 특정 Namespace 또는 여러 Namespace 관리
 &lt;a class="heading-anchor" href="#%ed%8a%b9%ec%a0%95-namespace-%eb%98%90%eb%8a%94-%ec%97%ac%eb%9f%ac-namespace-%ea%b4%80%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;watchNamespaces&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;특정 Namespace에서만 Resource를 감시(watch)하도록 지정하는 기능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;watchAnyNamespace&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Kafka 및 관련 Resource를 관리할 때, 여러 Namespace에서 발생하는 변경 사항을 감시(watch)할 수 있도록 설정하는 옵션&lt;/li&gt;
&lt;li&gt;여러 Namespace에서 Kafka 관련 Resource의 생성, 삭제, 업데이트 등을 실시간으로 추적할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# If you set `watchNamespaces` to the same value as ``.Release.Namespace` (e.g. `helm ... --namespace $NAMESPACE`),&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# the chart will fail because duplicate RoleBindings will be attempted to be created in the same namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;watchNamespaces&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;watchAnyNamespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;values yaml 참고 - &lt;a href="https://github.com/strimzi/strimzi-kafka-operator/blob/main/helm-charts/helm3/strimzi-kafka-operator/values.yaml"&gt;https://github.com/strimzi/strimzi-kafka-operator/blob/main/helm-charts/helm3/strimzi-kafka-operator/values.yaml&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="확인"&gt;
 확인
 &lt;a class="heading-anchor" href="#%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pod -n kafka --watch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="log-확인"&gt;
 Log 확인
 &lt;a class="heading-anchor" href="#log-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl logs deployment/strimzi-cluster-operator -n kafka -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="storage-class-세팅-storage-class-및-persistentvolume-세팅이-되어-있지-않다면"&gt;
 Storage Class 세팅 (Storage Class 및 PersistentVolume 세팅이 되어 있지 않다면)
 &lt;a class="heading-anchor" href="#storage-class-%ec%84%b8%ed%8c%85-storage-class-%eb%b0%8f-persistentvolume-%ec%84%b8%ed%8c%85%ec%9d%b4-%eb%90%98%ec%96%b4-%ec%9e%88%ec%a7%80-%ec%95%8a%eb%8b%a4%eb%a9%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;StorageClass&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;storage.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local-storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;provisioner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes.io/no-provisioner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;volumeBindingMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;WaitForFirstConsumer&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="patch-storage-class"&gt;
 Patch Storage Class
 &lt;a class="heading-anchor" href="#patch-storage-class" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl patch storageclass local-storage -p &lt;span class="s1"&gt;&amp;#39;{&amp;#34;metadata&amp;#34;: {&amp;#34;annotations&amp;#34;:{&amp;#34;storageclass.kubernetes.io/is-default-class&amp;#34;:&amp;#34;true&amp;#34;}}}&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="확인-1"&gt;
 확인
 &lt;a class="heading-anchor" href="#%ed%99%95%ec%9d%b8-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get sc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;local-storage &lt;span class="o"&gt;(&lt;/span&gt;default&lt;span class="o"&gt;)&lt;/span&gt; kubernetes.io/no-provisioner Delete WaitForFirstConsumer &lt;span class="nb"&gt;false&lt;/span&gt; 3h16m&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="persistentvolume-세팅"&gt;
 PersistentVolume 세팅
 &lt;a class="heading-anchor" href="#persistentvolume-%ec%84%b8%ed%8c%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PersistentVolume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kafka-pv-volume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClassName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local-storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteOnce&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/mnt/data&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PersistentVolume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kafka-pv-volume-2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClassName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local-storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteOnce&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/mnt/data&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PersistentVolume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kafka-pv-volume-3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClassName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local-storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteOnce&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/mnt/data&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="kafka-single-node---kraft-모드"&gt;
 Kafka Single Node - kraft 모드
 &lt;a class="heading-anchor" href="#kafka-single-node---kraft-%eb%aa%a8%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="kafka-single-node-yaml-파일-수정-및-참고---kraft-모드"&gt;
 Kafka Single Node Yaml 파일 수정 및 참고 - kraft 모드
 &lt;a class="heading-anchor" href="#kafka-single-node-yaml-%ed%8c%8c%ec%9d%bc-%ec%88%98%ec%a0%95-%eb%b0%8f-%ec%b0%b8%ea%b3%a0---kraft-%eb%aa%a8%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kafka.strimzi.io/v1beta2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;KafkaNodePool&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;dual-role&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;strimzi.io/cluster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;controller&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;broker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;jbod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;persistent-claim&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;class&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local-storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;deleteClaim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kraftMetadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;shared&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kafka.strimzi.io/v1beta2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Kafka&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;strimzi.io/node-pools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;enabled&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;strimzi.io/kraft&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;enabled&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kafka&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3.9.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadataVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3.9&lt;/span&gt;-&lt;span class="l"&gt;IV0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;plain&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9092&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;internal&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tls&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9093&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;internal&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;offsets.topic.replication.factor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;transaction.state.log.replication.factor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;transaction.state.log.min.isr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;default.replication.factor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;min.insync.replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;entityOperator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;topicOperator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;userOperator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;참고 - &lt;a href="https://github.com/strimzi/strimzi-kafka-operator/tree/main/examples/kafka/kraft"&gt;https://github.com/strimzi/strimzi-kafka-operator/tree/main/examples/kafka/kraft&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="kafka-single-node-설치---kraft-모드"&gt;
 Kafka Single Node 설치 - kraft 모드
 &lt;a class="heading-anchor" href="#kafka-single-node-%ec%84%a4%ec%b9%98---kraft-%eb%aa%a8%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f https://strimzi.io/examples/latest/kafka/kraft/kafka-single-node.yaml -n kafka &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="준비될-때까지-기다리기"&gt;
 준비될 때까지 기다리기
 &lt;a class="heading-anchor" href="#%ec%a4%80%eb%b9%84%eb%90%a0-%eb%95%8c%ea%b9%8c%ec%a7%80-%ea%b8%b0%eb%8b%a4%eb%a6%ac%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;wait&lt;/span&gt; kafka/my-cluster --for&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Ready --timeout&lt;span class="o"&gt;=&lt;/span&gt;300s -n kafka &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="kafka---kraft-모드"&gt;
 Kafka - kraft 모드
 &lt;a class="heading-anchor" href="#kafka---kraft-%eb%aa%a8%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="kafka-yaml-파일-수정-및-참고---kraft-모드"&gt;
 Kafka Yaml 파일 수정 및 참고 - kraft 모드
 &lt;a class="heading-anchor" href="#kafka-yaml-%ed%8c%8c%ec%9d%bc-%ec%88%98%ec%a0%95-%eb%b0%8f-%ec%b0%b8%ea%b3%a0---kraft-%eb%aa%a8%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kafka.strimzi.io/v1beta2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;KafkaNodePool&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;controller&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;strimzi.io/cluster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;controller&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;jbod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;persistent-claim&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;100Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kraftMetadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;shared&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;deleteClaim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kafka.strimzi.io/v1beta2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;KafkaNodePool&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;broker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;strimzi.io/cluster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;broker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;jbod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;persistent-claim&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;100Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kraftMetadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;shared&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;deleteClaim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kafka.strimzi.io/v1beta2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Kafka&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;strimzi.io/node-pools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;enabled&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;strimzi.io/kraft&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;enabled&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kafka&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3.9.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadataVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3.9&lt;/span&gt;-&lt;span class="l"&gt;IV0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;plain&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9092&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;internal&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tls&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9093&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;internal&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;offsets.topic.replication.factor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;transaction.state.log.replication.factor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;transaction.state.log.min.isr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;default.replication.factor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;min.insync.replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;entityOperator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;topicOperator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;userOperator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;참고 - &lt;a href="https://github.com/strimzi/strimzi-kafka-operator/tree/main/examples/kafka/kraft"&gt;https://github.com/strimzi/strimzi-kafka-operator/tree/main/examples/kafka/kraft&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="kafka-설치---kraft-모드"&gt;
 Kafka 설치 - kraft 모드
 &lt;a class="heading-anchor" href="#kafka-%ec%84%a4%ec%b9%98---kraft-%eb%aa%a8%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f https://strimzi.io/examples/latest/kafka/kraft/kafka.yaml -n kafka &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="준비될-때까지-기다리기-1"&gt;
 준비될 때까지 기다리기
 &lt;a class="heading-anchor" href="#%ec%a4%80%eb%b9%84%eb%90%a0-%eb%95%8c%ea%b9%8c%ec%a7%80-%ea%b8%b0%eb%8b%a4%eb%a6%ac%ea%b8%b0-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;wait&lt;/span&gt; kafka/my-cluster --for&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Ready --timeout&lt;span class="o"&gt;=&lt;/span&gt;300s -n kafka &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Install Alloy(v1.7.1) Using Helm Chart</title><link>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-install-alloyv1.7.1-using-helm/</link><pubDate>Thu, 06 Mar 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-install-alloyv1.7.1-using-helm/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="install-the-helm-charts"&gt;
 Install the Helm charts
 &lt;a class="heading-anchor" href="#install-the-helm-charts" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;namespace 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create namespace &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Alloy 배포&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo add grafana https://grafana.github.io/helm-charts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;helm install --namespace &amp;lt;NAMESPACE&amp;gt; &amp;lt;RELEASE_NAME&amp;gt; grafana/alloy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Alloy - Helm 설치 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/alloy/latest/set-up/install/kubernetes/"&gt;https://grafana.com/docs/alloy/latest/set-up/install/kubernetes/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="customize-default-configuration"&gt;
 Customize Default Configuration
 &lt;a class="heading-anchor" href="#customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;values.yaml 수정&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;최상위 values.yaml을 수정하면 하위 폴더 values.yaml을 override 한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Release file (.tgz)
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana/helm-charts/releases"&gt;https://github.com/grafana/helm-charts/releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="kafka-연결"&gt;
 kafka 연결
 &lt;a class="heading-anchor" href="#kafka-%ec%97%b0%ea%b2%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;alloy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Create a new ConfigMap for the config file.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Content to assign to the new ConfigMap. This is passed into `tpl` allowing for templating from values.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; loki.source.kafka &amp;#34;raw&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; brokers = [&amp;#34;kafka:9092&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; topics = [&amp;#34;loki&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; forward_to = [loki.write.http.receiver]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; relabel_rules = loki.relabel.kafka.rules
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; version = &amp;#34;2.0.0&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; labels = {service_name = &amp;#34;raw_kafka&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; loki.relabel &amp;#34;kafka&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; forward_to = [loki.write.http.receiver]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; rule {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; source_labels = [&amp;#34;__meta_kafka_topic&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; target_label = &amp;#34;topic&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; loki.write &amp;#34;http&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; endpoint {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; url = &amp;#34;http://loki:3100/loki/api/v1/push&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Name of existing ConfigMap to use. Used when create is false.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Key in ConfigMap to get config from.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;참고 - &lt;a href="https://grafana.com/docs/loki/latest/send-data/alloy/examples/alloy-kafka-logs/"&gt;https://grafana.com/docs/loki/latest/send-data/alloy/examples/alloy-kafka-logs/&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="kafka를-통해-opentelemetry-logs-수집"&gt;
 Kafka를 통해 OpenTelemetry logs 수집
 &lt;a class="heading-anchor" href="#kafka%eb%a5%bc-%ed%86%b5%ed%95%b4-opentelemetry-logs-%ec%88%98%ec%a7%91" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;alloy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Create a new ConfigMap for the config file.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Content to assign to the new ConfigMap. This is passed into `tpl` allowing for templating from values.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; loki.source.kafka &amp;#34;raw&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; brokers = [&amp;#34;kafka:9092&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; topics = [&amp;#34;loki&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; forward_to = [loki.write.http.receiver]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; relabel_rules = loki.relabel.kafka.rules
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; version = &amp;#34;2.0.0&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; labels = {service_name = &amp;#34;raw_kafka&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; loki.relabel &amp;#34;kafka&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; forward_to = [loki.write.http.receiver]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; rule {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; source_labels = [&amp;#34;__meta_kafka_topic&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; target_label = &amp;#34;topic&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; loki.write &amp;#34;http&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; endpoint {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; url = &amp;#34;http://loki:3100/loki/api/v1/push&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; otelcol.receiver.kafka &amp;#34;default&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; brokers = [&amp;#34;kafka:9092&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; protocol_version = &amp;#34;2.0.0&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; topic = &amp;#34;otlp&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; encoding = &amp;#34;otlp_proto&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; output {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; logs = [otelcol.processor.batch.default.input]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; otelcol.processor.batch &amp;#34;default&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; output {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; logs = [otelcol.exporter.otlphttp.default.input]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; otelcol.exporter.otlphttp &amp;#34;default&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; client {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; endpoint = &amp;#34;http://loki:3100/otlp&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Name of existing ConfigMap to use. Used when create is false.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Key in ConfigMap to get config from.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;참고 - &lt;a href="https://grafana.com/docs/loki/latest/send-data/alloy/examples/alloy-kafka-logs/"&gt;https://grafana.com/docs/loki/latest/send-data/alloy/examples/alloy-kafka-logs/&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="kubernetes-pods-logs-연결"&gt;
 Kubernetes Pods logs 연결
 &lt;a class="heading-anchor" href="#kubernetes-pods-logs-%ec%97%b0%ea%b2%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;alloy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Create a new ConfigMap for the config file.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Content to assign to the new ConfigMap. This is passed into `tpl` allowing for templating from values.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; loki.write &amp;#34;http&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; endpoint {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; url = &amp;#34;http://loki:3100/loki/api/v1/push&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // discovery.kubernetes allows you to find scrape targets from Kubernetes resources.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // It watches cluster state and ensures targets are continually synced with what is currently running in your cluster.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; discovery.kubernetes &amp;#34;pod&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; role = &amp;#34;pod&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // discovery.relabel rewrites the label set of the input targets by applying one or more relabeling rules.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // If no rules are defined, then the input targets are exported as-is.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; discovery.relabel &amp;#34;pod_logs&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; targets = discovery.kubernetes.pod.targets
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // Label creation - &amp;#34;namespace&amp;#34; field from &amp;#34;__meta_kubernetes_namespace&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; rule {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; source_labels = [&amp;#34;__meta_kubernetes_namespace&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; action = &amp;#34;replace&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; target_label = &amp;#34;namespace&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // Label creation - &amp;#34;pod&amp;#34; field from &amp;#34;__meta_kubernetes_pod_name&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; rule {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; source_labels = [&amp;#34;__meta_kubernetes_pod_name&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; action = &amp;#34;replace&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; target_label = &amp;#34;pod&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // Label creation - &amp;#34;container&amp;#34; field from &amp;#34;__meta_kubernetes_pod_container_name&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; rule {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; source_labels = [&amp;#34;__meta_kubernetes_pod_container_name&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; action = &amp;#34;replace&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; target_label = &amp;#34;container&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // Label creation - &amp;#34;app&amp;#34; field from &amp;#34;__meta_kubernetes_pod_label_app_kubernetes_io_name&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; rule {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; source_labels = [&amp;#34;__meta_kubernetes_pod_label_app_kubernetes_io_name&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; action = &amp;#34;replace&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; target_label = &amp;#34;app&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // Label creation - &amp;#34;job&amp;#34; field from &amp;#34;__meta_kubernetes_namespace&amp;#34; and &amp;#34;__meta_kubernetes_pod_container_name&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // Concatenate values __meta_kubernetes_namespace/__meta_kubernetes_pod_container_name
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; rule {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; source_labels = [&amp;#34;__meta_kubernetes_namespace&amp;#34;, &amp;#34;__meta_kubernetes_pod_container_name&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; action = &amp;#34;replace&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; target_label = &amp;#34;job&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; separator = &amp;#34;/&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; replacement = &amp;#34;$1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // Label creation - &amp;#34;container&amp;#34; field from &amp;#34;__meta_kubernetes_pod_uid&amp;#34; and &amp;#34;__meta_kubernetes_pod_container_name&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // Concatenate values __meta_kubernetes_pod_uid/__meta_kubernetes_pod_container_name.log
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; rule {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; source_labels = [&amp;#34;__meta_kubernetes_pod_uid&amp;#34;, &amp;#34;__meta_kubernetes_pod_container_name&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; action = &amp;#34;replace&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; target_label = &amp;#34;__path__&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; separator = &amp;#34;/&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; replacement = &amp;#34;/var/log/pods/*$1/*.log&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // Label creation - &amp;#34;container_runtime&amp;#34; field from &amp;#34;__meta_kubernetes_pod_container_id&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; rule {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; source_labels = [&amp;#34;__meta_kubernetes_pod_container_id&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; action = &amp;#34;replace&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; target_label = &amp;#34;container_runtime&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; regex = &amp;#34;^(\\S+):\\/\\/.+$&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; replacement = &amp;#34;$1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // loki.source.kubernetes tails logs from Kubernetes containers using the Kubernetes API.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; loki.source.kubernetes &amp;#34;pod_logs&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; targets = discovery.relabel.pod_logs.output
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; forward_to = [loki.process.pod_logs.receiver]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // loki.process receives log entries from other Loki components, applies one or more processing stages,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; // and forwards the results to the list of receivers in the component&amp;#39;s arguments.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; loki.process &amp;#34;pod_logs&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; stage.static_labels {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; values = {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; cluster = &amp;#34;&amp;lt;CLUSTER_NAME&amp;gt;&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; forward_to = [loki.write.&amp;lt;WRITE_COMPONENT_NAME&amp;gt;.receiver]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Name of existing ConfigMap to use. Used when create is false.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Key in ConfigMap to get config from.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;참고 - &lt;a href="https://grafana.com/docs/alloy/latest/collect/logs-in-kubernetes/#pods-logs"&gt;https://grafana.com/docs/alloy/latest/collect/logs-in-kubernetes/#pods-logs&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="외부-접속을-위한-nodeport-설정"&gt;
 외부 접속을 위한 NodePort 설정
 &lt;a class="heading-anchor" href="#%ec%99%b8%eb%b6%80-%ec%a0%91%ec%86%8d%ec%9d%84-%ec%9c%84%ed%95%9c-nodeport-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Creates a Service for the controller&amp;#39;s pods.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Service type&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NodePort&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- NodePort port. Only takes effect when `service.type: NodePort`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;31128&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Cluster IP, can be set to None, empty &amp;#34;&amp;#34; or an IP address&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;clusterIP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Value for internal traffic policy. &amp;#39;Cluster&amp;#39; or &amp;#39;Local&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;internalTrafficPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# cloud.google.com/load-balancer-type: Internal&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="외부-접속을-위한-ingress-설정"&gt;
 외부 접속을 위한 Ingress 설정
 &lt;a class="heading-anchor" href="#%ec%99%b8%eb%b6%80-%ec%a0%91%ec%86%8d%ec%9d%84-%ec%9c%84%ed%95%9c-ingress-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;ingress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Enables ingress for Alloy (Faro port)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# For Kubernetes &amp;gt;= 1.18 you should specify the ingress-controller via the field ingressClassName&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ingressClassName: nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Values can be templated&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# kubernetes.io/ingress.class: nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# kubernetes.io/tls-acme: &amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;faroPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;12345&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# pathType is only for k8s &amp;gt;= 1.1=&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pathType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Prefix&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;chart-example.local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## Extra paths to prepend to every host configuration. This is useful when working with annotation based services.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extraPaths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - path: /*&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# backend:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# serviceName: ssl-redirect&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# servicePort: use-annotation&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## Or for k8s &amp;gt; 1.19&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - path: /*&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# pathType: Prefix&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# backend:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# service:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# name: ssl-redirect&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# port:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# name: use-annotation&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - secretName: chart-example-tls&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# hosts:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - chart-example.local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="install-customize-default-configuration"&gt;
 Install Customize Default Configuration
 &lt;a class="heading-anchor" href="#install-customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install -n &amp;lt;NAMESPACE&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;Chart.yaml 경로&lt;span class="o"&gt;]&lt;/span&gt; -f &lt;span class="o"&gt;[&lt;/span&gt;YAML 파일 또는 URL에 값 지정 &lt;span class="o"&gt;(&lt;/span&gt;여러 개를 지정가능&lt;span class="o"&gt;)]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install --namespace &amp;lt;NAMESPACE&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; grafana/alloy -f override-values.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="uninstall-the-chart"&gt;
 Uninstall the Chart
 &lt;a class="heading-anchor" href="#uninstall-the-chart" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm uninstall &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Gitlab] Back up &amp; Restore</title><link>https://kyungryeol-yoon.github.io/devops/gitlab/gitlab-backup-restore/</link><pubDate>Wed, 19 Feb 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/gitlab/gitlab-backup-restore/</guid><description>&lt;h2 id="back-up"&gt;
 Back up
 &lt;a class="heading-anchor" href="#back-up" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;gitlab-backup create&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;위 명령어를 실행하면 .tar 백업파일이 생성된다.&lt;/li&gt;
&lt;li&gt;생성된 백업파일은
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/var/opt/gitlab/backups&lt;/code&gt; 경로에 저장된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="만약-백업파일의-경로를-변경하려면"&gt;
 만약 백업파일의 경로를 변경하려면
 &lt;a class="heading-anchor" href="#%eb%a7%8c%ec%95%bd-%eb%b0%b1%ec%97%85%ed%8c%8c%ec%9d%bc%ec%9d%98-%ea%b2%bd%eb%a1%9c%eb%a5%bc-%eb%b3%80%ea%b2%bd%ed%95%98%eb%a0%a4%eb%a9%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi /etc/gitlab/gitlab.rb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="아래내용-수정"&gt;
 아래내용 수정
 &lt;a class="heading-anchor" href="#%ec%95%84%eb%9e%98%eb%82%b4%ec%9a%a9-%ec%88%98%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;gitlab_rails[&amp;#39;backup_path&amp;#39;] = &amp;#34;/var/opt/gitlab/backups&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="restore"&gt;
 Restore
 &lt;a class="heading-anchor" href="#restore" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;만약 다른 서버에 gitlab을 설치하고 복원하기를 원한다면 위에서 백업한 gitlab과 동일한 버전으로 설치하여야 한다.&lt;/li&gt;
&lt;li&gt;백업파일을 새로 gitlab을 설치한 서버의 동일한 경로에 옮긴다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="백업파일의-소유자-변경"&gt;
 백업파일의 소유자 변경
 &lt;a class="heading-anchor" href="#%eb%b0%b1%ec%97%85%ed%8c%8c%ec%9d%bc%ec%9d%98-%ec%86%8c%ec%9c%a0%ec%9e%90-%eb%b3%80%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /var/opt/gitlab/backups/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;chown git:git 1707880170_2024_02_14_16.8.1_gitlab_backup.tar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="gitlab-서비스-중단"&gt;
 gitlab 서비스 중단
 &lt;a class="heading-anchor" href="#gitlab-%ec%84%9c%eb%b9%84%ec%8a%a4-%ec%a4%91%eb%8b%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo gitlab-ctl stop puma
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo gitlab-ctl stop sidekiq
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Verify&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;sudo gitlab-ctl status&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="복원"&gt;
 복원
 &lt;a class="heading-anchor" href="#%eb%b3%b5%ec%9b%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo gitlab-backup restore &lt;span class="nv"&gt;BACKUP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;11493107454_2018_04_25_10.6.4-ce&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="재시작"&gt;
 재시작
 &lt;a class="heading-anchor" href="#%ec%9e%ac%ec%8b%9c%ec%9e%91" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo gitlab-ctl restart
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo gitlab-rake gitlab:check &lt;span class="nv"&gt;SANITIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="자동-백업구성"&gt;
 자동 백업구성
 &lt;a class="heading-anchor" href="#%ec%9e%90%eb%8f%99-%eb%b0%b1%ec%97%85%ea%b5%ac%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;시간대 확인&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;현재 서버의 시간대를 확인해서 원하는 시간에 실행되도록 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Asia/Seoul 시간대로 설정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;timedatectl set-timezone Asia/Seoul&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;reboot&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;reboot&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;crontab 설정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;crontab -e&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;# 아래 내용 추가
# 매주 수요일 00시 30분에 백업실행
30 0 * * 3 sh /opt/gitlab/bin/gitlab-backup create&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="gitlab-container-back-up--restore"&gt;
 Gitlab Container Back up &amp;amp; Restore
 &lt;a class="heading-anchor" href="#gitlab-container-back-up--restore" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="back-up-1"&gt;
 Back up
 &lt;a class="heading-anchor" href="#back-up-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; -t &amp;lt;container name&amp;gt; gitlab-backup create&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="backup-options"&gt;
 Backup options
 &lt;a class="heading-anchor" href="#backup-options" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;대부분의 경우에는 정상적으로 작동하지만, 데이터가 빠르게 변경될 때 문제가 발생할 수 있다.&lt;/li&gt;
&lt;li&gt;tar이 데이터를 읽는 도중 데이터가 변경되면 오류 file changed as we read it가 발생하여 백업 프로세스가 실패할 수 있다.
&lt;ul&gt;
&lt;li&gt;이 경우, copy라는 백업 전략을 사용할 수 있다. 이 전략은 tar와 gzip를 호출하기 전에 데이터 파일을 임시 위치로 복사하여 오류를 피한다.
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;기본 스트리밍 전략 대신 copy 전략을 사용하려면 Rake 작업 명령에 &lt;code&gt;STRATEGY=copy&lt;/code&gt;를 지정하면 된다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; -t &amp;lt;container name&amp;gt; gitlab-backup create &lt;span class="nv"&gt;STRATEGY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;copy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="back-up-파일-확인"&gt;
 Back up 파일 확인
 &lt;a class="heading-anchor" href="#back-up-%ed%8c%8c%ec%9d%bc-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/var/opt/gitlab/backups&lt;/code&gt; 경로
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[Timestamp of backup creation]_[Date (YYYY_MM_DD)]_[GitLab version]_[GitLab edition]_gitlab_backup.tar&lt;/code&gt;와 같은 형태로 백업파일이 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;gitlab 공식 문서 : &lt;a href="https://docs.gitlab.com/administration/backup_restore/backup_archive_process"&gt;https://docs.gitlab.com/administration/backup_restore/backup_archive_process&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="resotre"&gt;
 Resotre
 &lt;a class="heading-anchor" href="#resotre" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;데이터베이스에 연결된 프로세스를 중지 및 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Stop the processes that are connected to the database&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; -it &amp;lt;name of container&amp;gt; gitlab-ctl stop puma
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; -it &amp;lt;name of container&amp;gt; gitlab-ctl stop sidekiq
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Verify that the processes are all down before continuing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; -it &amp;lt;name of container&amp;gt; gitlab-ctl status&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;BACKUP 변수에 복원 대상이 되는 파일명을 기준&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;예를들어 &lt;code&gt;1493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar&lt;/code&gt; 이 파일 이름이라면 &lt;code&gt;_gitlab_backup.tar&lt;/code&gt; 의 앞부분까지의 문자열인 &lt;code&gt;1493107454_2018_04_25_10.6.4-ce&lt;/code&gt; 까지를 입력해주면 된다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Run the restore. NOTE: &amp;#34;_gitlab_backup.tar&amp;#34; is omitted from the name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; -it &amp;lt;name of container&amp;gt; gitlab-backup restore &lt;span class="nv"&gt;BACKUP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;11493107454_2018_04_25_10.6.4-ce&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;작업이 완료된 이후 Container를 재시작&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="restart"&gt;
 Restart
 &lt;a class="heading-anchor" href="#restart" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Restart the GitLab container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;docker restart &amp;lt;name of container&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Check GitLab&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; -it &amp;lt;name of container&amp;gt; gitlab-rake gitlab:check &lt;span class="nv"&gt;SANITIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Gitlab Back up : &lt;a href="https://docs.gitlab.com/administration/backup_restore"&gt;https://docs.gitlab.com/administration/backup_restore&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Gitlab Archive Process : &lt;a href="https://docs.gitlab.com/administration/backup_restore/backup_archive_process"&gt;https://docs.gitlab.com/administration/backup_restore/backup_archive_process&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Gitlab Restore : &lt;a href="https://docs.gitlab.com/administration/backup_restore/restore_gitlab"&gt;https://docs.gitlab.com/administration/backup_restore/restore_gitlab&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Redis] Save</title><link>https://kyungryeol-yoon.github.io/database/redis/redis-save/</link><pubDate>Mon, 17 Feb 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/redis/redis-save/</guid><description>&lt;ul&gt;
&lt;li&gt;Redis는 기본적으로 메모리 기반 저장소이지만, 데이터를 디스크에 저장하기 위해 &lt;code&gt;RDB&lt;/code&gt; 또는 &lt;code&gt;AOF&lt;/code&gt; 모드를 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;이를 설정 파일에서 조정하거나, &lt;code&gt;redis-cli&lt;/code&gt; 명령어를 통해 실시간으로 변경할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="redis-접속"&gt;
 Redis 접속
 &lt;a class="heading-anchor" href="#redis-%ec%a0%91%ec%86%8d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods -l &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;redis &lt;span class="c1"&gt;# redis라는 label을 가진 Pod 확인&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Redis Pod에 접속&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; -it &amp;lt;redis-pod-name&amp;gt; -- redis-cli&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="redis-저장-방식-변경"&gt;
 Redis 저장 방식 변경
 &lt;a class="heading-anchor" href="#redis-%ec%a0%80%ec%9e%a5-%eb%b0%a9%ec%8b%9d-%eb%b3%80%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Redis는 기본적으로 두 가지 방식으로 데이터를 디스크에 저장할 수 있다: &lt;strong&gt;RDB (Redis Database) snapshotting&lt;/strong&gt;과 &lt;strong&gt;AOF (Append-Only File).&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rdb-redis-database-snapshotting-방식-변경"&gt;
 RDB (Redis Database snapshotting) 방식 변경
 &lt;a class="heading-anchor" href="#rdb-redis-database-snapshotting-%eb%b0%a9%ec%8b%9d-%eb%b3%80%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;RDB는 특정 시간 간격으로 데이터를 디스크에 덤프하여 저장하는 방식이다. Redis 설정에서 &lt;code&gt;save&lt;/code&gt; 옵션을 사용하여 RDB 덤프 간격을 설정할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;현재 &lt;code&gt;save&lt;/code&gt; 설정을 확인하려면 &lt;code&gt;redis-cli&lt;/code&gt;에서 다음 명령을 입력한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;CONFIG GET save&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;RDB 설정을 변경하려면 &lt;code&gt;CONFIG SET&lt;/code&gt; 명령어를 사용하여 덤프 주기를 설정할 수 있다. 예를 들어, 60초마다 1000개의 키가 변경되면 덤프를 생성하도록 설정하려면 아래와 같이 실행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;CONFIG SET save &lt;span class="s2"&gt;&amp;#34;60 1000&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;이 설정은 &lt;strong&gt;60초 동안 1000개의 키가 변경되면 RDB 파일을 덤프&lt;/strong&gt;하도록 지정한다. 이 설정은 Redis가 동작하는 동안 지속되지 않으므로, 영구적인 변경을 원한다면 &lt;code&gt;redis.conf&lt;/code&gt; 파일에서 이 값을 설정해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="aof-append-only-file-방식-변경"&gt;
 AOF (Append-Only File) 방식 변경
 &lt;a class="heading-anchor" href="#aof-append-only-file-%eb%b0%a9%ec%8b%9d-%eb%b3%80%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;AOF는 모든 쓰기 명령을 로그 파일에 순차적으로 기록하여 데이터 손실을 방지하는 방식이다. &lt;code&gt;appendonly&lt;/code&gt; 옵션을 사용하여 AOF를 활성화하거나 비활성화할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;현재 AOF 설정을 확인하려면 &lt;code&gt;redis-cli&lt;/code&gt;에서 다음 명령을 입력한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;CONFIG GET appendonly&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;AOF를 활성화하려면 다음 명령을 입력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;CONFIG SET appendonly yes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;AOF의 동작 방식을 조정하려면 &lt;code&gt;appendfsync&lt;/code&gt; 설정을 사용할 수 있다. 예를 들어, AOF 동기화를 &lt;code&gt;always&lt;/code&gt;로 설정하면, Redis는 각 쓰기 연산 후에 즉시 파일을 디스크에 동기화한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;CONFIG SET appendfsync always&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;AOF는 성능에 영향을 미칠 수 있으므로, 이를 사용하되 주기적인 백업과 모니터링이 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="변경-사항-확인"&gt;
 변경 사항 확인
 &lt;a class="heading-anchor" href="#%eb%b3%80%ea%b2%bd-%ec%82%ac%ed%95%ad-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;저장 방식을 변경한 후, 설정이 적용되었는지 다시 확인할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;CONFIG GET save
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;CONFIG GET appendonly&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="영구적인-설정-변경"&gt;
 영구적인 설정 변경
 &lt;a class="heading-anchor" href="#%ec%98%81%ea%b5%ac%ec%a0%81%ec%9d%b8-%ec%84%a4%ec%a0%95-%eb%b3%80%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;CONFIG SET&lt;/code&gt; 명령어는 Redis가 종료되고 재시작되면 설정이 초기화된다. 따라서 영구적인 변경을 원한다면 Redis 설정 파일인 &lt;code&gt;redis.conf&lt;/code&gt;에서 해당 값을 수정해야 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Redis의 설정 파일 (&lt;code&gt;redis.conf&lt;/code&gt;)을 Kubernetes 설정에 맞게 수정한 후, 해당 파일을 Pod에 반영하거나, Redis가 사용하는 ConfigMap을 업데이트해야 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl edit configmap redis-config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;위 명령을 사용하여 ConfigMap을 수정하고, 그에 맞는 변경을 Redis Pod에 적용한다. Pod가 재시작되면 새로운 설정이 반영된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="변경-후-redis-재시작"&gt;
 변경 후 Redis 재시작
 &lt;a class="heading-anchor" href="#%eb%b3%80%ea%b2%bd-%ed%9b%84-redis-%ec%9e%ac%ec%8b%9c%ec%9e%91" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;변경 사항을 적용하려면 Redis Pod를 재시작해야 할 수 있다. Redis Pod를 재시작하려면 다음 명령어를 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout restart deployment redis&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Deploy Redis Insight(2.64.1)</title><link>https://kyungryeol-yoon.github.io/database/redis/kubernetes-deploy-redis-insight2.64.1/</link><pubDate>Fri, 14 Feb 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/redis/kubernetes-deploy-redis-insight2.64.1/</guid><description>&lt;h2 id="redis-insight-배포"&gt;
 Redis Insight 배포
 &lt;a class="heading-anchor" href="#redis-insight-%eb%b0%b0%ed%8f%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redisinsight&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#deployment name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redisinsight&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#deployment label&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#a single replica pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redisinsight&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#which pods is the deployment managing, as defined by the pod template&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#pod template&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redisinsight&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#label for pod/s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redisinsight&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#Container name (DNS_LABEL, unique)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis/redisinsight:latest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#repo/image&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;imagePullPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;IfNotPresent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#Installs the latest Redis Insight version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redisinsight&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#Pod volumes to mount into the container&amp;#39;s filesystem. Cannot be updated.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5540&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#exposed container port and protocol&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redisinsight&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;emptyDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# node-ephemeral volume https://kubernetes.io/docs/concepts/storage/volumes/#emptydir&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Redis Insight 설치 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://redis.io/docs/latest/operate/redisinsight/install/install-on-k8s"&gt;https://redis.io/docs/latest/operate/redisinsight/install/install-on-k8s&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Redis Insight Configuration Settings 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://redis.io/docs/latest/operate/redisinsight/configuration"&gt;https://redis.io/docs/latest/operate/redisinsight/configuration&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Deploy P3X Redis UI(v2025.4.101)</title><link>https://kyungryeol-yoon.github.io/database/redis/kubernetes-deploy-p3x-redis-uiv2025.4.101/</link><pubDate>Thu, 13 Feb 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/redis/kubernetes-deploy-p3x-redis-uiv2025.4.101/</guid><description>&lt;h2 id="p3x-redis-ui-배포"&gt;
 P3X Redis UI 배포
 &lt;a class="heading-anchor" href="#p3x-redis-ui-%eb%b0%b0%ed%8f%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;p3x-redis-ui&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;p3x-redis-ui&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;p3x-redis-ui&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;p3x-redis-ui&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;p3x-redis-ui&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;patrikx3/p3x-redis-ui&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;p3x-redis-ui&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7843&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;p3x-redis-ui-settings&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/settings/.p3xrs-conns.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;subPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;.p3xrs-conns.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;p3x-redis-ui-settings&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;p3x-redis-ui-settings&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="configmap-설정"&gt;
 ConfigMap 설정
 &lt;a class="heading-anchor" href="#configmap-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ConfigMap&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;p3x-redis-ui-settings&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;p3x-redis-ui&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;.p3xrs-conns.json&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;list&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;name&amp;#34;: &amp;#34;cluster&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;host&amp;#34;: &amp;#34;YOUR_REDIS_HOST&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;port&amp;#34;: 6379,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;password&amp;#34;: &amp;#34;YOUR_REDIS_PASSWORD_OR_EMPTY&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;id&amp;#34;: &amp;#34;unique&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;license&amp;#34;: &amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Deploy Redis(7.4.2)</title><link>https://kyungryeol-yoon.github.io/database/redis/kubernetes-deploy-redis7.4.2/</link><pubDate>Wed, 12 Feb 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/redis/kubernetes-deploy-redis7.4.2/</guid><description>&lt;h2 id="command를-통해-redis-acl-설정하여-배포--pvc-설정"&gt;
 Command를 통해 Redis ACL 설정하여 배포 + PVC 설정
 &lt;a class="heading-anchor" href="#command%eb%a5%bc-%ed%86%b5%ed%95%b4-redis-acl-%ec%84%a4%ec%a0%95%ed%95%98%ec%97%ac-%eb%b0%b0%ed%8f%ac--pvc-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6379&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sh&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s1"&gt;&amp;#39;-c&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;nohup sh -c &amp;#39;sleep 15 &amp;amp;&amp;amp; redis-cli -a $REDIS_PASSWORD ACL SETUSER $REDIS_USERNAME on +@all ~* \\&amp;gt;$REDIS_PASSWORD&amp;#39; &amp;amp; redis-server --requirepass $REDIS_PASSWORD&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;REDIS_USERNAME&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;valueFrom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secretKeyRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-credentials&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;REDIS_USERNAME&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;REDIS_PASSWORD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;valueFrom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secretKeyRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-credentials&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;REDIS_PASSWORD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persistentVolumeClaim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;claimName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-pvc&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="데이터-보존을-위한-pvc-생성"&gt;
 데이터 보존을 위한 PVC 생성
 &lt;a class="heading-anchor" href="#%eb%8d%b0%ec%9d%b4%ed%84%b0-%eb%b3%b4%ec%a1%b4%ec%9d%84-%ec%9c%84%ed%95%9c-pvc-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="persistent-volume-생성"&gt;
 Persistent Volume 생성
 &lt;a class="heading-anchor" href="#persistent-volume-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PersistentVolume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-pv&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;5Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteOnce&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persistentVolumeReclaimPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Retain&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/mnt/data/redis&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="persistent-volume-claim-생성"&gt;
 Persistent Volume Claim 생성
 &lt;a class="heading-anchor" href="#persistent-volume-claim-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PersistentVolumeClaim&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-pvc&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteOnce&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;5Gi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="secret-설정"&gt;
 Secret 설정
 &lt;a class="heading-anchor" href="#secret-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Secret&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-credentials&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Opaque&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# base64 인코딩된 값 (user와 password 값)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;REDIS_USERNAME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;YWRtaW4= &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# admin을 base64로 인코딩한 값&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;REDIS_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;MTIzNQ== &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 1235를 base64로 인코딩한 값&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="redis-acl-설정을-configmap을-통해-redis-배포"&gt;
 Redis ACL 설정을 ConfigMap을 통해 Redis 배포
 &lt;a class="heading-anchor" href="#redis-acl-%ec%84%a4%ec%a0%95%ec%9d%84-configmap%ec%9d%84-%ed%86%b5%ed%95%b4-redis-%eb%b0%b0%ed%8f%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6379&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;redis-server&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;--aclfile&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;/etc/redis/redis.acl&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ACL 파일 경로 지정&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-acl-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/etc/redis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;subPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis.acl&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-acl-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-acl-config&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="configmap-설정"&gt;
 ConfigMap 설정
 &lt;a class="heading-anchor" href="#configmap-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ConfigMap&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-acl-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;redis.acl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # default 계정 No Password
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; user default on nopass ~* +@all
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # admin 계정 Password 설정
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; user admin on &amp;gt;password ~* +@all
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; 또는
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # 모든 key 읽기 권한만 부여
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; user default on &amp;gt;password allkeys +@read
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; 또는
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # 관리자 계정
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; user default on +@all
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # 사용자 계정 (readonly 권한)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; user myuser on &amp;gt;password +@read
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # 관리자 권한을 가진 사용자
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; user admin on &amp;gt;adminpassword +@all&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="acl-redis-설정-관련-configmap을-통해-command로-배포"&gt;
 ACL, Redis 설정 관련 ConfigMap을 통해 Command로 배포
 &lt;a class="heading-anchor" href="#acl-redis-%ec%84%a4%ec%a0%95-%ea%b4%80%eb%a0%a8-configmap%ec%9d%84-%ed%86%b5%ed%95%b4-command%eb%a1%9c-%eb%b0%b0%ed%8f%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6379&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sh&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s1"&gt;&amp;#39;-c&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;nohup sh -c &amp;#39;sleep 15 &amp;amp;&amp;amp; redis-cli -a $REDIS_PASSWORD ACL SETUSER $REDIS_USERNAME on +@all ~* \\&amp;gt;$REDIS_PASSWORD&amp;#39; &amp;amp; redis-server /etc/redis/redis.conf --aclfile /etc/redis/redis.acl --requirepass $REDIS_PASSWORD&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;REDIS_USERNAME&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;valueFrom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secretKeyRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-credentials&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;REDIS_USERNAME&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;REDIS_PASSWORD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;valueFrom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secretKeyRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-credentials&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;REDIS_PASSWORD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-acl-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/etc/redis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;subPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis.acl&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/etc/redis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;subPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis.conf&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persistentVolumeClaim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;claimName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-pvc&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-acl-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-acl-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-config&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="redis-configmap-설정"&gt;
 Redis ConfigMap 설정
 &lt;a class="heading-anchor" href="#redis-configmap-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ConfigMap&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;redis.conf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # Redis의 기본 설정 예시
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; save 900 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; save 300 10
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; save 60 10000
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; appendonly yes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; appendfsync everysec
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # 아래와 같이 ACL 파일 경로 설정하지 않는다면 command에서 실행
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; aclfile /etc/redis/redis.acl&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="redis-acl-configmap-설정"&gt;
 Redis ACL ConfigMap 설정
 &lt;a class="heading-anchor" href="#redis-acl-configmap-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ConfigMap&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-acl-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;redis-namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;redis.acl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # default 계정 No Password
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; user default on nopass ~* +@all
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # admin 계정 Password 설정
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; user admin on &amp;gt;password ~* +@all
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; 또는
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # 모든 key 읽기 권한만 부여
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; user default on &amp;gt;password allkeys +@read
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; 또는
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # 관리자 계정
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; user default on +@all
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # 사용자 계정 (readonly 권한)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; user myuser on &amp;gt;password +@read
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # 관리자 권한을 가진 사용자
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; user admin on &amp;gt;adminpassword +@all&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Redis] ACL</title><link>https://kyungryeol-yoon.github.io/database/redis/redis-acl/</link><pubDate>Wed, 05 Feb 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/redis/redis-acl/</guid><description>&lt;h2 id="redis-acl"&gt;
 Redis ACL
 &lt;a class="heading-anchor" href="#redis-acl" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Redis 6 Version 부터 ACL(Access Control List)로 User라는 개념이 도입&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이 User를 통해 실행 가능 Command와 접근 가능 키를 제한할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ACL : Access Control List. 접근 제어&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;사용자를 생성하고 암호 지정, 사용 가능한 Command와 키 지정 가능&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ACL 사용을 통해 보안성과 안전성 구현 가능&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;KEYS/FLUSHALL 호출 방지, 사용자에게 필요한 권한만 부여 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="사용자-조회"&gt;
 사용자 조회
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%ec%9e%90-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="사용자-정보-리스트-조회"&gt;
 사용자 정보 리스트 조회
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%ec%9e%90-%ec%a0%95%eb%b3%b4-%eb%a6%ac%ec%8a%a4%ed%8a%b8-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; ACL LIST
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;1&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;user default on nopass ~* +@all&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;초기 Redis 서버에는 default user가 등록되어 있음&lt;/li&gt;
&lt;li&gt;사용자명 default
&lt;ul&gt;
&lt;li&gt;활성 상태&lt;/li&gt;
&lt;li&gt;비밀번호 없음&lt;/li&gt;
&lt;li&gt;모든 키 접근 가능&lt;/li&gt;
&lt;li&gt;모든 Command 수행 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용자-목록-조회"&gt;
 사용자 목록 조회
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%ec%9e%90-%eb%aa%a9%eb%a1%9d-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; ACL USERS&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="사용자-조회-1"&gt;
 사용자 조회
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%ec%9e%90-%ec%a1%b0%ed%9a%8c-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; ACL GETUSER user&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="본인-확인"&gt;
 본인 확인
 &lt;a class="heading-anchor" href="#%eb%b3%b8%ec%9d%b8-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; ACL WHOAMI&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="로그인-auth"&gt;
 로그인 AUTH
 &lt;a class="heading-anchor" href="#%eb%a1%9c%ea%b7%b8%ec%9d%b8-auth" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; AUTH user password&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;user명 생략 시 default user로 로그인&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="사용자-등록-acl-setuser"&gt;
 사용자 등록 ACL SETUSER
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%ec%9e%90-%eb%93%b1%eb%a1%9d-acl-setuser" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; ACL SETUSER user on&lt;span class="p"&gt;|&lt;/span&gt;off &amp;gt;password keys commands&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;user&lt;/code&gt; : user id 설정&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;on|off&lt;/code&gt; : 활성화 여부 설정. 사용자를 등록하지만 일단 사용하지 못하게 할 때 off 사용&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;새로 로그인(auth) 할 수는 없지만, 이미 로그인한 사용자의 사용을 막을 수는 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;password&lt;/code&gt; : 비밀번호는 &lt;code&gt;&amp;gt;&lt;/code&gt; 구분자 다음에 지정&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nopass&lt;/code&gt; : 비밀번호 없이 사용하려는 경우 지정. 로그인 시 아무 문자열이나 입력해도 됨&lt;/li&gt;
&lt;li&gt;비밀번호 저장 시 내부적으로 SHA-256 암호화 알고리즘 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;keys&lt;/code&gt; : 사용가능한 키 지정&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;모든 키 허용 : &lt;code&gt;allkeys&lt;/code&gt; 또는 &lt;code&gt;~*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;특정 패턴 지정 : &lt;code&gt;~user*&lt;/code&gt; 로 지정 시 user로 시작하는 키만 사용 가능&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~*&lt;/code&gt; 상태에서 특정 패턴을 지정하려면 &lt;code&gt;resetkeys&lt;/code&gt; 사용 ex) &lt;code&gt;ACL SETUSER user resetkeys ~user*&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;commands&lt;/code&gt; : 사용 가능한 Command 지정&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;모든 Command 허용 : &lt;code&gt;allcommands&lt;/code&gt; 또는 &lt;code&gt;+@all&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;모든 Command 비허용 : &lt;code&gt;nocommands&lt;/code&gt; 또는 &lt;code&gt;-@all&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Command 지정 : &lt;code&gt;+command&lt;/code&gt;로 추가, &lt;code&gt;-command&lt;/code&gt;로 빼기&lt;/li&gt;
&lt;li&gt;Command 그룹 지정 : &lt;code&gt;+@group&lt;/code&gt;으로 추가, &lt;code&gt;-@group&lt;/code&gt;으로 빼기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ACL SETUSER Command는 비밀번호가 포함되므로 로그에 남지 않음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;관리자 user 설정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; ACL SETUSER admin on &amp;gt;password allkeys allcommands&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;조회 user 설정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; ACL SETUSER reader on &amp;gt;password allkeys +@read&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Read/Write 가능한 일반 사용자 설정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; ACL SETUSER writer on &amp;gt;password allkeys allcommands -@dangerous&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;read-only:&lt;/code&gt;로 시작하는 key만 접근 가능&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; ACL SETUSER reader on &amp;gt;abcd ~read-only:* +@all -@set &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;reader라는 User의 비밀번호를 abcd로 설정&lt;/li&gt;
&lt;li&gt;key는 &lt;code&gt;read-only:&lt;/code&gt;로 시작하는 key만 접근 가능&lt;/li&gt;
&lt;li&gt;&lt;code&gt;+@all&lt;/code&gt;은 모든 Command 사용 가능&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-@set&lt;/code&gt;은 set Command는 사용 불가능&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;*&lt;/code&gt;는 모든 pub/sub채널에 대해 접근 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="command-그룹"&gt;
 Command 그룹
 &lt;a class="heading-anchor" href="#command-%ea%b7%b8%eb%a3%b9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="command-그룹-목록-조회"&gt;
 Command 그룹 목록 조회
 &lt;a class="heading-anchor" href="#command-%ea%b7%b8%eb%a3%b9-%eb%aa%a9%eb%a1%9d-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; ACL CAT
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; 1&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;keyspace&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; 2&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;read&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; 3&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;write&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; 4&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;set&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; 5&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;sortedset&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; 6&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;list&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; 7&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;hash&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; 8&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; 9&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;bitmap&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;10&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;hyperloglog&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;11&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;geo&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;12&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;stream&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;13&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pubsub&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;14&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;15&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;fast&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;16&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;slow&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;17&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;blocking&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;18&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;dangerous&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;19&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;connection&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;20&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;transaction&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;21&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;scripting&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;keyspace&lt;/strong&gt; : del, expire, flushdb, keys, ttl, scan 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;read&lt;/strong&gt; : get, lrange, smembers, zrange, hget, xrange 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;write&lt;/strong&gt; : set, lpush, sadd, zadd, hset, xadd 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;set&lt;/strong&gt; : sadd, scard, srem, spop 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sortedset&lt;/strong&gt; : zadd, zcard, srem, zpopmin 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;list&lt;/strong&gt; : lpush, llen, lrem, lpop 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;hash&lt;/strong&gt; : hset, hlen, ldel, hget 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;string&lt;/strong&gt; : set, get, incr 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;bitmap&lt;/strong&gt; : setbit, bitop, getbit 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;hyperloglog&lt;/strong&gt; : pfadd, pfmerge, pfcount, pfselftest&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;geo&lt;/strong&gt; : geoadd, geodist, georadius 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;stream&lt;/strong&gt; : xadd, xlen, xrange, xdel 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pubsub&lt;/strong&gt; : publish, subscribe, pubsub 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;admin&lt;/strong&gt; : bgsave, config, debug, shutdown 등
&lt;ul&gt;
&lt;li&gt;admin 명령은 dangerous 그룹에 포함됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;fast&lt;/strong&gt; : get, lpush, hget 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;slow&lt;/strong&gt; : lrem, mset, save 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;blocking&lt;/strong&gt; : blpop, brpop, brpoplpush, bzpopmin, bzpopmax, xread, xreadgroup&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dangerous&lt;/strong&gt; : flushall, keys, shutdown, failover, cluster, client, module 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;connection&lt;/strong&gt; : hello, client, auth, echo, ping, command&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;transaction&lt;/strong&gt; : watch, multi, unwatch, discard, exec&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;scripting&lt;/strong&gt; : evalsha, eval, script&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dangerous-그룹"&gt;
 Dangerous 그룹
 &lt;a class="heading-anchor" href="#dangerous-%ea%b7%b8%eb%a3%b9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;보안 위험, 성능 저하 위험이 있는 Command들이 포함됨&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;flushall&lt;/strong&gt; : Redis 서버의 모든 데이터(key, value) 삭제&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;flushdb&lt;/strong&gt; : 현재 사용중인 DB의 모든 데이터(key, value) 삭제&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;swapdb&lt;/strong&gt; : 두 DB를 swap&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;keys&lt;/strong&gt; : 패턴에 일치하는 모든 key 반환 ➡️ scan 사용으로 대체&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;shutdown&lt;/strong&gt; : Redis 종료&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;monitor&lt;/strong&gt; : 서버에서 실행되는 모든 Command 관찰/감시. monitor 수행 시 서버 성능 50% 하락&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;role&lt;/strong&gt; : 자신의 역할(master/slave/sentinel)과 부가 정보 조회&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sync&lt;/strong&gt; : 내부 Command replication&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;psync&lt;/strong&gt; : 내부 Command partial replication&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;replconf&lt;/strong&gt; : 내부 명령 cluster&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pfselftest&lt;/strong&gt; : 내부 명령 HyperLogLog&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sort&lt;/strong&gt; : list 데이터를 정렬&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sort_ro&lt;/strong&gt; : sort와 동일하지만 결과를 저장하지 않음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;migrate&lt;/strong&gt; : data를 다른 redis server로 옮기기. 내부적으로 dump, restore, del 명령이 실행됨&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;restore, restore-asking&lt;/strong&gt; : serialized value를 deserialize하여 저장&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;failover&lt;/strong&gt; : master와 replica 변경&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;info&lt;/strong&gt; : Redis 서버 정보와 통계값 조회&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;debug, pfdebug&lt;/strong&gt; : redis 개발/테스트 용도. 여러 관리 명령 실행 가능&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;save&lt;/strong&gt; : RDB 파일 저장 (foreground 수행). 수행 완료까지 서버가 다른 일 수행 불가&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;bgsave&lt;/strong&gt; : RDB 파일 저장 (background 수행). 하위 프로세스를 생성하여 수행&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;bgrewriteaof&lt;/strong&gt; : AOF 파일 저장(background 수행). 하위 프로세스를 생성하여 수행&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;lastsave&lt;/strong&gt; : RDB 마지막 저장 일시를 timestamp 형식으로 출력&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;slaveof&lt;/strong&gt; : 슬레이브 설정 변경&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;replicaof&lt;/strong&gt; : 복제노드 설정 변경&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;config&lt;/strong&gt; : 서버 설정 변경&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;client&lt;/strong&gt; : 클라이언트 관리 (조회, 제거, 이름 변경 등)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;cluster&lt;/strong&gt; : 클러스터 설정 변경&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;module&lt;/strong&gt; : 모듈 관리&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;slowlog&lt;/strong&gt; : 명령 성능 측정/기록. 성능 저하 발생&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;latency&lt;/strong&gt; : 서버 성능 분석. 성능 저하 발생&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;acl&lt;/strong&gt; : 사용자 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="그룹의-command-목록-조회"&gt;
 그룹의 Command 목록 조회
 &lt;a class="heading-anchor" href="#%ea%b7%b8%eb%a3%b9%ec%9d%98-command-%eb%aa%a9%eb%a1%9d-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; ACL CAT group&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Command가 어느 그룹에 속하는지 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; COMMAND INFO &amp;lt;Command명&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="사용자-삭제-deluser"&gt;
 사용자 삭제 DELUSER
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%ec%9e%90-%ec%82%ad%ec%a0%9c-deluser" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; ACL DELUSER user&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Default user 삭제 불가&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="acl-file"&gt;
 ACL file
 &lt;a class="heading-anchor" href="#acl-file" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;사용자 정보 저장&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; ACL SAVE&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;사용자 정보를 redis.conf에 설정된 옵션에 따라 acl file에 저장&lt;/li&gt;
&lt;li&gt;저장하는 사용자 정보는 ACL LIST의 결과와 같음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;사용자 정보 로드&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; ACL LOAD&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;redis 서버 시작 시 acl file에서 사용자 정보 로드&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="aclauth-로그"&gt;
 ACL(Auth) 로그
 &lt;a class="heading-anchor" href="#aclauth-%eb%a1%9c%ea%b7%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;127.0.0.1:6379&amp;gt; ACL LOG &lt;span class="o"&gt;[&lt;/span&gt;&amp;lt;count&amp;gt; &lt;span class="p"&gt;|&lt;/span&gt; RESET&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;실패한 로그인 정보 조회&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;ACL 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl"&gt;https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Install CloudNativePG Using Helm Chart</title><link>https://kyungryeol-yoon.github.io/database/postgresql/kubernetes-install-cloudnative-pg-using-helm/</link><pubDate>Thu, 16 Jan 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/postgresql/kubernetes-install-cloudnative-pg-using-helm/</guid><description>&lt;div class="alert alert-info"&gt;
 &lt;span class="alert-label"&gt;참고&lt;/span&gt;
 &lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
&lt;/div&gt;

&lt;h2 id="postgresql-helm-repo-추가"&gt;
 PostgreSQL Helm Repo 추가
 &lt;a class="heading-anchor" href="#postgresql-helm-repo-%ec%b6%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo add cnpg https://cloudnative-pg.github.io/charts&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo update&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="자신의-환경에-맞게-valuesyaml-파일-수정"&gt;
 자신의 환경에 맞게 values.yaml 파일 수정
 &lt;a class="heading-anchor" href="#%ec%9e%90%ec%8b%a0%ec%9d%98-%ed%99%98%ea%b2%bd%ec%97%90-%eb%a7%9e%ea%b2%8c-valuesyaml-%ed%8c%8c%ec%9d%bc-%ec%88%98%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;replicaCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ghcr.io/cloudnative-pg/cloudnative-pg&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pullPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;IfNotPresent&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Overrides the image tag whose default is the chart appVersion.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;imagePullSecrets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;nameOverride&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;fullnameOverride&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;namespaceOverride&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;hostNetwork&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# -- Nodeselector for the operator to be installed.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;nodeSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# -- Tolerations for the operator to be installed.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;tolerations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# -- Affinity for the operator to be installed.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;affinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Values 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/cloudnative-pg/charts/blob/main/charts/cloudnative-pg/values.yaml"&gt;https://github.com/cloudnative-pg/charts/blob/main/charts/cloudnative-pg/values.yaml&lt;/a&gt;
&lt;div class="alert alert-info"&gt;
 &lt;span class="alert-label"&gt;참고&lt;/span&gt;
 
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="helm으로-operator-설치"&gt;
 Helm으로 Operator 설치
 &lt;a class="heading-anchor" href="#helm%ec%9c%bc%eb%a1%9c-operator-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install cnpg cnpg/cloudnative-pg --namespace &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt; -f values.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="postgresql-배포"&gt;
 postgresql 배포
 &lt;a class="heading-anchor" href="#postgresql-%eb%b0%b0%ed%8f%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql.cnpg.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mycluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;imageName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgres:17.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;instances&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 3대 파드 (Primary 1대, Standby 2대가 기본)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;3Gi &lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;postgresql&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;max_worker_processes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;40&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Asia/Seoul&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ssl_min_protocol_version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TLSv1.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pg_hba&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;host all postgres all trust&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;primaryUpdateStrategy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;unsupervised&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enableSuperuserAccess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bootstrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;initdb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;encoding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;UTF8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;localeCType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;C&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;localeCollate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;C&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Cluster Sample Yaml 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/cloudnative-pg/cloudnative-pg/blob/main/docs/src/samples/cluster-example-full.yaml"&gt;https://github.com/cloudnative-pg/cloudnative-pg/blob/main/docs/src/samples/cluster-example-full.yaml&lt;/a&gt;
&lt;div class="alert alert-info"&gt;
 &lt;span class="alert-label"&gt;참고&lt;/span&gt;
 
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Cluster Sample Init DB Yaml 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/cloudnative-pg/cloudnative-pg/blob/main/docs/src/samples/cluster-example-initdb.yaml"&gt;https://github.com/cloudnative-pg/cloudnative-pg/blob/main/docs/src/samples/cluster-example-initdb.yaml&lt;/a&gt;
&lt;div class="alert alert-info"&gt;
 &lt;span class="alert-label"&gt;참고&lt;/span&gt;
 
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Cluster Sample Init DB SQL Refs Yaml 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/cloudnative-pg/cloudnative-pg/blob/main/docs/src/samples/cluster-example-initdb-sql-refs.yaml"&gt;https://github.com/cloudnative-pg/cloudnative-pg/blob/main/docs/src/samples/cluster-example-initdb-sql-refs.yaml&lt;/a&gt;
&lt;div class="alert alert-info"&gt;
 &lt;span class="alert-label"&gt;참고&lt;/span&gt;
 
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Blog] Chirpy</title><link>https://kyungryeol-yoon.github.io/blog/blog-chirpy/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/blog/blog-chirpy/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Linux 환경에서 작업 (아래 중에 하나 선택)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;WSL(Windows Subsystem for Linux)&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Mac OS
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;bundle 실행 전 반드시 ruby Version이 최소 3 Version 이상인지 확인해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Ruby 2.x Version인 bundle을 통해 모듈을 설치할 경우
&lt;ul&gt;
&lt;li&gt;Chirpy에서 사용하는 모듈과 호환되지 않아 정상적으로 동작하지 않는다.
&lt;ul&gt;
&lt;li&gt;블로그 기능(Dark Mode, 검색, 이미지 표시, Mobile 환경 비정상 동작 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Node.js Version 20 이상 추천한다.
&lt;ul&gt;
&lt;li&gt;Node.js Version이 낮을 경우, 몇몇 npm module이 설치가 되지 않을 때가 있다.
{: .prompt-tip }&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ruby-설치"&gt;
 Ruby 설치
 &lt;a class="heading-anchor" href="#ruby-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;아래와 같이 설치하면 2.x version이 설치된다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get install ruby-full&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ruby -v&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ruby-3x-version-설치"&gt;
 Ruby 3.x Version 설치
 &lt;a class="heading-anchor" href="#ruby-3x-version-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="se"&gt;\c&lt;/span&gt;url -sSL https://get.rvm.io &lt;span class="p"&gt;|&lt;/span&gt; bash -s stable&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;rvm install 3.4.1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ruby -v&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="nodejs-설치"&gt;
 Node.js 설치
 &lt;a class="heading-anchor" href="#nodejs-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -fsSL https://deb.nodesource.com/setup_23.x -o nodesource_setup.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;node.js 모듈을 설치하지 않으면 &lt;code&gt;assets/js/dist/*.min.js&lt;/code&gt; &lt;strong&gt;Not Found&lt;/strong&gt; 에러 발생과 함께 블로그 기능이 정상적으로 동작하지 않는다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="필요-패키지-설치"&gt;
 필요 패키지 설치
 &lt;a class="heading-anchor" href="#%ed%95%84%ec%9a%94-%ed%8c%a8%ed%82%a4%ec%a7%80-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;gem install bundler&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;bundle install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="초기화-전에-git-commit"&gt;
 초기화 전에 &lt;code&gt;git commit&lt;/code&gt;
 &lt;a class="heading-anchor" href="#%ec%b4%88%ea%b8%b0%ed%99%94-%ec%a0%84%ec%97%90-git-commit" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;git add .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;git commit -m &lt;span class="s2"&gt;&amp;#34;chore(release): prepare for version 1.2.3&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="chirpy-초기화"&gt;
 Chirpy 초기화
 &lt;a class="heading-anchor" href="#chirpy-%ec%b4%88%ea%b8%b0%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo bash tools/init.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;git push&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] PostgreSQL SSL Mode 설정</title><link>https://kyungryeol-yoon.github.io/database/postgresql/kubernetes-postgresql-ssl-setting/</link><pubDate>Wed, 08 Jan 2025 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/postgresql/kubernetes-postgresql-ssl-setting/</guid><description>&lt;ul&gt;
&lt;li&gt;Kubernetes에서 PostgreSQL의 &lt;code&gt;pg_hba.conf&lt;/code&gt; 파일에서 SSL 모드를 활성화하려면 다음 단계에 따라 설정할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ssl-인증서-준비"&gt;
 SSL 인증서 준비
 &lt;a class="heading-anchor" href="#ssl-%ec%9d%b8%ec%a6%9d%ec%84%9c-%ec%a4%80%eb%b9%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SSL 모드를 활성화하려면 PostgreSQL 서버와 클라이언트가 인증서와 개인 키를 설정해야 한다. 보통 다음 파일들이 필요하다:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;server.crt&lt;/code&gt;: 서버 인증서&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;server.key&lt;/code&gt;: 서버의 개인 키&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;root.crt&lt;/code&gt;: 클라이언트가 신뢰하는 CA 인증서 (optional, 클라이언트 검증용)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;인증서 파일을 Kubernetes 비밀(Secret)로 관리하는 것이 일반적이다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="postgresql-docker-이미지에서-ssl-설정"&gt;
 PostgreSQL Docker 이미지에서 SSL 설정
 &lt;a class="heading-anchor" href="#postgresql-docker-%ec%9d%b4%eb%af%b8%ec%a7%80%ec%97%90%ec%84%9c-ssl-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;PostgreSQL의 Docker 이미지를 사용하고 있다면, &lt;code&gt;postgresql.conf&lt;/code&gt; 파일과 &lt;code&gt;pg_hba.conf&lt;/code&gt; 파일을 수정하여 SSL을 활성화할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;postgresql.conf&lt;/code&gt;에서 SSL 활성화:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ssl = on&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ssl_cert_file = '/path/to/server.crt'&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ssl_key_file = '/path/to/server.key'&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ssl_ca_file = '/path/to/root.crt'&lt;/code&gt; (옵션)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="pg_hbaconf-파일에서-ssl-모드-설정"&gt;
 pg_hba.conf 파일에서 SSL 모드 설정
 &lt;a class="heading-anchor" href="#pg_hbaconf-%ed%8c%8c%ec%9d%bc%ec%97%90%ec%84%9c-ssl-%eb%aa%a8%eb%93%9c-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pg_hba.conf&lt;/code&gt; 파일에서 SSL 모드를 활성화하려면, &lt;code&gt;hostssl&lt;/code&gt; 키워드를 사용하여 SSL 연결만 허용하도록 설정할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TYPE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DATABASE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ADDRESS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;METHOD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;hostssl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;md5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;hostssl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;md5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;이 설정은 모든 IP에서 SSL 연결만 허용하고, &lt;code&gt;md5&lt;/code&gt; 인증 방법을 사용하도록 설정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="kubernetes에서-설정-적용하기"&gt;
 Kubernetes에서 설정 적용하기
 &lt;a class="heading-anchor" href="#kubernetes%ec%97%90%ec%84%9c-%ec%84%a4%ec%a0%95-%ec%a0%81%ec%9a%a9%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes에서 PostgreSQL Pod의 설정을 수정하려면, &lt;code&gt;ConfigMap&lt;/code&gt; 또는 &lt;code&gt;Secret&lt;/code&gt;을 사용하여 &lt;code&gt;pg_hba.conf&lt;/code&gt;와 SSL 인증서 파일을 제공해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="configmap-또는-secret을-사용하여-pg_hbaconf-수정"&gt;
 ConfigMap 또는 Secret을 사용하여 &lt;code&gt;pg_hba.conf&lt;/code&gt; 수정
 &lt;a class="heading-anchor" href="#configmap-%eb%98%90%eb%8a%94-secret%ec%9d%84-%ec%82%ac%ec%9a%a9%ed%95%98%ec%97%ac-pg_hbaconf-%ec%88%98%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes ConfigMap 또는 Secret을 생성하여 &lt;code&gt;pg_hba.conf&lt;/code&gt;와 &lt;code&gt;postgresql.conf&lt;/code&gt;를 제공할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ConfigMap&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pg_hba.conf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # TYPE DATABASE USER ADDRESS METHOD
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; hostssl all all 0.0.0.0/0 md5
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; hostssl all all ::/0 md5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;postgresql.conf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; ssl = on
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; ssl_cert_file = &amp;#39;/etc/ssl/certs/server.crt&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; ssl_key_file = &amp;#39;/etc/ssl/private/server.key&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; ssl_ca_file = &amp;#39;/etc/ssl/certs/root.crt&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="pod에-ssl-인증서-및-키-파일을-추가"&gt;
 Pod에 SSL 인증서 및 키 파일을 추가
 &lt;a class="heading-anchor" href="#pod%ec%97%90-ssl-%ec%9d%b8%ec%a6%9d%ec%84%9c-%eb%b0%8f-%ed%82%a4-%ed%8c%8c%ec%9d%bc%ec%9d%84-%ec%b6%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;server.crt&lt;/code&gt;, &lt;code&gt;server.key&lt;/code&gt;, &lt;code&gt;root.crt&lt;/code&gt; 파일을 Kubernetes Secret으로 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Secret&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-ssl-secret&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;server.crt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;&amp;lt;base64-encoded-certificate&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;server.key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;&amp;lt;base64-encoded-private-key&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;root.crt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;&amp;lt;base64-encoded-ca-certificate&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;그런 다음 PostgreSQL Pod의 볼륨으로 Secret을 마운트하여 &lt;code&gt;postgresql.conf&lt;/code&gt; 및 &lt;code&gt;pg_hba.conf&lt;/code&gt;와 함께 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="postgresql-pod에-적용"&gt;
 PostgreSQL Pod에 적용
 &lt;a class="heading-anchor" href="#postgresql-pod%ec%97%90-%ec%a0%81%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pg_hba.conf&lt;/code&gt;와 SSL 관련 파일들을 수정한 후, 해당 파일들을 컨테이너 내부에 마운트해야 한다. PostgreSQL 컨테이너의 &lt;code&gt;postgresql.conf&lt;/code&gt; 파일과 &lt;code&gt;pg_hba.conf&lt;/code&gt; 파일을 수정한 후, 컨테이너를 재시작하여 변경 사항을 적용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgres:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-config-volume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/etc/postgresql/postgresql.conf&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;subPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql.conf&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-ssl-secret&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/etc/ssl/certs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-config-volume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/etc/pgsql/pg_hba.conf&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;subPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pg_hba.conf&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-config-volume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-ssl-secret&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secretName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-ssl-secret&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="pod-재시작"&gt;
 Pod 재시작
 &lt;a class="heading-anchor" href="#pod-%ec%9e%ac%ec%8b%9c%ec%9e%91" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;위 설정을 완료한 후, PostgreSQL Pod를 재시작하여 SSL 및 &lt;code&gt;pg_hba.conf&lt;/code&gt; 설정이 적용되도록 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout restart deployment postgresql&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;이 과정을 통해 Kubernetes에서 PostgreSQL에 SSL을 활성화하고, &lt;code&gt;pg_hba.conf&lt;/code&gt; 파일에 &lt;code&gt;hostssl&lt;/code&gt; 설정을 추가하여 SSL 연결을 강제할 수 있다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Blog] Jekyll Liquid Tag Template</title><link>https://kyungryeol-yoon.github.io/blog/jekyll-liquid-template/</link><pubDate>Sun, 29 Dec 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/blog/jekyll-liquid-template/</guid><description>&lt;ul&gt;
&lt;li&gt;jekyll를 이용해서 만든 github blog에 Markdown 문법을 이용해서 글을 쓴다.&lt;/li&gt;
&lt;li&gt;글을 쓰다 보면 예시를 작성하기 위해 &lt;code&gt;{{ }}&lt;/code&gt; 과 &lt;code&gt;{% %}&lt;/code&gt;를 사용하는 일이 생긴다.&lt;/li&gt;
&lt;li&gt;하지만 그대로 작성하면 문제가 생긴다. 그럴 경우에는 다음과 같이 liquid 문법의 raw tag를 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="작성-방법"&gt;
 작성 방법
 &lt;a class="heading-anchor" href="#%ec%9e%91%ec%84%b1-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;raw tag를 이용해서 앞뒤로 감싸주면 다음과 같이 Markdown 문법에서 &lt;code&gt;{{ }}&lt;/code&gt;, &lt;code&gt;{% %}&lt;/code&gt;이 예외 처리가 되어 실행되지 않는다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{% raw %} {{ example }} {% endraw %}
{% raw %} {% example %} {% endraw %}&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="결과"&gt;
 결과
 &lt;a class="heading-anchor" href="#%ea%b2%b0%ea%b3%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{{ example }}
{% example %}&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="다른-방법"&gt;
 다른 방법
 &lt;a class="heading-anchor" href="#%eb%8b%a4%eb%a5%b8-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Jekyll은 코드 블록 안에서도 Liquid 필터를 처리한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;코드 앞 뒤를 &lt;code&gt;{% raw %}&lt;/code&gt; 와 &lt;code&gt;{% endraw %}&lt;/code&gt; Tag로 감싸야 할 것입니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Jekyll 4.0 부터, 머리말에 &lt;code&gt;render_with_liquid: false&lt;/code&gt; 를 추가해 문서 전체의 Liquid 를 비활성화할 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-md" data-lang="md"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;title: &amp;#34;[Blog] Jekyll Liquid Tag Template&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;date: 2024-12-29
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;categories: [Blog, Jekyll]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;tags: [blog, jekyll, liquid, tag, template]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;render_with_liquid: false
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;---&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Jekyll Liquid 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jekyllrb-ko.github.io/docs/liquid/tags/"&gt;https://jekyllrb-ko.github.io/docs/liquid/tags/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[DevOps] GitLab Kubernetes Runner: Service Account 권한 에러 해결</title><link>https://kyungryeol-yoon.github.io/devops/gitlab/gitlab-kubernetes-runner-service-account-error/</link><pubDate>Sun, 01 Dec 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/gitlab/gitlab-kubernetes-runner-service-account-error/</guid><description>&lt;h2 id="-문제-상황"&gt;
 🔎 문제 상황
 &lt;a class="heading-anchor" href="#-%eb%ac%b8%ec%a0%9c-%ec%83%81%ed%99%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Helm 기반으로 GitLab Runner를 설치하면 다음 리소스가 생성됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Pod&lt;/code&gt;, &lt;code&gt;Role&lt;/code&gt;, &lt;code&gt;RoleBinding&lt;/code&gt;, &lt;code&gt;ServiceAccount&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Runner 서비스 어카운트(&lt;code&gt;sa&lt;/code&gt;)가 namespace에 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;예시: &lt;code&gt;gitlab-runner&lt;/code&gt; 네임스페이스에 설치된 리소스&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl get pod,role,rolebinding,sa -n gitlab-runner&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;보면 &lt;code&gt;default&lt;/code&gt;와 &lt;code&gt;gitlab-runner&lt;/code&gt;라는 두 ServiceAccount가 생성됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="-실제-에러"&gt;
 🚨 실제 에러
 &lt;a class="heading-anchor" href="#-%ec%8b%a4%ec%a0%9c-%ec%97%90%eb%9f%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;CI 파이프라인에서 아래와 같이 kubectl 명령을 실행하면 다음과 같은 에러가 발생합니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Error from server (Forbidden): pods &amp;#34;nginx-test&amp;#34; is forbidden:
User &amp;#34;system:serviceaccount:gitlab-runner:default&amp;#34;
cannot get resource &amp;#34;pods&amp;#34; in API group &amp;#34;&amp;#34; in the namespace &amp;#34;gitlab-runner&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;즉, &lt;strong&gt;Runner가 잘 설치됐지만 잘못된 ServiceAccount를 사용&lt;/strong&gt;하여 권한이 없어 작업을 수행할 수 없는 상황입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-원인-분석"&gt;
 ❓ 원인 분석
 &lt;a class="heading-anchor" href="#-%ec%9b%90%ec%9d%b8-%eb%b6%84%ec%84%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes에서 GitLab Runner는 기본적으로 &lt;code&gt;default&lt;/code&gt; ServiceAccount를 사용하는데,
이 경우 Runner가 파이프라인에서 필요한 리소스(예: Pod, Secrets)에 대한 권한을 가지지 못합니다.&lt;/p&gt;
&lt;p&gt;특히 다음과 같은 CI/CD 작업에서 &lt;code&gt;kubectl apply&lt;/code&gt;나 리소스 조회를 할 때 이 문제가 발생합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-해결-방법"&gt;
 ✅ 해결 방법
 &lt;a class="heading-anchor" href="#-%ed%95%b4%ea%b2%b0-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1-runner-helm-values-파일-설정"&gt;
 1) Runner Helm values 파일 설정
 &lt;a class="heading-anchor" href="#1-runner-helm-values-%ed%8c%8c%ec%9d%bc-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Helm 설치 시 &lt;code&gt;values.yaml&lt;/code&gt;에서 다음 값을 반드시 override해야 합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;gitlabUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;lt;GITLAB_URL&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;runnerToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;lt;RUNNER_TOKEN&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;rbac&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;configmaps&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;events&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods/attach&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods/exec&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;secrets&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;services&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;list&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;watch&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;patch&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;update&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;delete&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods/exec&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;patch&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;delete&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods/log&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;위 설정으로 Runner가 처리할 리소스에 대한 RBAC 권한을 충분히 부여합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="2-serviceaccount-지정"&gt;
 2) ServiceAccount 지정
 &lt;a class="heading-anchor" href="#2-serviceaccount-%ec%a7%80%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Runner가 사용할 &lt;strong&gt;ServiceAccount 이름을 직접 지정&lt;/strong&gt;해야 합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;runners&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; [[runners]]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; [runners.kubernetes]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; namespace = &amp;#34;{{ .Release.Namespace }}&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; image = &amp;#34;alpine&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; privileged = true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; service_account = &amp;#34;&amp;lt;GITLAB_RUNNER_SA_NAME&amp;gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이렇게 함으로써 Runner가 실제로 생성된 &lt;code&gt;ServiceAccount&lt;/code&gt;를 명시적으로 사용하도록 설정합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-실행-예시"&gt;
 🧪 실행 예시
 &lt;a class="heading-anchor" href="#-%ec%8b%a4%ed%96%89-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Helm으로 Runner를 설치할 때 아래처럼 실행합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install --namespace gitlab-runner gitlab-runner &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; -f values.yaml &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; gitlab/gitlab-runner&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;설치 후 파이프라인을 다시 실행하면,
Runner가 올바른 &lt;code&gt;ServiceAccount&lt;/code&gt;를 이용해 Kubernetes 리소스에 접근합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-요약"&gt;
 📌 요약
 &lt;a class="heading-anchor" href="#-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GitLab Runner를 Kubernetes에 설치하면 &lt;code&gt;default&lt;/code&gt; ServiceAccount가 기본적으로 선택됩니다.&lt;/li&gt;
&lt;li&gt;이 경우 필요한 권한이 없어 &lt;code&gt;kubectl&lt;/code&gt; 명령이 실패할 수 있습니다.&lt;/li&gt;
&lt;li&gt;해결 방법은:
&lt;ul&gt;
&lt;li&gt;RBAC rules로 리소스 권한을 명시적으로 추가&lt;/li&gt;
&lt;li&gt;Runner가 사용할 ServiceAccount를 지정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 설정이 적용되면 &lt;strong&gt;CI 파이프라인에서 kubectl 작업이 정상적으로 실행&lt;/strong&gt;됩니다.&lt;/p&gt;</description></item><item><title>[Kubernetes] Install Kong Ingress Controller - Gateway API</title><link>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-install-kong-ingress-controller/</link><pubDate>Sat, 30 Nov 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-install-kong-ingress-controller/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Kong Ingress Controller 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.konghq.com/kubernetes-ingress-controller/latest/"&gt;https://docs.konghq.com/kubernetes-ingress-controller/latest/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="install-the-experimental-gateway-api-crds"&gt;
 Install the experimental Gateway API CRDs
 &lt;a class="heading-anchor" href="#install-the-experimental-gateway-api-crds" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/experimental-install.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="install-gatewayclass"&gt;
 Install GatewayClass
 &lt;a class="heading-anchor" href="#install-gatewayclass" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;GatewayClass&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kong&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;konghq.com/gatewayclass-unmanaged&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;controllerName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;konghq.com/kic-gateway-controller&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="install-gateway"&gt;
 Install Gateway
 &lt;a class="heading-anchor" href="#install-gateway" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Gateway&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kong&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gatewayClassName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kong&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;proxy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;HTTP&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;allowedRoutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespaces&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;All&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;proxy-ssl&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;HTTPS&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kong.example.com&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Terminate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;certificateRefs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Secret&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kong-example-com-cert&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;proxy-tcp-9901&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9901&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;proxy-udp-9902&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9902&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;UDP&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;proxy-tls-9903&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9903&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TLS&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="add-kong-helm-chart"&gt;
 Add Kong Helm Chart
 &lt;a class="heading-anchor" href="#add-kong-helm-chart" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo add kong https://charts.konghq.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;helm repo update&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="modify-valuesyaml"&gt;
 Modify Values.yaml
 &lt;a class="heading-anchor" href="#modify-valuesyaml" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;ingressController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;anonymous_reports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;postgresql&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="install-kong"&gt;
 Install Kong
 &lt;a class="heading-anchor" href="#install-kong" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install kong kong/kong -n kong --create-namespace &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="enable-the-gateway-api-alpha-feature-gate"&gt;
 Enable the Gateway API Alpha feature gate
 &lt;a class="heading-anchor" href="#enable-the-gateway-api-alpha-feature-gate" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;set&lt;/span&gt; env -n kong deployment/kong-controller &lt;span class="nv"&gt;CONTROLLER_FEATURE_GATES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;GatewayAlpha=true&amp;#34;&lt;/span&gt; -c ingress-controller&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="tcp-service"&gt;
 TCP Service
 &lt;a class="heading-anchor" href="#tcp-service" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;포트 기반 라우팅: Kong Gateway는 특정 포트에서 수신한 모든 트래픽을 Kubernetes 서비스로 단순히 프록시한다. TCP 연결은 서비스의 모든 사용 가능한 Pods에 걸쳐 로드 밸런싱된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SNI 기반 라우팅: Kong Gateway는 지정된 포트에서 TLS 암호화된 스트림을 수락하고, TLS 핸드쉐이크에서 제공되는 SNI를 기준으로 트래픽을 다른 서비스로 라우팅할 수 있다. 또한 Kong Gateway는 TLS 핸드쉐이크를 종료하고 TCP 스트림을 Kubernetes 서비스로 전달한한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="patch-deployment-kong-gateway"&gt;
 Patch Deployment kong-gateway
 &lt;a class="heading-anchor" href="#patch-deployment-kong-gateway" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;kubectl patch deploy -n kong kong-gateway --patch &lt;span class="s1"&gt;&amp;#39;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;spec&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;template&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;spec&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;containers&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;name&amp;#34;: &amp;#34;proxy&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;env&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;name&amp;#34;: &amp;#34;KONG_STREAM_LISTEN&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;value&amp;#34;: &amp;#34;0.0.0.0:9000, 0.0.0.0:9443 ssl&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;ports&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;containerPort&amp;#34;: 9000,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;name&amp;#34;: &amp;#34;stream9000&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;protocol&amp;#34;: &amp;#34;TCP&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;containerPort&amp;#34;: 9443,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;name&amp;#34;: &amp;#34;stream9443&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;protocol&amp;#34;: &amp;#34;TCP&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="patch-service-kong-kong-gateway-proxy"&gt;
 Patch Service kong kong-gateway-proxy
 &lt;a class="heading-anchor" href="#patch-service-kong-kong-gateway-proxy" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;kubectl patch service -n kong kong-gateway-proxy --patch &lt;span class="s1"&gt;&amp;#39;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;spec&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;ports&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;name&amp;#34;: &amp;#34;stream9000&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;port&amp;#34;: 9000,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;protocol&amp;#34;: &amp;#34;TCP&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;targetPort&amp;#34;: 9000
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;name&amp;#34;: &amp;#34;stream9443&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;port&amp;#34;: 9443,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;protocol&amp;#34;: &amp;#34;TCP&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;targetPort&amp;#34;: 9443
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;}&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="create-tcp-ingress"&gt;
 Create TCP Ingress
 &lt;a class="heading-anchor" href="#create-tcp-ingress" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="l"&gt;echo &amp;#34;apiVersion: configuration.konghq.com/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCPIngress&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;echo-tls&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubernetes.io/ingress.class&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kong&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;secretName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tls9443.kong.example&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;tls9443.kong.example&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tls9443.kong.example&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;backend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serviceName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;echo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;servicePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1025&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Dashboard 설치</title><link>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-dashboard/</link><pubDate>Thu, 21 Nov 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-dashboard/</guid><description>&lt;h2 id="-1-kubernetes-dashboard란"&gt;
 📌 1. Kubernetes Dashboard란?
 &lt;a class="heading-anchor" href="#-1-kubernetes-dashboard%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes Dashboard는 클러스터 리소스를 &lt;strong&gt;웹 UI로 시각화하고 관리할 수 있는 공식 웹 인터페이스&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;주요 기능:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod / Deployment / Service 조회&lt;/li&gt;
&lt;li&gt;로그 확인&lt;/li&gt;
&lt;li&gt;리소스 생성 및 삭제&lt;/li&gt;
&lt;li&gt;네임스페이스 관리&lt;/li&gt;
&lt;li&gt;RBAC 기반 인증&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-2-dashboard-설치"&gt;
 📦 2. Dashboard 설치
 &lt;a class="heading-anchor" href="#-2-dashboard-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;공식 manifest를 이용해 설치합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-생성되는-주요-리소스"&gt;
 🔎 생성되는 주요 리소스
 &lt;a class="heading-anchor" href="#-%ec%83%9d%ec%84%b1%eb%90%98%eb%8a%94-%ec%a3%bc%ec%9a%94-%eb%a6%ac%ec%86%8c%ec%8a%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Namespace&lt;/code&gt;: kubernetes-dashboard&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Deployment&lt;/code&gt;: kubernetes-dashboard&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Deployment&lt;/code&gt;: dashboard-metrics-scraper&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Service&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ServiceAccount&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Role / RoleBinding&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;설치 확인:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get all -n kubernetes-dashboard&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-3-dashboard-외부-접속-nodeport-방식"&gt;
 🌐 3. Dashboard 외부 접속 (NodePort 방식)
 &lt;a class="heading-anchor" href="#-3-dashboard-%ec%99%b8%eb%b6%80-%ec%a0%91%ec%86%8d-nodeport-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;기본적으로 Service 타입은 &lt;code&gt;ClusterIP&lt;/code&gt;이므로 외부에서 접근할 수 없습니다.&lt;/p&gt;
&lt;h3 id="1-service-타입-변경"&gt;
 1️⃣ Service 타입 변경
 &lt;a class="heading-anchor" href="#1-service-%ed%83%80%ec%9e%85-%eb%b3%80%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;아래 부분을 수정합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NodePort&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;targetPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;31000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;저장 후 확인:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get svc -n kubernetes-dashboard&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;예시 출력:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubernetes-dashboard NodePort 10.97.112.43 443:31000/TCP&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h3 id="2-브라우저-접속"&gt;
 2️⃣ 브라우저 접속
 &lt;a class="heading-anchor" href="#2-%eb%b8%8c%eb%9d%bc%ec%9a%b0%ec%a0%80-%ec%a0%91%ec%86%8d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;https://&amp;lt;NodeIP&amp;gt;:31000&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;⚠️ Self-signed 인증서이므로 브라우저에서 보안 경고가 발생할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-4-관리자-계정-및-토큰-생성"&gt;
 🔐 4. 관리자 계정 및 토큰 생성
 &lt;a class="heading-anchor" href="#-4-%ea%b4%80%eb%a6%ac%ec%9e%90-%ea%b3%84%ec%a0%95-%eb%b0%8f-%ed%86%a0%ed%81%b0-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Dashboard는 기본적으로 &lt;strong&gt;Token 인증 방식&lt;/strong&gt;을 사용합니다.&lt;/p&gt;
&lt;h3 id="1-serviceaccount-생성"&gt;
 1️⃣ ServiceAccount 생성
 &lt;a class="heading-anchor" href="#1-serviceaccount-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;admin-user&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes-dashboard&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f admin-user.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="2-clusterrolebinding-생성"&gt;
 2️⃣ ClusterRoleBinding 생성
 &lt;a class="heading-anchor" href="#2-clusterrolebinding-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRoleBinding&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;admin-user&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;roleRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRole&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster-admin&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;subjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;admin-user&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes-dashboard&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f cluster-role-binding.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="3-토큰-생성"&gt;
 3️⃣ 토큰 생성
 &lt;a class="heading-anchor" href="#3-%ed%86%a0%ed%81%b0-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl -n kubernetes-dashboard create token admin-user&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;출력된 토큰을 복사하여 Dashboard 로그인 화면에 붙여넣습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-5-자주-발생하는-이슈"&gt;
 ⚠️ 5. 자주 발생하는 이슈
 &lt;a class="heading-anchor" href="#-5-%ec%9e%90%ec%a3%bc-%eb%b0%9c%ec%83%9d%ed%95%98%eb%8a%94-%ec%9d%b4%ec%8a%88" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="-1-neterr_cert_invalid"&gt;
 🔸 1. NET::ERR_CERT_INVALID
 &lt;a class="heading-anchor" href="#-1-neterr_cert_invalid" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Self-signed 인증서로 인한 브라우저 경고&lt;/li&gt;
&lt;li&gt;실서비스 환경에서는 Ingress + TLS 구성 권장&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="-2-권한-관련-에러"&gt;
 🔸 2. 권한 관련 에러
 &lt;a class="heading-anchor" href="#-2-%ea%b6%8c%ed%95%9c-%ea%b4%80%eb%a0%a8-%ec%97%90%eb%9f%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Forbidden&lt;/code&gt; 오류 발생 시 RBAC 확인&lt;/li&gt;
&lt;li&gt;실 운영 환경에서는 &lt;code&gt;cluster-admin&lt;/code&gt; 대신 최소 권한 Role 사용 권장&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-보안-관점에서의-주의사항"&gt;
 🔐 보안 관점에서의 주의사항
 &lt;a class="heading-anchor" href="#-%eb%b3%b4%ec%95%88-%ea%b4%80%ec%a0%90%ec%97%90%ec%84%9c%ec%9d%98-%ec%a3%bc%ec%9d%98%ec%82%ac%ed%95%ad" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;운영 환경에서 반드시 고려해야 할 사항:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;❌ NodePort 직접 오픈은 지양&lt;/li&gt;
&lt;li&gt;✅ Ingress + 인증서(TLS) 적용&lt;/li&gt;
&lt;li&gt;✅ OIDC / SSO 연동 고려&lt;/li&gt;
&lt;li&gt;✅ 최소 권한 RBAC 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-개발자-관점-정리"&gt;
 🧠 개발자 관점 정리
 &lt;a class="heading-anchor" href="#-%ea%b0%9c%eb%b0%9c%ec%9e%90-%ea%b4%80%ec%a0%90-%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;Dev 환경&lt;/th&gt;
					&lt;th&gt;운영 환경&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Service 타입&lt;/td&gt;
					&lt;td&gt;NodePort&lt;/td&gt;
					&lt;td&gt;Ingress&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;인증&lt;/td&gt;
					&lt;td&gt;Admin Token&lt;/td&gt;
					&lt;td&gt;OIDC / SSO&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;권한&lt;/td&gt;
					&lt;td&gt;cluster-admin&lt;/td&gt;
					&lt;td&gt;최소 권한&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;인증서&lt;/td&gt;
					&lt;td&gt;Self-signed&lt;/td&gt;
					&lt;td&gt;공인 TLS&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-마무리"&gt;
 🏁 마무리
 &lt;a class="heading-anchor" href="#-%eb%a7%88%eb%ac%b4%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes Dashboard는:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;빠르게 클러스터를 시각적으로 확인할 수 있고&lt;/li&gt;
&lt;li&gt;리소스 디버깅에 매우 유용하지만&lt;/li&gt;
&lt;li&gt;보안 설정 없이 운영 환경에 노출하는 것은 위험합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dev/Test 환경에서는 빠른 실습용으로,
운영 환경에서는 보안 구성을 충분히 고려하여 사용하세요.&lt;/p&gt;
&lt;hr&gt;</description></item><item><title>[Python] Python Setup Package</title><link>https://kyungryeol-yoon.github.io/backend/python/python-setup-package/</link><pubDate>Sat, 19 Oct 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/python/python-setup-package/</guid><description>&lt;h2 id="package-directory-구조-만들기"&gt;
 Package Directory 구조 만들기
 &lt;a class="heading-anchor" href="#package-directory-%ea%b5%ac%ec%a1%b0-%eb%a7%8c%eb%93%a4%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;package로 만들기 위해 Directory 구조를 만든다.&lt;/li&gt;
&lt;li&gt;프로젝트는 기본적으로 아래와 같은 형태로 구성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;project/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;├── package/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;│ ├── __init__.py
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;│ └── module.py
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;├── README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;└── setup.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;Name&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Description&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;project&lt;/td&gt;
					&lt;td style="text-align: left"&gt;프로젝트 root Directory&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;package&lt;/td&gt;
					&lt;td style="text-align: left"&gt;프로젝트의 핵심 Directory. 일반적으로 Package의 이름과 동일하게 지정한다.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;init&lt;/strong&gt;.py&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Package를 모듈로 인식하게 만드는 파일. Package가 import될 때 실행된다.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;module.py&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Package에서 제공하는 기능들이 정의된 Python 모듈 파일. 여러 개의 모듈로 구성할 수도 있으며, 기능별로 파일을 나눌 수 있다.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;README.md&lt;/td&gt;
					&lt;td style="text-align: left"&gt;프로젝트의 설명 파일&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;setup.py&lt;/td&gt;
					&lt;td style="text-align: left"&gt;PIP 배포를 위한 설정 파일&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="package-배포를-위한-의존성-설치"&gt;
 Package 배포를 위한 의존성 설치
 &lt;a class="heading-anchor" href="#package-%eb%b0%b0%ed%8f%ac%eb%a5%bc-%ec%9c%84%ed%95%9c-%ec%9d%98%ec%a1%b4%ec%84%b1-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;손수 만든 Python 프로젝트를 배포하기 위한 몇가지 의존성 Package가 존재한다.&lt;/li&gt;
&lt;li&gt;이후 손쉽게 배포하기 위해, 먼저 의존성을 설치해 준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pip install setuptools
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;pip install wheel
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;pip install twine&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="package-설치를-위한-설정-파일-작성"&gt;
 Package 설치를 위한 설정 파일 작성
 &lt;a class="heading-anchor" href="#package-%ec%84%a4%ec%b9%98%eb%a5%bc-%ec%9c%84%ed%95%9c-%ec%84%a4%ec%a0%95-%ed%8c%8c%ec%9d%bc-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Package를 설치 가능하게 만들기 위해 setup.py 파일을 작성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;setuptools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;setup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# README.md 파일을 불러오는 기능&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;README.md&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;long_description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;project&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 등록할 Package 이름 (PyPI에 등록되는 이름)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;0.0.1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Package 버전&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;This is my Python Package.&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Package의 짧은 설명&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;long_description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;long_description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Package의 상세 설명&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;long_description_content_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;text/markdown&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# long_description의 형식&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;author name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Package 작성자 이름&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;author_email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;author email&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Package 작성자 이메일&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://example.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 프로젝트의 공식 URL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;MIT&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Package의 라이선스 정보&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;python_requires&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;gt;=3.7&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Package가 지원하는 Python 버전&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;install_requires&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="c1"&gt;# Package가 의존하는 외부 라이브러리 목록&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;package&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# 포함할 Python Package 목록&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;package_data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="c1"&gt;# Package에 포함할 추가 데이터 목록&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="c1"&gt;# Package 검색 키워드&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;classifiers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;Development Status :: 4 - Beta&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;Intended Audience :: Developers&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;Programming Language :: Python :: 3&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;Operating System :: OS Independent&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;License :: OSI Approved :: MIT License&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# Package 분류&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="package-배포"&gt;
 Package 배포
 &lt;a class="heading-anchor" href="#package-%eb%b0%b0%ed%8f%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;python setup.py bdist_wheel&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;명령어를 실행하면 Package 파일들이 생성된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;아래 명령어를 통해 PyPI로 배포&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;twine&lt;/span&gt; &lt;span class="n"&gt;upload&lt;/span&gt; &lt;span class="n"&gt;dist&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;배포할&lt;/span&gt; &lt;span class="n"&gt;Package&lt;/span&gt; &lt;span class="n"&gt;파일&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;명령어를 실행하면 아래와 같이 API 토큰을 입력하라고 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;API 토큰은 PyPI 사이트에 로그인한 후, Account settings에서 발급받을 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Uploading distributions to https://upload.pypi.org/legacy/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;Enter your API token: &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이후 올바른 API 토큰을 입력하면 배포가 시작되고, 패키지가 등록된다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="package-설치"&gt;
 Package 설치
 &lt;a class="heading-anchor" href="#package-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Package 설치하려면 Terminal을 열고 Package Directory로 이동한 후 다음 명령어를 실행한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pip install .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이 명령어를 실행하면 Package가 Local 환경에 설치된다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="package-사용"&gt;
 Package 사용
 &lt;a class="heading-anchor" href="#package-%ec%82%ac%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;설치된 Package를 다른 Python Script에서 사용할 수 있다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;my_package&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;my_utils&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] eBPF로 실시간 커널 레벨 모니터링하기</title><link>https://kyungryeol-yoon.github.io/observability/ebpf/kubernetes-ebpf/</link><pubDate>Thu, 17 Oct 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/observability/ebpf/kubernetes-ebpf/</guid><description>&lt;h2 id="-ebpf-개발자-관점에서-보는-커널-레벨-모니터링"&gt;
 🔍 eBPF: 개발자 관점에서 보는 커널 레벨 모니터링
 &lt;a class="heading-anchor" href="#-ebpf-%ea%b0%9c%eb%b0%9c%ec%9e%90-%ea%b4%80%ec%a0%90%ec%97%90%ec%84%9c-%eb%b3%b4%eb%8a%94-%ec%bb%a4%eb%84%90-%eb%a0%88%eb%b2%a8-%eb%aa%a8%eb%8b%88%ed%84%b0%eb%a7%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;쿠버네티스 환경에서 성능 분석, 네트워크 모니터링, 보안 트레이싱을 위해 &lt;strong&gt;eBPF&lt;/strong&gt;가 점점 주목받고 있습니다.&lt;br&gt;
개발자 입장에서 이해하면 &lt;strong&gt;애플리케이션과 커널 단위를 어떻게 실시간으로 관측하는지&lt;/strong&gt; 명확해집니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-ebpf란"&gt;
 1️⃣ eBPF란?
 &lt;a class="heading-anchor" href="#1-ebpf%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;eBPF = extended Berkeley Packet Filter&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;리눅스 커널 내부에서 &lt;strong&gt;안전하게 코드 실행&lt;/strong&gt; 가능&lt;/li&gt;
&lt;li&gt;원래 패킷 필터링 용도로 시작했지만, 지금은:
&lt;ul&gt;
&lt;li&gt;커널/시스템 이벤트 트레이싱&lt;/li&gt;
&lt;li&gt;성능 분석&lt;/li&gt;
&lt;li&gt;네트워크 패킷 모니터링&lt;/li&gt;
&lt;li&gt;보안 이벤트 감지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;즉, &lt;strong&gt;커널 레벨에서 실시간 데이터를 수집하고 분석하는 기술&lt;/strong&gt;입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="2-개발자-관점에서-특징"&gt;
 2️⃣ 개발자 관점에서 특징
 &lt;a class="heading-anchor" href="#2-%ea%b0%9c%eb%b0%9c%ec%9e%90-%ea%b4%80%ec%a0%90%ec%97%90%ec%84%9c-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;커널 레벨 후킹&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Tracepoints, kprobes, uprobes를 사용하여 커널 이벤트나 특정 함수 호출 추적 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;실시간 분석&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;거의 지연 없이 syscall, 네트워크 패킷, 컨테이너 활동 감지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;낮은 오버헤드&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;커널 내부에서 직접 실행되므로, 고성능 모니터링 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;다양한 활용&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;성능 최적화, 보안 모니터링, 네트워크 분석 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="3-활용-사례"&gt;
 3️⃣ 활용 사례
 &lt;a class="heading-anchor" href="#3-%ed%99%9c%ec%9a%a9-%ec%82%ac%eb%a1%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;분야&lt;/th&gt;
					&lt;th&gt;예시&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;네트워크&lt;/td&gt;
					&lt;td&gt;Cilium: Kubernetes 네트워크 정책 + 모니터링&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;성능 분석&lt;/td&gt;
					&lt;td&gt;bpftrace: syscall 트레이싱, latency 분석&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;보안&lt;/td&gt;
					&lt;td&gt;Falco: 실시간 보안 이벤트 감지&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Observability 연계&lt;/td&gt;
					&lt;td&gt;eBPF → OTel Collector → Grafana/Loki 시각화&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;eBPF 자체가 데이터 수집/분석용 엔진이고, OTel 같은 Observability 플랫폼과 결합하면 &lt;strong&gt;심층 + 통합 관측&lt;/strong&gt;이 가능합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="4-설치--사용-예시-간단"&gt;
 4️⃣ 설치 &amp;amp; 사용 예시 (간단)
 &lt;a class="heading-anchor" href="#4-%ec%84%a4%ec%b9%98--%ec%82%ac%ec%9a%a9-%ec%98%88%ec%8b%9c-%ea%b0%84%eb%8b%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# bcc 설치 (Ubuntu)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo apt install bpfcc-tools linux-headers-&lt;span class="k"&gt;$(&lt;/span&gt;uname -r&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 간단한 syscall 트레이싱&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;sudo execsnoop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;bcc/bpftrace 도구를 이용하면 커널 이벤트를 쉽게 추적 가능&lt;/li&gt;
&lt;li&gt;Kubernetes에서는 &lt;strong&gt;DaemonSet 형태로 eBPF agent&lt;/strong&gt; 배포 가능 (Cilium, Pixie 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="5-개발자-관점-핵심-포인트"&gt;
 5️⃣ 개발자 관점 핵심 포인트
 &lt;a class="heading-anchor" href="#5-%ea%b0%9c%eb%b0%9c%ec%9e%90-%ea%b4%80%ec%a0%90-%ed%95%b5%ec%8b%ac-%ed%8f%ac%ec%9d%b8%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;데이터 수집 레이어&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;애플리케이션 단위 관측과 달리, 커널/호스트 수준에서 직접 수집&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;사용 난이도&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;커널 지식이 필요하고, 추적 스크립트 작성이 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;보완적 사용&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;eBPF로 syscall/네트워크 이벤트 수집 → OTel로 통합 시각화 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;성능 고려&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;실시간 후킹이지만, 너무 과도하게 사용하면 CPU/메모리 오버헤드 발생 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="6-요약"&gt;
 6️⃣ 요약
 &lt;a class="heading-anchor" href="#6-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;내용&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;이름&lt;/td&gt;
					&lt;td&gt;eBPF (extended Berkeley Packet Filter)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;역할&lt;/td&gt;
					&lt;td&gt;커널 레벨 실시간 트레이싱, 성능/보안/네트워크 모니터링&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;배포&lt;/td&gt;
					&lt;td&gt;Host Agent, Kubernetes DaemonSet 형태 가능&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;장점&lt;/td&gt;
					&lt;td&gt;거의 실시간, 커널 레벨 데이터, 오버헤드 낮음&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;개발자 포인트&lt;/td&gt;
					&lt;td&gt;심층 분석용, Observability 플랫폼과 결합 시 최적 활용 가능&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;💡 &lt;strong&gt;한 줄 기억:&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;eBPF = “커널/호스트 단위 실시간 모니터링·트레이싱 엔진”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;eBPF는 네트워크 패킷 필터링에서 시작하여, 보안, 성능 모니터링, 트레이싱 등 다양한 영역에 걸쳐 커널과 사용자 공간 사이의 경계를 허물며 중요한 역할을 하고 있다.&lt;/li&gt;
&lt;li&gt;이를 통해 시스템 관리자와 개발자들은 커널의 복잡한 부분을 안전하고 효율적으로 제어할 수 있으며, 다양한 문제를 실시간으로 해결할 수 있다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Install Kubernetes(v1.29.x) on Multipass</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-kubernetesv1.29.x-on-multipass/</link><pubDate>Tue, 15 Oct 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-kubernetesv1.29.x-on-multipass/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/linux-multipass/"&gt;Multipass 설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="cloud-init-yaml-구성"&gt;
 cloud-init yaml 구성
 &lt;a class="heading-anchor" href="#cloud-init-yaml-%ea%b5%ac%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="masteryaml"&gt;
 master.yaml
 &lt;a class="heading-anchor" href="#masteryaml" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;package_update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;package_upgrade&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;packages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;apt-transport-https&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ca-certificates&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;curl&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ntpdate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;runcmd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo swapoff -a&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo ntpdate ntp.ubuntu.com&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo systemctl enable containerd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo systemctl start containerd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo mkdir -p /etc/apt/keyrings&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;echo &amp;#34;deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /&amp;#34; | sudo tee /etc/apt/sources.list.d/kubernetes.list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo apt update&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo apt install -y kubelet kubeadm kubectl&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo apt-mark hold kubelet kubeadm kubectl&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo systemctl enable kubelet&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo kubeadm init&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mkdir -p /home/ubuntu/.kube&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo cp -i /etc/kubernetes/admin.conf /home/ubuntu/.kube/config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo chown -R ubuntu:ubuntu /home/ubuntu/.kube&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo kubeadm token create --print-join-command &amp;gt; /home/ubuntu/kubeadm_join_cmd.sh&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo chown ubuntu:ubuntu /home/ubuntu/kubeadm_join_cmd.sh&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;chmod +x /home/ubuntu/kubeadm_join_cmd.sh&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; sudo bash -c &amp;#39;cat &amp;lt;&amp;lt;EOF &amp;gt; /home/ubuntu/k8s-post-init.sh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; #!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; export KUBECONFIG=/home/ubuntu/.kube/config
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; sleep 60
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; kubectl taint nodes --all node-role.kubernetes.io/control-plane-
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; EOF&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo chown ubuntu:ubuntu /home/ubuntu/k8s-post-init.sh&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo chmod +x /home/ubuntu/k8s-post-init.sh&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo -u ubuntu /home/ubuntu/k8s-post-init.sh&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="kubeadm-세부-설정-참고"&gt;
 kubeadm 세부 설정 참고
 &lt;a class="heading-anchor" href="#kubeadm-%ec%84%b8%eb%b6%80-%ec%84%a4%ec%a0%95-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;pod 네트워크 CIDR 설정
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Calico 기반 구축&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pod-network-cidr=192.168.0.0/16&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Flannel 기반 구축&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pod-network-cidr=10.244.0.0/16&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cilium 기반 구축&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pod-network-cidr=10.0.0.0/8&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm init --pod-network-cidr&lt;span class="o"&gt;=&lt;/span&gt;10.244.0.0/12 --apiserver-advertise-address&lt;span class="o"&gt;=&lt;/span&gt;192.168.0.55&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--pod-network-cidr&lt;/code&gt; : pod 간 통신할 IP 주소를 지정&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--apiserver-advertise-address&lt;/code&gt; : Control-plane의 api-server가 사용할 IP 주소. 지정하지 않으면 default network interface 주소를 사용&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--service-cidr&lt;/code&gt; : Cluster 내에서 Application 간 통신을 위해 사용되며, 고유한 IP 주소를 가지게 된다. 기본값으로 10.96.0.0/12을 가진다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--pod-network-cidr&lt;/code&gt; 과 &lt;code&gt;--service-cidr&lt;/code&gt; 주소를 겹치지 않게 설정. 겹칠 경우 Kubernetes가 중복되지 않게 배치함&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="workeryaml"&gt;
 worker.yaml
 &lt;a class="heading-anchor" href="#workeryaml" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;package_update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;package_upgrade&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;packages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;apt-transport-https&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ca-certificates&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;curl&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ntpdate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;runcmd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo swapoff -a&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo ntpdate ntp.ubuntu.com&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo systemctl enable containerd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo systemctl start containerd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo mkdir -p /etc/apt/keyrings&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;echo &amp;#34;deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /&amp;#34; | sudo tee /etc/apt/sources.list.d/kubernetes.list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo apt update&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo apt install -y kubelet kubeadm kubectl&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sudo systemctl enable kubelet&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="instance-생성"&gt;
 Instance 생성
 &lt;a class="heading-anchor" href="#instance-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass launch focal --name mp-master --memory 4G --disk 50G --cpus &lt;span class="m"&gt;2&lt;/span&gt; --cloud-init mp-master.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;multipass launch focal --name mp-master --memory 4G --disk 50G --cpus &lt;span class="m"&gt;2&lt;/span&gt; --network &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multipass,mode&lt;span class="o"&gt;=&lt;/span&gt;manual
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;multipass launch focal --name mp-worker-1 --memory 4G --disk 50G --cpus &lt;span class="m"&gt;2&lt;/span&gt; --cloud-init mp-worker.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;multipass launch focal --name mp-worker-1 --memory 4G --disk 50G --cpus &lt;span class="m"&gt;2&lt;/span&gt; --network &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multipass,mode&lt;span class="o"&gt;=&lt;/span&gt;manual
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;multipass launch focal --name mp-worker-2 --memory 4G --disk 50G --cpus &lt;span class="m"&gt;2&lt;/span&gt; --cloud-init mp-worker.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;multipass launch focal --name mp-worker-2 --memory 4G --disk 50G --cpus &lt;span class="m"&gt;2&lt;/span&gt; --network &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multipass,mode&lt;span class="o"&gt;=&lt;/span&gt;manual&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="network---static-ip"&gt;
 Network - Static IP
 &lt;a class="heading-anchor" href="#network---static-ip" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="network-for-windows"&gt;
 Network for Windows
 &lt;a class="heading-anchor" href="#network-for-windows" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;관리자 권한 파워쉘에서 실행.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 고정된 Switch와 인터넷 통신을 위한 NAT 를 생성한다. 172.16.0.1/16&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;New-VMSwitch -SwitchName &lt;span class="s2"&gt;&amp;#34;MySwitch&amp;#34;&lt;/span&gt; -SwitchType Internal
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;New-NetIPAddress -IPAddress 172.16.0.1 -PrefixLength &lt;span class="m"&gt;16&lt;/span&gt; -InterfaceAlias &lt;span class="s2"&gt;&amp;#34;vEthernet (MySwitch)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;New-NetNat -Name &lt;span class="s2"&gt;&amp;#34;NATNetwork&amp;#34;&lt;/span&gt; -InternalIPInterfaceAddressPrefix &lt;span class="s2"&gt;&amp;#34;172.16.0.1/16&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# mutipass launch 시 network 를 추가한다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;multipass launch -n mp-master -c &lt;span class="m"&gt;2&lt;/span&gt; -m 2G -d 20G --network &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;MySwitch focal&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;생성한 VM 접속하여 아래와 같이 설정 및 추가&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo vi /etc/netplan/50-cloud-init.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ethernets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eth0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;macaddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;52&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;54&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="l"&gt;f1:f0:e8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;set-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;eth0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;추가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eth1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;192.168.0.55&lt;/span&gt;&lt;span class="l"&gt;/24]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;via&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.0.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nameservers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;8.8.8.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1.1.1.1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--network name=multipass,mode=manual&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ethernets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eth0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;macaddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;52&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;54&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="l"&gt;6b:21&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;set-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;eth0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;추가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eth1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;192.168.0.55&lt;/span&gt;&lt;span class="l"&gt;/24]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gateway4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.0.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;no&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--network name=multipass&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ethernets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;macaddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;52&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;54&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;25&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="l"&gt;1d:ab&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extra0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4-overrides&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;route-metric&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;macaddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;52&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;54&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;13&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;61&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;추가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eth1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;192.168.0.55&lt;/span&gt;&lt;span class="l"&gt;/24]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gateway4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.0.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;no&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;worker Node에도 추가&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ethernets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eth0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;macaddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;52&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;54&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="l"&gt;6b:21&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;set-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;eth0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;추가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;eth1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;192.168.0.56&lt;/span&gt;&lt;span class="l"&gt;/24]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gateway4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.0.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dhcp4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;no&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="restart-network"&gt;
 Restart Network
 &lt;a class="heading-anchor" href="#restart-network" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;아래와 같이 network 적용 또는 instance를 재시작
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo netplan apply&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="network-for-macos"&gt;
 Network for MacOS
 &lt;a class="heading-anchor" href="#network-for-macos" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Mac Terminal에서 아래와 같이 설정 및 추가
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;sudo vi /var/db/dhcpd_leases
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mp-master
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;ip_address&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;192.168.64.55
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;hw_address&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ff,f1:f5:dd:7f:0:2:0:0:ab:11:fa:4c:c0:e7:17:a6:ae:9a
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;identifier&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ff,f1:f5:dd:7f:0:2:0:0:ab:11:fa:4c:c0:e7:17:a6:ae:9a
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;lease&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0x671d9fc1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mp-worker-1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;ip_address&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;192.168.64.56
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;hw_address&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ff,f1:f5:dd:7f:0:2:0:0:ab:11:50:ed:1b:91:59:3e:45:b4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;identifier&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ff,f1:f5:dd:7f:0:2:0:0:ab:11:50:ed:1b:91:59:3e:45:b4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;lease&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0x671daf7a
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="restart-instance"&gt;
 Restart Instance
 &lt;a class="heading-anchor" href="#restart-instance" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass restart mp-master
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;multipass restart mp-worker-1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="add-cluster-node--join"&gt;
 Add Cluster Node : Join
 &lt;a class="heading-anchor" href="#add-cluster-node--join" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;kubeadm_join_cmd.sh 파일 받아서 worker로 전송&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass transfer mp-master:/home/ubuntu/kubeadm_join_cmd.sh ./
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;multipass transfer kubeadm_join_cmd.sh mp-worker-1:/home/ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;multipass transfer kubeadm_join_cmd.sh mp-worker-2:/home/ubuntu&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;각 worker 접속하여 join&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kubeadm_join_cmd.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Flutter] RootTab</title><link>https://kyungryeol-yoon.github.io/frontend/flutter/root-tab/</link><pubDate>Sun, 15 Sep 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/frontend/flutter/root-tab/</guid><description>&lt;h2 id="roottab"&gt;
 RootTab
 &lt;a class="heading-anchor" href="#roottab" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;정의&lt;/strong&gt;: 일반적으로 &amp;ldquo;RootTab&amp;quot;은 여러 개의 탭을 상단에 배치하여 사용자가 여러 화면을 쉽게 전환할 수 있게 하는 UI 구성 요소를 의미한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;구성&lt;/strong&gt;: 각 탭은 사용자가 선택할 수 있는 특정 항목을 나타낸다. 이 탭은 일반적으로 TabBar 위젯을 통해 생성된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tabbarview"&gt;
 TabBarView
 &lt;a class="heading-anchor" href="#tabbarview" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;정의&lt;/strong&gt;: TabBarView는 TabBar와 함께 사용되는 위젯으로, 각 탭에 해당하는 내용을 표시한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;구성&lt;/strong&gt;: TabBarView는 여러 개의 자식 위젯을 받아서 각 탭이 선택될 때 보여줄 내용을 정의한다. 각 탭에 대해 해당하는 콘텐츠를 작성할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/tab-bar-view"&gt;설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="flutter-프로젝트-생성"&gt;
 Flutter 프로젝트 생성
 &lt;a class="heading-anchor" href="#flutter-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;코드 복사
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;flutter create my_app
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; my_app&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="필요한-패키지-추가"&gt;
 필요한 패키지 추가
 &lt;a class="heading-anchor" href="#%ed%95%84%ec%9a%94%ed%95%9c-%ed%8c%a8%ed%82%a4%ec%a7%80-%ec%b6%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;기본적으로 material.dart만 있으면 충분하다.&lt;/li&gt;
&lt;li&gt;추가적인 패키지는 필요하지 않다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="기본-ui-구성"&gt;
 기본 UI 구성
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-ui-%ea%b5%ac%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;lib/main.dart 파일을 열고 아래의 코드를 작성한다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;package:flutter/material.dart&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;runApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyApp&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;MaterialApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Flutter Tab Example&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;home:&lt;/span&gt; &lt;span class="n"&gt;HomeScreen&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HomeScreen&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;DefaultTabController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;length:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 탭의 개수
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Root Tab Example&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;bottom:&lt;/span&gt; &lt;span class="n"&gt;TabBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;tabs:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Tab 1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Tab 2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Tab 3&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;TabBarView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Content for Tab 1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Content for Tab 2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Content for Tab 3&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="코드-설명"&gt;
 코드 설명
 &lt;a class="heading-anchor" href="#%ec%bd%94%eb%93%9c-%ec%84%a4%eb%aa%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;main() 함수&lt;/strong&gt;: 애플리케이션의 진입점이다. runApp(MyApp())를 통해 Flutter 앱을 실행한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MyApp 클래스&lt;/strong&gt;: MaterialApp 위젯으로 앱의 기본적인 스타일을 제공한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="homescreen-클래스"&gt;
 HomeScreen 클래스
 &lt;a class="heading-anchor" href="#homescreen-%ed%81%b4%eb%9e%98%ec%8a%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DefaultTabController&lt;/strong&gt;: 탭을 관리하는 컨트롤러로, 탭의 개수를 length 속성으로 지정한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scaffold&lt;/strong&gt;: 앱의 기본 레이아웃을 제공하는 위젯이다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AppBar&lt;/strong&gt;: 상단에 위치하며, 앱의 제목과 TabBar를 포함한다. TabBar는 각각의 탭을 정의한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TabBar&lt;/strong&gt;: 각 탭을 표시하는 위젯으로, Tab 위젯을 리스트로 포함한다. 여기서는 3개의 탭을 정의했다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TabBarView&lt;/strong&gt;: 각 탭에 대한 내용을 표시하는 위젯이다. children 속성에는 각 탭에 맞는 위젯을 포함한다. 여기서는 각 탭에 대한 간단한 텍스트를 사용했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="실행하기"&gt;
 실행하기
 &lt;a class="heading-anchor" href="#%ec%8b%a4%ed%96%89%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;flutter run&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="탭-사용하기"&gt;
 탭 사용하기
 &lt;a class="heading-anchor" href="#%ed%83%ad-%ec%82%ac%ec%9a%a9%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;앱이 실행되면 상단에 3개의 탭이 표시된다.&lt;/li&gt;
&lt;li&gt;각 탭을 클릭하면 해당하는 내용이 아래에 표시된다.&lt;/li&gt;
&lt;li&gt;이로써 기본적인 Root Tab 구성이 완료되었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="추가-기능"&gt;
 추가 기능
 &lt;a class="heading-anchor" href="#%ec%b6%94%ea%b0%80-%ea%b8%b0%eb%8a%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;탭 아이콘 추가: 각 탭에 아이콘을 추가할 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="n"&gt;Icon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Icons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Tab 1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;탭 간 전환 애니메이션&lt;/strong&gt;: 기본적으로 Flutter에서 제공하는 전환 애니메이션을 사용하여 사용자 경험을 향상시킬 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;상태 관리&lt;/strong&gt;: 탭 간의 상태를 유지하기 위해 상태 관리 라이브러리(예: Provider, Riverpod)를 사용할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Flutter] TabBarView</title><link>https://kyungryeol-yoon.github.io/frontend/flutter/tab-bar-view/</link><pubDate>Thu, 12 Sep 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/frontend/flutter/tab-bar-view/</guid><description>&lt;h2 id="roottab"&gt;
 RootTab
 &lt;a class="heading-anchor" href="#roottab" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;정의&lt;/strong&gt;: 일반적으로 &amp;ldquo;RootTab&amp;quot;은 여러 개의 탭을 상단에 배치하여 사용자가 여러 화면을 쉽게 전환할 수 있게 하는 UI 구성 요소를 의미한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;구성&lt;/strong&gt;: 각 탭은 사용자가 선택할 수 있는 특정 항목을 나타낸다. 이 탭은 일반적으로 TabBar 위젯을 통해 생성된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/root-tab"&gt;설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="tabbarview"&gt;
 TabBarView
 &lt;a class="heading-anchor" href="#tabbarview" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;정의&lt;/strong&gt;: TabBarView는 TabBar와 함께 사용되는 위젯으로, 각 탭에 해당하는 내용을 표시한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;구성&lt;/strong&gt;: TabBarView는 여러 개의 자식 위젯을 받아서 각 탭이 선택될 때 보여줄 내용을 정의한다. 각 탭에 대해 해당하는 콘텐츠를 작성할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="tabbarview-정의"&gt;
 TabBarView 정의
 &lt;a class="heading-anchor" href="#tabbarview-%ec%a0%95%ec%9d%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;TabBarView는 여러 개의 자식 위젯을 받아서 각 탭이 선택될 때 보여줄 내용을 정의한다.&lt;/li&gt;
&lt;li&gt;이 위젯은 TabBar와 함께 사용되어 탭 인터페이스를 구성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;TabBarView의 기본적인 구조는 다음과 같다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;TabBarView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 각 탭에 해당하는 위젯
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Content for Tab 1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Content for Tab 2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Content for Tab 3&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="주요-속성"&gt;
 주요 속성
 &lt;a class="heading-anchor" href="#%ec%a3%bc%ec%9a%94-%ec%86%8d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;children&lt;/strong&gt;: TabBarView에서 표시할 위젯들의 리스트이다. 각 탭에 해당하는 콘텐츠를 포함한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용-예시"&gt;
 사용 예시
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;아래는 TabBar와 TabBarView를 함께 사용한 기본적인 예시이다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;package:flutter/material.dart&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;runApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyApp&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;MaterialApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;TabBarView Example&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;home:&lt;/span&gt; &lt;span class="n"&gt;DefaultTabController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;length:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 탭의 개수
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;TabBarView Example&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;bottom:&lt;/span&gt; &lt;span class="n"&gt;TabBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;tabs:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Tab 1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Tab 2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Tab 3&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;TabBarView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Content for Tab 1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Content for Tab 2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Content for Tab 3&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="코드-설명"&gt;
 코드 설명
 &lt;a class="heading-anchor" href="#%ec%bd%94%eb%93%9c-%ec%84%a4%eb%aa%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DefaultTabController&lt;/strong&gt;: TabBar와 TabBarView의 상태를 관리한다. length 속성은 탭의 개수를 설정한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TabBar&lt;/strong&gt;: 상단에 표시되는 탭으로, 사용자가 선택할 수 있는 각 항목을 나타낸다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TabBarView&lt;/strong&gt;: children 리스트에 포함된 각 위젯이 탭 선택에 따라 표시된다. 각 탭에 대한 콘텐츠를 정의할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="탭-전환-애니메이션"&gt;
 탭 전환 애니메이션
 &lt;a class="heading-anchor" href="#%ed%83%ad-%ec%a0%84%ed%99%98-%ec%95%a0%eb%8b%88%eb%a9%94%ec%9d%b4%ec%85%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;TabBarView는 기본적으로 탭 간 전환 애니메이션을 제공한다.&lt;/li&gt;
&lt;li&gt;사용자가 탭을 클릭할 때마다 애니메이션 효과가 자동으로 적용되어 부드러운 전환을 경험할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="상태-관리"&gt;
 상태 관리
 &lt;a class="heading-anchor" href="#%ec%83%81%ed%83%9c-%ea%b4%80%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;탭 간의 상태를 유지하고 싶다면, 각 탭에서 상태를 관리하는 방식
&lt;ul&gt;
&lt;li&gt;예: StatefulWidget, Provider, Riverpod 등을 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;예를 들어, 각 탭에 대한 상태를 관리하는 별도의 StatefulWidget을 만들 수도 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="스크롤-가능한-tabbarview"&gt;
 스크롤 가능한 TabBarView
 &lt;a class="heading-anchor" href="#%ec%8a%a4%ed%81%ac%eb%a1%a4-%ea%b0%80%eb%8a%a5%ed%95%9c-tabbarview" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;대량의 콘텐츠를 다룰 경우 TabBarView를 스크롤 가능하도록 설정할 수 있다.
&lt;ul&gt;
&lt;li&gt;예를 들어, SingleChildScrollView와 함께 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Flutter] Drawer</title><link>https://kyungryeol-yoon.github.io/frontend/flutter/drawer/</link><pubDate>Tue, 10 Sep 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/frontend/flutter/drawer/</guid><description>&lt;h3 id="기본-flutter-프로젝트-설정"&gt;
 기본 Flutter 프로젝트 설정
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-flutter-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Flutter 프로젝트를 생성하고 필요한 패키지를 추가
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;flutter create my_app
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; my_app&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="drawer-추가"&gt;
 Drawer 추가
 &lt;a class="heading-anchor" href="#drawer-%ec%b6%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;lib/main.dart&lt;/code&gt; 파일 수정&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이제 &lt;code&gt;lib/main.dart&lt;/code&gt; 파일을 열어 기본적인 UI를 구성한다. 아래의 코드를 추가&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;package:flutter/material.dart&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;runApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyApp&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;MaterialApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Flutter Drawer Demo&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;home:&lt;/span&gt; &lt;span class="n"&gt;HomeScreen&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;main() 함수&lt;/strong&gt;: Flutter 애플리케이션의 진입점이다. runApp() 함수를 호출하여 위젯 트리를 시작한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MyApp 클래스&lt;/strong&gt;: 애플리케이션의 루트 위젯을 정의한다. MaterialApp 위젯을 사용하여 기본적인 Material Design 스타일을 제공한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="homescreen-클래스-추가"&gt;
 HomeScreen 클래스 추가
 &lt;a class="heading-anchor" href="#homescreen-%ed%81%b4%eb%9e%98%ec%8a%a4-%ec%b6%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;다음으로, HomeScreen 클래스를 추가하여 Drawer를 포함한 화면을 정의
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HomeScreen&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Drawer Example&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;drawer:&lt;/span&gt; &lt;span class="n"&gt;Drawer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;padding:&lt;/span&gt; &lt;span class="n"&gt;EdgeInsets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Widget&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DrawerHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;Drawer Header&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;style:&lt;/span&gt; &lt;span class="n"&gt;TextStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;white&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;fontSize:&lt;/span&gt; &lt;span class="m"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;decoration:&lt;/span&gt; &lt;span class="n"&gt;BoxDecoration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ListTile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;leading:&lt;/span&gt; &lt;span class="n"&gt;Icon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Icons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Home&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;onTap:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Drawer 닫기
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ListTile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;leading:&lt;/span&gt; &lt;span class="n"&gt;Icon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Icons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Settings&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;onTap:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Drawer 닫기
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ListTile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;leading:&lt;/span&gt; &lt;span class="n"&gt;Icon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Icons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;About&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;onTap:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Drawer 닫기
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Home Screen&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="scaffold-구성-요소-설명"&gt;
 Scaffold 구성 요소 설명
 &lt;a class="heading-anchor" href="#scaffold-%ea%b5%ac%ec%84%b1-%ec%9a%94%ec%86%8c-%ec%84%a4%eb%aa%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Scaffold&lt;/strong&gt;: Flutter에서 기본적인 레이아웃 구조를 제공하는 위젯이다. appBar, drawer, body 등의 속성을 사용하여 앱의 구조를 설정한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AppBar&lt;/strong&gt;: 화면 상단에 위치하며, 앱의 제목이나 액션 버튼을 포함할 수 있다. 여기서는 &amp;ldquo;Drawer Example&amp;quot;이라는 제목을 표시한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Drawer&lt;/strong&gt;: 왼쪽에서 슬라이드 방식으로 열리는 사이드 메뉴이다. 이 안에 여러 개의 ListTile을 배치하여 메뉴 항목을 나열한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ListView&lt;/strong&gt;: 스크롤 가능한 리스트를 생성한다. padding: EdgeInsets.zero를 통해 기본 패딩을 제거한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DrawerHeader&lt;/strong&gt;: 드로어의 헤더 부분으로, 주로 사용자 프로필이나 앱 이름 등을 표시한다. 배경색과 텍스트 스타일을 설정할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ListTile&lt;/strong&gt;: 각 메뉴 항목을 구성하는 위젯이다. leading 속성을 사용하여 아이콘을 추가하고, title 속성으로 텍스트를 설정한다. onTap 속성에는 해당 항목을 클릭했을 때 실행될 동작을 정의한다. 여기서는 Drawer를 닫기 위해 Navigator.pop(context)를 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="실행"&gt;
 실행
 &lt;a class="heading-anchor" href="#%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;코드 복사
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;flutter run&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="drawer-열기"&gt;
 Drawer 열기
 &lt;a class="heading-anchor" href="#drawer-%ec%97%b4%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;앱이 실행되면, 화면의 왼쪽 상단에 있는 아이콘을 클릭하면 Drawer가 열린다.&lt;/li&gt;
&lt;li&gt;Drawer 안에는 &lt;code&gt;Home&lt;/code&gt;, &lt;code&gt;Settings&lt;/code&gt;, &lt;code&gt;About&lt;/code&gt;라는 항목이 표시된다.&lt;/li&gt;
&lt;li&gt;각 항목을 클릭하면 Navigator.pop(context)에 의해 Drawer가 닫힌다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="추가-기능"&gt;
 추가 기능
 &lt;a class="heading-anchor" href="#%ec%b6%94%ea%b0%80-%ea%b8%b0%eb%8a%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;항목 클릭 시 페이지 전환: 각 ListTile의 onTap에서 페이지를 전환하도록 추가적인 코드를 작성할 수 있다.
&lt;ul&gt;
&lt;li&gt;예를 들어, 새로운 화면으로 이동할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;상태 관리: 복잡한 앱에서는 Drawer의 상태를 관리하기 위해 상태 관리 라이브러리를 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Android] SDK Manager</title><link>https://kyungryeol-yoon.github.io/frontend/android/install-android-sdk-manager/</link><pubDate>Sat, 07 Sep 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/frontend/android/install-android-sdk-manager/</guid><description>&lt;h2 id="sdk-manager"&gt;
 SDK Manager
 &lt;a class="heading-anchor" href="#sdk-manager" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Android 개발에 필요한 소프트웨어 개발 키트(Software Development Kit) 및 관련 도구, 플랫폼 및 시스템 이미지를 설치하고 관리하는 도구&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="주요-기능"&gt;
 주요 기능
 &lt;a class="heading-anchor" href="#%ec%a3%bc%ec%9a%94-%ea%b8%b0%eb%8a%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;SDK 및 도구 설치&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Android SDK Manager를 통해 Android 버전에 맞는 SDK 플랫폼, 빌드 도구, 플랫폼 도구, 시스템 이미지 등을 다운로드하고 설치할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;strong&gt;라이브러리 및 추가 컴포넌트 관리&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;필요한 라이브러리, 추가 도구, 시스템 이미지 등을 SDK Manager를 통해 쉽게 관리할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;strong&gt;SDK 버전 및 플랫폼 업데이트&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;새로운 Android 버전이나 플랫폼 도구가 출시되면 SDK Manager를 통해 업데이트를 받고 새로운 기능 및 개선 사항을 활용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="4"&gt;
&lt;li&gt;&lt;strong&gt;가상 디바이스 생성 및 관리&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;SDK Manager를 사용하여 가상 디바이스에 사용할 수 있는 다양한 시스템 이미지를 설치하고 관리할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="5"&gt;
&lt;li&gt;&lt;strong&gt;라이선스 관리&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Android SDK Manager를 통해 필요한 라이선스를 수락하고 관리할 수 있다. 명령행 도구로도 사용 가능하며, 명령행에서는 &lt;strong&gt;sdkmanager&lt;/strong&gt;를 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="6"&gt;
&lt;li&gt;&lt;strong&gt;안드로이드 스튜디오와의 통합&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Android SDK Manager는 주로 안드로이드 스튜디오(Android Studio)와 함께 사용되며, 스튜디오에서도 SDK 관리 기능이 일부 내장되어 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="android-sdk-설치"&gt;
 Android SDK 설치
 &lt;a class="heading-anchor" href="#android-sdk-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Andriod Studio 실행&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;More Actions ➡️ SDK Manager&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Edit&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SDK Components Setup&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Andriod SDK&lt;/li&gt;
&lt;li&gt;Android SDK Platform&lt;/li&gt;
&lt;li&gt;Android API 34(Version)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="cmdline-tools-설치"&gt;
 cmdline tools 설치
 &lt;a class="heading-anchor" href="#cmdline-tools-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Andriod Studio 실행&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;More Actions ➡️ SDK Manager&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SDK Tools&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Android SDK Command-line Tools&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;이 도구가 있어야 CLI (명령어)로 설정을 할 수 있다.
{: .prompt-warning }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;flutter doctor --android-licenses&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Flutter] Google Login</title><link>https://kyungryeol-yoon.github.io/frontend/flutter/google-login/</link><pubDate>Thu, 29 Aug 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/frontend/flutter/google-login/</guid><description>&lt;h3 id="flutter-프로젝트-설정"&gt;
 Flutter 프로젝트 설정
 &lt;a class="heading-anchor" href="#flutter-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;flutter create my_project
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; my_project&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="firebase-설정"&gt;
 Firebase 설정
 &lt;a class="heading-anchor" href="#firebase-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Firebase Console에 가서 새 프로젝트를 생성한다.&lt;/li&gt;
&lt;li&gt;안드로이드 앱을 추가한다.&lt;/li&gt;
&lt;li&gt;패키지 이름을 입력합니다.
- 예: com.example.my_project&lt;/li&gt;
&lt;li&gt;google-services.json 파일을 다운로드한다.&lt;/li&gt;
&lt;li&gt;다운로드한 google-services.json 파일을 android/app Directory에 추가한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="dependencies-추가"&gt;
 Dependencies 추가
 &lt;a class="heading-anchor" href="#dependencies-%ec%b6%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;pubspec.yaml 파일을 열고 google_sign_in과 firebase_auth 패키지를 추가한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;flutter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;sdk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;flutter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;google_sign_in&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;^6.1.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;firebase_auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;^4.5.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;firebase_core&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;^2.16.0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그런 다음, 패키지를 설치한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;flutter pub get&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="android-설정"&gt;
 Android 설정
 &lt;a class="heading-anchor" href="#android-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;android/build.gradle&lt;/code&gt; 파일을 열고 classpath에 Google 서비스 플러그인을 추가한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-groovy" data-lang="groovy"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;buildscript&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="err"&gt;✂&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;classpath&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;com.google.gms:google-services:4.3.15&amp;#39;&lt;/span&gt; &lt;span class="c1"&gt;// 최신 버전 확인
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그 다음 &lt;code&gt;android/app/build.gradle&lt;/code&gt; 파일을 열고 아래를 추가한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-groovy" data-lang="groovy"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="nl"&gt;plugin:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;com.google.gms.google-services&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;android&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="err"&gt;✂&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;defaultConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="err"&gt;✂&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;minSdkVersion&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="firebase-초기화"&gt;
 Firebase 초기화
 &lt;a class="heading-anchor" href="#firebase-%ec%b4%88%ea%b8%b0%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;lib/main.dart&lt;/code&gt; 파일을 열고 Firebase를 초기화한다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;package:flutter/material.dart&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;package:firebase_core/firebase_core.dart&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;package:google_sign_in/google_sign_in.dart&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;package:firebase_auth/firebase_auth.dart&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;WidgetsFlutterBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ensureInitialized&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;initializeApp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;runApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyApp&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;MaterialApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;home:&lt;/span&gt; &lt;span class="n"&gt;SignInScreen&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="google-로그인-기능-구현"&gt;
 Google 로그인 기능 구현
 &lt;a class="heading-anchor" href="#google-%eb%a1%9c%ea%b7%b8%ec%9d%b8-%ea%b8%b0%eb%8a%a5-%ea%b5%ac%ed%98%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;SignInScreen 클래스를 추가하여 Google 로그인 기능을 구현한다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SignInScreen&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;GoogleSignIn&lt;/span&gt; &lt;span class="n"&gt;googleSignIn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GoogleSignIn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;FirebaseAuth&lt;/span&gt; &lt;span class="n"&gt;firebaseAuth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FirebaseAuth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_signInWithGoogle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;GoogleSignInAccount&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;googleUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;await&lt;/span&gt; &lt;span class="n"&gt;googleSignIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;GoogleSignInAuthentication&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;googleAuth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;await&lt;/span&gt; &lt;span class="n"&gt;googleUser&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;authentication&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;AuthCredential&lt;/span&gt; &lt;span class="n"&gt;credential&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GoogleAuthProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;accessToken:&lt;/span&gt; &lt;span class="n"&gt;googleAuth&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;idToken:&lt;/span&gt; &lt;span class="n"&gt;googleAuth&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;idToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;UserCredential&lt;/span&gt; &lt;span class="n"&gt;userCredential&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;await&lt;/span&gt; &lt;span class="n"&gt;firebaseAuth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signInWithCredential&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;userCredential&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Google Sign In&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;ElevatedButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_signInWithGoogle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;로그인 성공: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;displayName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Google로 로그인&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="권한-설정"&gt;
 권한 설정
 &lt;a class="heading-anchor" href="#%ea%b6%8c%ed%95%9c-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;AndroidManifest.xml 파일에 인터넷 권한을 추가한다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;uses-permission&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;android.permission.INTERNET&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Deploy MinIO</title><link>https://kyungryeol-yoon.github.io/kubernetes/storage/kubernetes-deploy-minio/</link><pubDate>Mon, 26 Aug 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/storage/kubernetes-deploy-minio/</guid><description>&lt;h2 id="create-minio-object"&gt;
 Create MinIO Object
 &lt;a class="heading-anchor" href="#create-minio-object" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl https://raw.githubusercontent.com/minio/docs/master/source/extra/examples/minio-dev.yaml -O&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Deploys a new Namespace for the MinIO Pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;minio-dev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Change this value if you want a different namespace name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;minio-dev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Change this value to match metadata.name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Deploys a new MinIO Pod into the metadata.namespace Kubernetes namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;#&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# The `spec.containers[0].args` contains the command run on the pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# The `/data` directory corresponds to the `spec.containers[0].volumeMounts[0].mountPath`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# That mount path corresponds to a Kubernetes HostPath which binds `/data` to a local drive or volume on the worker node where the pod runs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# &lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;minio&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;minio&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;minio-dev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Change this value to match the namespace metadata.name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;minio&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;quay.io/minio/minio:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;/bin/bash&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- -&lt;span class="l"&gt;c&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;minio server /data --console-address :9001&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;localvolume&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Corresponds to the `spec.volumes` Persistent Volume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubernetes.io/hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubealpha.local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Specify a node label associated to the Worker Node on which you want to deploy the pod.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;localvolume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# MinIO generally recommends using locally-attached volumes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/mnt/disk1/data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Specify a path to a local drive or volume on the Kubernetes worker node&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;DirectoryOrCreate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# The path to the last directory must exist&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;minio 설치 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://min.io/docs/minio/kubernetes/upstream/index.html"&gt;https://min.io/docs/minio/kubernetes/upstream/index.html&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="apply-the-minio-object-definition"&gt;
 Apply the MinIO Object Definition
 &lt;a class="heading-anchor" href="#apply-the-minio-object-definition" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The following command applies the minio-dev.yaml configuration and deploys the objects to Kubernetes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f minio-dev.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The command output should resemble the following:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;namespace/minio-dev created
pod/minio created&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can verify the state of the pod by running kubectl get pods:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl get pods -n minio-dev&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The output should resemble the following:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;NAME READY STATUS RESTARTS AGE
minio 1/1 Running 0 77s&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can also use the following commands to retrieve detailed information on the pod status:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl describe pod/minio -n minio-dev

kubectl logs pod/minio -n minio-dev&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="temporarily-access-the-minio-s3-api-and-console"&gt;
 Temporarily Access the MinIO S3 API and Console
 &lt;a class="heading-anchor" href="#temporarily-access-the-minio-s3-api-and-console" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Use the kubectl port-forward command to temporarily forward traffic from the MinIO pod to the local machine:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl port-forward pod/minio 9000 9090 -n minio-dev&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The command forwards the pod ports 9000 and 9090 to the matching port on the local machine while active in the shell. The kubectl port-forward command only functions while active in the shell session. Terminating the session closes the ports on the local machine.&lt;/p&gt;
&lt;p&gt;Note
The following steps of this procedure assume an active kubectl port-forward command.
To configure long term access to the pod, configure Ingress or similar network control components within Kubernetes to route traffic to and from the pod. Configuring Ingress is out of the scope for this documentation.&lt;/p&gt;
&lt;h2 id="connect-your-browser-to-the-minio-server"&gt;
 Connect your Browser to the MinIO Server
 &lt;a class="heading-anchor" href="#connect-your-browser-to-the-minio-server" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Access the MinIO Console by opening a browser on the local machine and navigating to &lt;a href="http://127.0.0.1:9001"&gt;http://127.0.0.1:9001&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Log in to the Console with the credentials minioadmin | minioadmin. These are the default root user credentials.&lt;/p&gt;</description></item><item><title>[Flutter] SDK</title><link>https://kyungryeol-yoon.github.io/frontend/flutter/install-flutter-sdk/</link><pubDate>Sat, 24 Aug 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/frontend/flutter/install-flutter-sdk/</guid><description>&lt;p&gt;&lt;strong&gt;Google에서 개발한 오픈 소스 프레임워크로, 모바일 앱뿐만 아니라 웹 및 데스크톱 앱까지 다양한 플랫폼에서 동작하는 크로스 플랫폼 앱을 개발하는 도구&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="sdk-software-development-kit--소프트웨어-개발-키트"&gt;
 SDK (Software Development Kit) : 소프트웨어 개발 키트
 &lt;a class="heading-anchor" href="#sdk-software-development-kit--%ec%86%8c%ed%94%84%ed%8a%b8%ec%9b%a8%ec%96%b4-%ea%b0%9c%eb%b0%9c-%ed%82%a4%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;특정한 소프트웨어를 개발하기 위해 필요한 도구, 라이브러리, 문서, 샘플 코드 등이 포함된 패키지이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="flutter-sdk-특징"&gt;
 Flutter SDK 특징
 &lt;a class="heading-anchor" href="#flutter-sdk-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Dart 언어:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;플러터 앱을 개발하기 위한 주 언어는 Dart. Dart는 간결하고 생산적인 언어로, 플러터 앱의 비즈니스 로직과 UI를 함께 다룰 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;strong&gt;위젯:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;플러터는 위젯을 기반으로 하는 UI 개발을 지원한다. 위젯은 화면에 표시되는 모든 것을 나타내며, 텍스트, 버튼, 이미지 등 다양한 형태의 위젯을 조합하여 UI를 구성할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;strong&gt;호환성:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;플러터는 iOS와 Android뿐만 아니라 웹 및 데스크톱 플랫폼에도 빌드할 수 있는 크로스 플랫폼 개발을 지원한다. 이는 개발자가 하나의 코드베이스로 여러 플랫폼에서 동일한 앱을 실행할 수 있도록 해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="4"&gt;
&lt;li&gt;&lt;strong&gt;빠른 개발:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;플러터는 Hot Reload 기능을 제공하여 앱의 변경 사항을 실시간으로 반영하고 테스트할 수 있다. 이는 빠른 개발 주기를 지원하여 생산성을 향상시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="5"&gt;
&lt;li&gt;&lt;strong&gt;Material Design 및 Cupertino 스타일:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;플러터는 Material Design(Android) 및 Cupertino(iOS)와 호환되는 미리 디자인된 스타일과 위젯을 제공하여 각 플랫폼의 네이티브한 룩앤필을 쉽게 구현할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="6"&gt;
&lt;li&gt;&lt;strong&gt;다양한 패키지 및 플러그인:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;플러터는 다양한 패키지와 플러그인을 제공하여 네트워크 통신, 데이터베이스 연동, 상태 관리 등 다양한 기능을 쉽게 추가할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Install Flutter&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.flutter.dev/get-started/install"&gt;https://docs.flutter.dev/get-started/install&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="flutter-시스템-환경-변수-설정"&gt;
 &lt;strong&gt;flutter 시스템 환경 변수 설정&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#flutter-%ec%8b%9c%ec%8a%a4%ed%85%9c-%ed%99%98%ea%b2%bd-%eb%b3%80%ec%88%98-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&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;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Path&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;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;~/설치경로/flutter/bin (입력)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;[확인]&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="flutter-doctor-실행하기"&gt;
 flutter doctor 실행하기
 &lt;a class="heading-anchor" href="#flutter-doctor-%ec%8b%a4%ed%96%89%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="flutter-doctor"&gt;
 &lt;strong&gt;flutter doctor?&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#flutter-doctor" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;개발 환경의 설정 및 필수 구성 요소를 검사하고 문제를 해결하는 데 도움을 주는 명령어&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="heading"&gt;
 &lt;strong&gt;📂~/설치경로/flutter/bin&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#heading" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;cd ~/설치경로/flutter/bin&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;flutter doctor&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;Doctor summary &lt;span class="o"&gt;(&lt;/span&gt;to see all details, run flutter doctor -v&lt;span class="o"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;√&lt;span class="o"&gt;]&lt;/span&gt; Flutter &lt;span class="o"&gt;(&lt;/span&gt;Channel stable, 3.24.0, on Microsoft Windows &lt;span class="o"&gt;[&lt;/span&gt;Version 10.0.22631.4169&lt;span class="o"&gt;]&lt;/span&gt;, locale ko-KR&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;√&lt;span class="o"&gt;]&lt;/span&gt; Windows Version &lt;span class="o"&gt;(&lt;/span&gt;Installed version of Windows is version &lt;span class="m"&gt;10&lt;/span&gt; or higher&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;!&lt;span class="o"&gt;]&lt;/span&gt; Android toolchain - develop &lt;span class="k"&gt;for&lt;/span&gt; Android devices &lt;span class="o"&gt;(&lt;/span&gt;Android SDK version 35.0.0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; ! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;√&lt;span class="o"&gt;]&lt;/span&gt; Chrome - develop &lt;span class="k"&gt;for&lt;/span&gt; the web
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;X&lt;span class="o"&gt;]&lt;/span&gt; Visual Studio - develop Windows apps
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; X Visual Studio not installed&lt;span class="p"&gt;;&lt;/span&gt; this is necessary to develop Windows apps.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; Download at https://visualstudio.microsoft.com/downloads/.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; Please install the &lt;span class="s2"&gt;&amp;#34;Desktop development with C++&amp;#34;&lt;/span&gt; workload, including all of its default components
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;!&lt;span class="o"&gt;]&lt;/span&gt; Android Studio &lt;span class="o"&gt;(&lt;/span&gt;version 2022.2&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; X Unable to find bundled Java version.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;√&lt;span class="o"&gt;]&lt;/span&gt; Android Studio &lt;span class="o"&gt;(&lt;/span&gt;version 2024.1&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;√&lt;span class="o"&gt;]&lt;/span&gt; VS Code &lt;span class="o"&gt;(&lt;/span&gt;version 1.92.2&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;√&lt;span class="o"&gt;]&lt;/span&gt; Connected device &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; available&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;√&lt;span class="o"&gt;]&lt;/span&gt; Network resources
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;! Doctor found issues in &lt;span class="m"&gt;3&lt;/span&gt; categories.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="-표시로-나오는-부분은-추가로-설치할-항목이-필요하거나-설정이-필요한-내용"&gt;
 &lt;strong&gt;❌ 표시로 나오는 부분은 추가로 설치할 항목이 필요하거나 설정이 필요한 내용&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#-%ed%91%9c%ec%8b%9c%eb%a1%9c-%eb%82%98%ec%98%a4%eb%8a%94-%eb%b6%80%eb%b6%84%ec%9d%80-%ec%b6%94%ea%b0%80%eb%a1%9c-%ec%84%a4%ec%b9%98%ed%95%a0-%ed%95%ad%eb%aa%a9%ec%9d%b4-%ed%95%84%ec%9a%94%ed%95%98%ea%b1%b0%eb%82%98-%ec%84%a4%ec%a0%95%ec%9d%b4-%ed%95%84%ec%9a%94%ed%95%9c-%eb%82%b4%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;❌ cmdline-tools component is missing.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;➡️cmdline-tools 라는 플러그인 설치가 필요합니다.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;❌ Anroid license status unknown.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;➡️안드로이드 관련 라이센스 동의가 필요합니다.&lt;/strong&gt;
&lt;blockquote&gt;
&lt;p&gt;명령어를 입력하여 라이센스 동의를 하라고 알려주고 있는데, 먼저 명령어를 사용하기 위해서는 cmdline-tools 라는 플러그인이 설치되어야 명령어를 사용할 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;❌ Visual Studio not installed: this is necessary to develop Windows apps&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;➡️&lt;/strong&gt;Visual Studio 개발 앱이 설치되어 있지 않다. (Visual Studio를 사용하지 않는다면, 무시해도 좋다. cf. VS Code 와 다르다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="andriod-라이센스-승인"&gt;
 &lt;strong&gt;Andriod 라이센스 승인&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#andriod-%eb%9d%bc%ec%9d%b4%ec%84%bc%ec%8a%a4-%ec%8a%b9%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;flutter doctor --andriod-licenses&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Android &lt;strong&gt;sdkmanager&lt;/strong&gt; not found. Update to the latest Android SDK and ensure that the &lt;strong&gt;cmdline-tools&lt;/strong&gt; are installed to resolve this.
{: .prompt-danger }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="해결방법-sdk-manager-에서-cmdline-tools-설치"&gt;
 &lt;strong&gt;해결방법: SDK Manager 에서 cmdline-tools 설치&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ed%95%b4%ea%b2%b0%eb%b0%a9%eb%b2%95-sdk-manager-%ec%97%90%ec%84%9c-cmdline-tools-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/install-android-sdk-manager/"&gt;SDK Manager 설치 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Andriod Studio 실행&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;More Actions SDK Manager&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SDK Tools&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Android SDK Command-line Tools&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;이 도구가 있어야 CLI (명령어)로 설정을 할 수 있다.&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;flutter doctor --android-licenses&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Git] .gitignore 파일이 바로 적용이 안될 때 해결방법 : git 캐시 삭제</title><link>https://kyungryeol-yoon.github.io/devops/git/git-error-gitignore/</link><pubDate>Thu, 22 Aug 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/git/git-error-gitignore/</guid><description>&lt;h2 id="문제점"&gt;
 &lt;strong&gt;문제점&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%eb%ac%b8%ec%a0%9c%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;.gitignore 파일에 추가를 하고 확인해 보았지만 바로 적용이 되지 않은 문제점을 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="해결방법"&gt;
 &lt;strong&gt;해결방법&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ed%95%b4%ea%b2%b0%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;해당 명령어는 Git에서 Local 저장소에서 파일을 제거하지만 &lt;strong&gt;실제 파일은 유지&lt;/strong&gt;되며 Commit을 수행하는 과정을 통해 반영되지 않은 .gitignore를 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;실제 파일은 삭제되지 않는다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 인덱스/스테이징 영역에 있는 영역에서만 Local 파일을 삭제하고 실제 파일은 남겨둔다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;git rm -r --cached .
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Local 저장소의 내용을 스테이징 영역으로 올린다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;git add .
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 변경 사항을 커밋한다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;git commit -m &lt;span class="s2"&gt;&amp;#34;커밋 내용&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 변경 사항을 원격 저장소로 올린다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;git push&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="해결-방법--1단계"&gt;
 &lt;strong&gt;해결 방법 : 1단계&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ed%95%b4%ea%b2%b0-%eb%b0%a9%eb%b2%95--1%eb%8b%a8%ea%b3%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Git 인덱스 또는 스테이징 영역에서 모든 파일과 디렉터리를 삭제하지만 Local 파일 시스템에서는 삭제하지 않고 남겨둘 때 사용된다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;실제 파일은 삭제되지 않는다
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;git&lt;/strong&gt; : Git의 명령 줄 인터페이스&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;rm&lt;/strong&gt; : 파일 또는 Directory를 삭제하는 명령&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;-r&lt;/strong&gt; : Directory를 재귀적으로 삭제하는 옵션&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;ndash;cached&lt;/strong&gt; : 이 옵션은 파일을 인덱스/스테이징 영역에서만 삭제하고 Local 파일 시스템에서는 삭제하지 않도록 Git에 지시&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;.&lt;/strong&gt; : 현재 디렉터리를 지정&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="해결방법--2단계"&gt;
 &lt;strong&gt;해결방법 : 2단계&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ed%95%b4%ea%b2%b0%eb%b0%a9%eb%b2%95--2%eb%8b%a8%ea%b3%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Local 저장소의 변경 사항을 스테이징 영역으로 모두 추가
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;git add .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="해결-방법--3단계"&gt;
 &lt;strong&gt;해결 방법 : 3단계&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ed%95%b4%ea%b2%b0-%eb%b0%a9%eb%b2%95--3%eb%8b%a8%ea%b3%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Local 저장소에 있는 내용들을 Commit하고 Push&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;git commit -m &lt;span class="s2"&gt;&amp;#34;Commit 내용&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;git push&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Error] Python PATH Problem</title><link>https://kyungryeol-yoon.github.io/backend/python/python-path-error/</link><pubDate>Tue, 20 Aug 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/python/python-path-error/</guid><description>&lt;ul&gt;
&lt;li&gt;Command 상에서 python 파일명.py를 써서 실행하면 Python이라는 응답이 나오는 것을 볼 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="문제점"&gt;
 문제점
 &lt;a class="heading-anchor" href="#%eb%ac%b8%ec%a0%9c%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;윈도우10 시스템 변수에 경로(PATH)로 추가하지 않았기 때문에 발생한다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;PS F:&lt;span class="se"&gt;\D&lt;/span&gt;evelopment&lt;span class="se"&gt;\p&lt;/span&gt;ython_prj&lt;span class="se"&gt;\B&lt;/span&gt;oardAPI&amp;gt; python -m venv venv
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;Python
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;PS F:&lt;span class="se"&gt;\D&lt;/span&gt;evelopment&lt;span class="se"&gt;\p&lt;/span&gt;ython_prj&lt;span class="se"&gt;\B&lt;/span&gt;oardAPI&amp;gt; python -v
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;Python
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;PS F:&lt;span class="se"&gt;\D&lt;/span&gt;evelopment&lt;span class="se"&gt;\p&lt;/span&gt;ython_prj&lt;span class="se"&gt;\B&lt;/span&gt;oardAPI&amp;gt; python3 -v
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;Python
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;PS F:&lt;span class="se"&gt;\D&lt;/span&gt;evelopment&lt;span class="se"&gt;\p&lt;/span&gt;ython_prj&lt;span class="se"&gt;\B&lt;/span&gt;oardAPI&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="해결-방법"&gt;
 해결 방법
 &lt;a class="heading-anchor" href="#%ed%95%b4%ea%b2%b0-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;윈도우10 시스템 변수에 경로(PATH)로 추가한다면 이 문제는 해결된다.&lt;/li&gt;
&lt;li&gt;또는 다시 설치해서 Add Path 해준다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Install CSI Driver SMB(v1.15.0) for Kubernetes Using Helm Chart</title><link>https://kyungryeol-yoon.github.io/kubernetes/storage/kubernetes-install-csi-driver-smbv1.15.0-using-helm/</link><pubDate>Mon, 12 Aug 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/storage/kubernetes-install-csi-driver-smbv1.15.0-using-helm/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="install-csi-driver-smb"&gt;
 Install CSI Driver SMB
 &lt;a class="heading-anchor" href="#install-csi-driver-smb" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo add csi-driver-smb https://raw.githubusercontent.com/kubernetes-csi/csi-driver-smb/master/charts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;helm install csi-driver-smb csi-driver-smb/csi-driver-smb --version 1.15.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;CSI Driver SMB - Helm 설치 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes-csi/csi-driver-smb"&gt;https://github.com/kubernetes-csi/csi-driver-smb&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="customize-default-configuration"&gt;
 Customize Default Configuration
 &lt;a class="heading-anchor" href="#customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;values.yaml 수정
&lt;blockquote&gt;
&lt;p&gt;최상위 values.yaml을 수정하면 하위 폴더 values.yaml을 override 한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Chart
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes-csi/csi-driver-smb/tree/master/charts"&gt;https://github.com/kubernetes-csi/csi-driver-smb/tree/master/charts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Release file (.tgz)
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes-csi/csi-driver-smb/releases"&gt;https://github.com/kubernetes-csi/csi-driver-smb/releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="install-customize-default-configuration"&gt;
 Install Customize Default Configuration
 &lt;a class="heading-anchor" href="#install-customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;Chart.yaml 경로&lt;span class="o"&gt;]&lt;/span&gt; -f &lt;span class="o"&gt;[&lt;/span&gt;YAML 파일 또는 URL에 값 지정 &lt;span class="o"&gt;(&lt;/span&gt;여러 개를 지정가능&lt;span class="o"&gt;)]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install csi-driver-smb csi-driver-smb/csi-driver-smb -f override-values.yaml -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="test"&gt;
 Test
 &lt;a class="heading-anchor" href="#test" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1-namespace-생성"&gt;
 1. Namespace 생성
 &lt;a class="heading-anchor" href="#1-namespace-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create ns smb-test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="2-secret-생성"&gt;
 2. Secret 생성
 &lt;a class="heading-anchor" href="#2-secret-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl -n smb-test create secret generic smb-creds &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;--from-literal &lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;testuser &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;--from-literal &lt;span class="nv"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;12.123.123.123 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;--from-literal &lt;span class="nv"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;testpw&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="3-persistentvolume-or-storageclass-생성"&gt;
 3. PersistentVolume or StorageClass 생성
 &lt;a class="heading-anchor" href="#3-persistentvolume-or-storageclass-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="persistentvolume"&gt;
 PersistentVolume
 &lt;a class="heading-anchor" href="#persistentvolume" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PersistentVolume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pv-smb&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;smb-test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClassName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;50Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteMany&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persistentVolumeReclaimPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Retain&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;dir_mode=0777&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;file_mode=0777&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;vers=3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;csi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;smb.csi.k8s.io&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeHandle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;$VOLUMEID &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# make sure it&amp;#39;s a unique id in the cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeAttributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;//12.123.123.123/testuser&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeStageSecretRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;smb-creds&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;smb-test&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="storageclass"&gt;
 StorageClass
 &lt;a class="heading-anchor" href="#storageclass" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;storage.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;StorageClass&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;smb&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;smb-test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;provisioner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;smb.csi.k8s.io&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# On Windows, &amp;#34;*.default.svc.cluster.local&amp;#34; could not be recognized by csi-proxy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;//smb-server.default.svc.cluster.local/share&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# if csi.storage.k8s.io/provisioner-secret is provided, will create a sub directory&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# with PV name under source&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# csi.storage.k8s.io/provisioner-secret-name: smbcreds&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# csi.storage.k8s.io/provisioner-secret-namespace: [NAMESPACE NAME]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;csi.storage.k8s.io/node-stage-secret-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;smbcreds&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;csi.storage.k8s.io/node-stage-secret-namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;smb-test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;volumeBindingMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Immediate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;mountOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;dir_mode=0777&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;file_mode=0777&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;uid=1001&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;gid=1001&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;noperm&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mfsymlinks&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;cache=strict&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;noserverino &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# required to prevent data corruption&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Storage Class 참고&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes-csi/csi-driver-smb/blob/master/deploy/example/storageclass-smb.yaml"&gt;https://github.com/kubernetes-csi/csi-driver-smb/blob/master/deploy/example/storageclass-smb.yaml&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="4-persistentvolumeclaim-생성"&gt;
 4. PersistentVolumeClaim 생성
 &lt;a class="heading-anchor" href="#4-persistentvolumeclaim-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PersistentVolumeClaim&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pvc-smb&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;smb-test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteMany&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pv-smb &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# pv를 설정했을 때&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClassName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;smb &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# sc를 설정했을 때&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="5-deployment-생성"&gt;
 5. Deployment 생성
 &lt;a class="heading-anchor" href="#5-deployment-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;deploy-smb-pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;smb-test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;deploy-smb-pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;deploy-smb-pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx:1.19.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;/bin/bash&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;-c&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;set -euo pipefail; while true; do echo $(date) &amp;gt;&amp;gt; /mnt/smb/outfile; sleep 1; done&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;smb&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/mnt/smb&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;smb&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persistentVolumeClaim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;claimName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pvc-smb&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="6-확인"&gt;
 6. 확인
 &lt;a class="heading-anchor" href="#6-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl -n smb-test &lt;span class="nb"&gt;exec&lt;/span&gt; -it deploy-smb-pod-8569fdd89c-dmlzh -- ls -rtl /mnt/smb
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;total &lt;span class="m"&gt;28&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;-rwxrwxrwx &lt;span class="m"&gt;1&lt;/span&gt; root root &lt;span class="m"&gt;26280&lt;/span&gt; Sep &lt;span class="m"&gt;25&lt;/span&gt; 17:53 outfile&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="7-testtxt-파일-생성"&gt;
 7. test.txt 파일 생성
 &lt;a class="heading-anchor" href="#7-testtxt-%ed%8c%8c%ec%9d%bc-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl -n smb-test &lt;span class="nb"&gt;exec&lt;/span&gt; -it deploy-smb-pod-8569fdd89c-dmlzh -- touch /mnt/smb/test.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="8-확인2"&gt;
 8. 확인2
 &lt;a class="heading-anchor" href="#8-%ed%99%95%ec%9d%b82" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl -n smb-test &lt;span class="nb"&gt;exec&lt;/span&gt; -it deploy-smb-pod-8569fdd89c-dmlzh -- ls -la /mnt/smb
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;total &lt;span class="m"&gt;48&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;drwxrwxrwx &lt;span class="m"&gt;2&lt;/span&gt; root root &lt;span class="m"&gt;0&lt;/span&gt; Sep &lt;span class="m"&gt;25&lt;/span&gt; 18:02 .
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;drwxr-xr-x &lt;span class="m"&gt;1&lt;/span&gt; root root &lt;span class="m"&gt;4096&lt;/span&gt; Sep &lt;span class="m"&gt;25&lt;/span&gt; 17:51 ..
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;-rwxrwxrwx &lt;span class="m"&gt;1&lt;/span&gt; root root &lt;span class="m"&gt;43800&lt;/span&gt; Sep &lt;span class="m"&gt;25&lt;/span&gt; 18:03 outfile
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;-rwxrwxrwx &lt;span class="m"&gt;1&lt;/span&gt; root root &lt;span class="m"&gt;0&lt;/span&gt; Sep &lt;span class="m"&gt;25&lt;/span&gt; 18:15 test.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[SRE] SLO, SLI 및 SLA란?</title><link>https://kyungryeol-yoon.github.io/devops/sre/slo-sli-sla/</link><pubDate>Sun, 11 Aug 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/sre/slo-sli-sla/</guid><description>&lt;h2 id="slo-sli-및-sla란"&gt;
 &lt;strong&gt;SLO, SLI 및 SLA란?&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#slo-sli-%eb%b0%8f-sla%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;서비스 레벨은 일정 기간 내에 사용자에게 제공되는 서비스를 측정 가능한 용어
&lt;ul&gt;
&lt;li&gt;서비스 레벨 목표(Service-level objectives, SLO)는 시스템에서 기대되는 가용성을 설정한 목표이다.&lt;/li&gt;
&lt;li&gt;서비스 레벨 지표(Service-level indicators, SLI)는 시스템의 가용성을 파악하기 위한 핵심 측정치와 지표이다.&lt;/li&gt;
&lt;li&gt;서비스 레벨 계약(Service-level agreements, SLA)은 시스템이 SLO를 충족하지 못할 경우 발생하는 상황과 합의된 내용을 설명하는 법적 계약이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;예를 들어,\
웹 애플리케이션의 SLO가 1주일 중 99%에 해당하는 시간 동안 2초 이내에 비디오 재생을 시작하는 것이라고 가정한다면,\
SLI는 웹사이트에서 2초 이내에 재생을 시작한 비디오의 비율을 측정한다.
SLA에는 이러한 SLO와 고객과 서비스 공급업체가 합의한 기타 SLO와 적용되는 서비스 범위, 그리고 성능을 측정하는 데 사용되는 메트릭인 SLI가 모두 포함된다.&lt;/p&gt;
&lt;p&gt;서비스의 성능과 안정성을 측정하는 방법에 초점을 맞추는 사이트 안정성 엔지니어링(Site Reliability Engineering, SRE)으로 인해,\
분산 시스템의 업타임과 안정성을 유지하기 위한 모범 사례들이 보편화되었다.\
2016년 3월, Google은 서비스 레벨 목표부터 시작해 메트릭을 모델링, 선택 및 분석하는 프레임워크에 대해 설명하는 &amp;lsquo;사이트 안정성 엔지니어링: Google이 프로덕션 시스템 운영하는 방법(Site Reliability Engineering: How Google Runs Production Systems)&amp;lsquo;을 발표했다.&lt;/p&gt;
&lt;h3 id="slo란"&gt;
 &lt;strong&gt;SLO란?&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#slo%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;SLO(서비스 레벨 목표)는 시스템에서 기대하는 가용성을 설정한 목표로, 일정 기간 동안의 백분율로 표시된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;서비스 레벨 목표는 ‘가용성’과 ‘업타임’이라는 공통된 의미를 기반으로 팀들이 협업하는 데 도움이 된다.\
SLO를 안정성과 가용성을 측정하는 표준으로 사용할 수 있다.\
이전 예시에서 설명한 것처럼, SLO는 1주일 중 99%의 시간 동안 웹 애플리케이션의 비디오가 2초 이내에 재생되어야 한다는 것이다.&lt;/p&gt;
&lt;h3 id="sli란"&gt;
 &lt;strong&gt;SLI란?&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#sli%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;SLI(서비스 레벨 지표)는 사용자가 시스템의 가용성을 경험하는 방식을 정량적으로 측정한 것이다.&lt;/li&gt;
&lt;li&gt;서비스 레벨의 성공 비율을 백분율로 나타낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;서비스 레벨 지표는 SLO와 관련해 설명이 되지만, SLI는 시스템 안정성에 대한 실시간 신호를 제공한다.\
SLI는 임계치보다 빠른 요청의 비율 또는 파이프라인으로 들어오는 기록의 비율을 측정하여 정확한 값을 산출할 수 있다.\
앞의 예시의 경우, SLI는 웹사이트에서 2초 이내에 재생을 시작한 비디오의 비율을 측정한다.\
이를 통해 SLO와 얼마나 차이가 나는지 알 수 있다.\
SLI는 임계치보다 빠른 요청의 비율 또는 파이프라인으로 들어오는 기록의 비율을 측정하여 정확한 값을 산출할 수 있다.\
앞의 예시의 경우, SLI는 웹사이트에서 2초 이내에 재생을 시작한 비디오의 비율을 측정한다.\
이를 통해 SLO와 얼마나 차이가 나는지 알 수 있다.&lt;/p&gt;
&lt;h3 id="sla란"&gt;
 &lt;strong&gt;SLA란?&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#sla%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;SLA(서비스 레벨 계약 또는 협약)는 고객이 서비스를 사용할 때 기대하는 서비스 레벨을 정의한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;서비스 레벨 계약은 서비스 제공업체와 고객 간의 계약으로, 공급업체가 제공할 서비스를 문서화하고 공급업체가 충족해야 하는 서비스 표준을 정의한다.\
SLA에는 SLO를 위반할 경우 어떤 구제책이나 페널티가 있는지를 설명한다.&lt;/p&gt;
&lt;p&gt;앞의 예시의 경우, SLA에는 웹 애플리케이션에 대한 모든 SLO는 물론 포함될 서비스 범위, SLO에 대한 성능 측정에 사용되는 모든 SLI가 포함된다.\
계약에는 또한 서비스 제공업체와 고객의 책임도 포함된다.&lt;/p&gt;
&lt;h2 id="서비스-레벨-slo-sli-및-sla는-누가-사용할까"&gt;
 &lt;strong&gt;서비스 레벨, SLO, SLI 및 SLA는 누가 사용할까?&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%84%9c%eb%b9%84%ec%8a%a4-%eb%a0%88%eb%b2%a8-slo-sli-%eb%b0%8f-sla%eb%8a%94-%eb%88%84%ea%b0%80-%ec%82%ac%ec%9a%a9%ed%95%a0%ea%b9%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;SRE 팀, 안정성 엔지니어 및 교차 기능 팀은 서비스의 ‘안정성’을 정의하고 측정하는 데 어려움을 겪는 경우가 많다.\
교차 기능 팀은 서비스나 시스템의 모든 측면에서 중요한 메트릭에 대한 포괄적인 뷰를 생성하여 업타임과 성능을 쉽게 측정할 수 있어야 한다.&lt;/p&gt;
&lt;p&gt;서비스 레벨은 SRE 팀과 안정성 엔지니어가 애플리케이션과 인프라에서 주요 구성 요소를 식별하는 데 도움이 된다.\
이들은 하나 이상의 구성 요소가 외부 고객들에게 기능을 노출시키는 경우 알아야 하기 때문이다.
이러한 교차점을 시스템 경계라고 한다.\
시스템 경계는 사이트 안정성 엔지니어가 시스템의 성능 및 안정성의 실제 상황을 설명하기 위해 서비스 레벨 지표와 목표를 측정 지표에 적용하는 지점이다.&lt;/p&gt;
&lt;p&gt;서비스 범위를 설정하고 어떤 메트릭이 SLI이 되어야 하고, SLO 준수 요구 사항이 무엇인지를 결정하려면 많은 노력이 필요하다.\
복잡하기 때문에 아예 시도하지 않고 포기하는 경우도 많다.\
안정성 엔지니어와 SRE 팀은 모든 팀을 위해 전체 스택에서 가용성 및 업타임에 대한 기준을 신속하게 설정할 수 있도록, 시스템의 성능 이력을 기반으로 맞춤화된 정확한 SLI 및 SLO가 필요하다.&lt;/p&gt;
&lt;p&gt;SRE 팀이 항상 서비스 레벨 관리에 대한 책임을 지는 것은 아니지만, 서비스 레벨이 책임 범위에 포함되는 경우가 많다. SLI를 추적하고 SLO에 연결하면, 시스템 성능에 대한 목표를 설정할 수 있다.\
Google의 SRE 지침은 레이턴시, 트래픽, 오류 및 포화를 서비스 레벨의 4가지 황금 신호로 정의하고 있다.\
예를 들어,\
API 호출을 확인하고 고객이 좋은 경험을 하기 위해 성공해야 하는 일반적인 요청의 비율(예: SLO 95%)을 기준으로 성공/실패 요청 수(SLI)를 추적할 수 있다.&lt;/p&gt;
&lt;p&gt;SRE 팀은 고객에게 어느 정도 레벨의 SLA를 보장해 줘야 할지 보다 잘 이해하기 위해, 애플리케이션과 서비스 내의 핵심 구성 요소에 대해 엄격한 SLO를 설정한다.\
이를 기준으로 팀은 SLO를 준수하려면 얼마나 신속하게 문제를 해결해야 하는지 이해하기 위한 방법으로 오류 예산을 적용할 수 있다.\
서비스 레벨은 팀이 메트릭을 집계하고 전체 조직에서 업타임, 성능 및 안정성을 투명하게 파악할 수 있도록 해준다.\
비즈니스 리더들은 서비스 레벨을 사용해 여러 팀, 애플리케이션, 서비스 등의 규정 준수 여부를 한눈에 모니터링하고 시스템 상태를 포괄적으로 파악할 수 있다.&lt;/p&gt;
&lt;h3 id="서비스-레벨-관리란"&gt;
 &lt;strong&gt;서비스 레벨 관리란?&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%84%9c%eb%b9%84%ec%8a%a4-%eb%a0%88%eb%b2%a8-%ea%b4%80%eb%a6%ac%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;서비스 레벨 관리는 고객에게 제공되는 서비스 레벨에 대한 모든 프로세스와 운영 계약이 적절한지 확인하는 것을 의미한다.\
여기에는 서비스 레벨에 대한 모니터링 및 보고, SLO 설정 및 조정, SLI 결정, SLA 준수 확인, 고객 리뷰 유지 등이 포함된다.&lt;/p&gt;
&lt;p&gt;중요한 점은 SLO의 경우 팀 간에 ‘가용성’의 의미를 공유해야 한다는 것이며, 이는 SLA를 통해 파악할 수도 있다.\
이러한 서비스 레벨 계약을 충족하거나 초과 충족하려면, 교차 기능 팀이 내부 SLO를 관리하는 것이 중요하다.&lt;/p&gt;
&lt;h3 id="서비스-레벨-관리의-혜택"&gt;
 &lt;strong&gt;서비스 레벨 관리의 혜택&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%84%9c%eb%b9%84%ec%8a%a4-%eb%a0%88%eb%b2%a8-%ea%b4%80%eb%a6%ac%ec%9d%98-%ed%98%9c%ed%83%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;팀 전체에 SLO 모범 사례를 구현하는 것은 쉽지 않은 일이다.\
팀 간에 공유되는 용어를 정확히 정의하려면 올바른 데이터가 필요하다.&lt;/p&gt;
&lt;p&gt;안정성 엔지니어는 전체 스택과 팀 전체의 가용성 및 업타임에 대한 기준을 신속하게 설정해야 한다.\
서비스 경계를 결정하고 서비스 안정성을 투명하게 파악할 수 있는 SLO와 SLI가 있어야, 고객과의 약속인 SLA를 보다 효과적으로 준수할 수 있다.\
환경 전반을 개선하려면 안정성, SLO 준수 메트릭 및 오류 예산을 보고할 수 있어야 한다.&lt;/p&gt;</description></item><item><title>[K6] K6 Load Testing Tool</title><link>https://kyungryeol-yoon.github.io/devops/k6/k6-load-testing-tool/</link><pubDate>Sat, 10 Aug 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/k6/k6-load-testing-tool/</guid><description>&lt;ul&gt;
&lt;li&gt;Smoke Test, Load Test, Stress Test 등 다양한 테스트 지원&lt;/li&gt;
&lt;li&gt;예를 들어, Kubernetes에 애플리케이션 Pod를 배포한다고 가정했을 때
&lt;ul&gt;
&lt;li&gt;Pod의 resources를 지정해줘야 하는데 어느 정도 값을 줘야 하는 지 모를 때가 있다.&lt;/li&gt;
&lt;li&gt;이때 k6 의 Load Test 를 진행하면 보다 수월하게 값을 지정할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Load Test Type&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/k6/latest/testing-guides/test-types/"&gt;https://grafana.com/docs/k6/latest/testing-guides/test-types/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="주요-성능-지표"&gt;
 주요 성능 지표
 &lt;a class="heading-anchor" href="#%ec%a3%bc%ec%9a%94-%ec%84%b1%eb%8a%a5-%ec%a7%80%ed%91%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;퍼포먼스 테스트의 결과를 분석 할때, 반드시 알아야 할 주요 성능 지표가 있다.
&lt;ul&gt;
&lt;li&gt;Latency(지연시간)&lt;/li&gt;
&lt;li&gt;Throughput(처리량)&lt;/li&gt;
&lt;li&gt;Iterations(반복)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="latency지연시간"&gt;
 Latency(지연시간)
 &lt;a class="heading-anchor" href="#latency%ec%a7%80%ec%97%b0%ec%8b%9c%ea%b0%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;고객이 배달 앱을 통해 식당에 음식을 주문하고 문 앞까지 도착하는 시간에 비유할 수 있다.&lt;/li&gt;
&lt;li&gt;주문하는데 1분이 걸렸고, 요리하는데 10분, 배달 오는데 10분 총 21 분이 소요되었다. 이때는 21 분의 지연시간이 걸렸다고 할 수 있다.&lt;/li&gt;
&lt;li&gt;인터넷에서 요청을 보내고 응답을 받기 전까지를 측정한 지표&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="throuput처리량"&gt;
 Throuput(처리량)
 &lt;a class="heading-anchor" href="#throuput%ec%b2%98%eb%a6%ac%eb%9f%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;이번엔 한 식당에 100 명의 고객이 웨이팅하고 있다고 가정&lt;/li&gt;
&lt;li&gt;Throuput은 식당이 1시간 동안 100 명의 고객에게 음식을 대접할 수 있는지에 비유할 수 있다.&lt;/li&gt;
&lt;li&gt;식당이 높은 Throuput을 가졌다면, 1시간 동안 100 명의 고객에게 모두 음식을 대접할 수 있을 것이고, 낮은 Throuput을 가졌다면 고객들은 더 많은 시간을 기다려야 할 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="iterations반복"&gt;
 Iterations(반복)
 &lt;a class="heading-anchor" href="#iterations%eb%b0%98%eb%b3%b5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;A 고객이 음식을 주문하고, 식당은 음식을 조리하고, 고객에게 음식을 제공합니다.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;B 고객이 음식을 주문하고, 식당은 음식을 조리하고, 고객에게 음식을 제공합니다.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;C 고객이 음식을 주문하고, 식당은 음식을 조리하고, 고객에게 음식을 제공합니다.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;이렇듯 같은 행위를 얼마만큼 안정적으로 반복할 수 있는지를 테스트하는 지표&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="k6의-lifecycle은-크게-네가지"&gt;
 k6의 Lifecycle은 크게 네가지
 &lt;a class="heading-anchor" href="#k6%ec%9d%98-lifecycle%ec%9d%80-%ed%81%ac%ea%b2%8c-%eb%84%a4%ea%b0%80%ec%a7%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 1. 초기화 - init code
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 2. 전처리 - setup code
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="c1"&gt;//　로그인 토큰취득 등 API실행전에 필요한 처리 구현
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 3. API실행(시나리오 실행) - VU code
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="c1"&gt;/// API를 실행할 시나리오를 구현
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 4. API 실행후 처리 - teardown code
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;teardown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="c1"&gt;// API 실행후에 필요한 처리가 있다면 구현
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;init은 스크립트를 초기화
&lt;ul&gt;
&lt;li&gt;모듈 임포트&lt;/li&gt;
&lt;li&gt;로컬 파일 시스템에서 파일 로드&lt;/li&gt;
&lt;li&gt;모든 옵션에 대한 설정 테스트&lt;/li&gt;
&lt;li&gt;함수 정의 (default에서 수행 혹은 setup, teardown에서 수행)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(선택사항)&lt;/code&gt; setup코드는 환경을 준비하고, 데이터를 생성
&lt;ul&gt;
&lt;li&gt;setup은 init 다음에 수행되며 오직 한번만 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;VU코드는 default 함수에서 수행. 실제로 테스트 요청을 보내는 코드가 작성된다. 옵션에 정의한 만큼 반복 동작한다.
&lt;ul&gt;
&lt;li&gt;default 함수에서 실제 테스트를 수행&lt;/li&gt;
&lt;li&gt;혹은 옵션에서 특정 시나리오가 정의한 함수를 수행&lt;/li&gt;
&lt;li&gt;VU코드는 테스트가 수행되는 기간동안 지속적으로 반복 수행&lt;/li&gt;
&lt;li&gt;VU코드는 테스트를 위한 http코드를 생성하고, 메트릭의 생성, 테스트를 위한 모든 작업을 수행&lt;/li&gt;
&lt;li&gt;job 함수를 제외하고 모든 작업이 수행되며, job은 init함수에서 수행
&lt;ul&gt;
&lt;li&gt;VU코드는 로컬 파일을 읽을 수 없다.&lt;/li&gt;
&lt;li&gt;VU코드는 어떠한 모듈도 로드할 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(선택사항)&lt;/code&gt; teardown 함수는 테스트의 환경을 정리하고, 자원을 릴리즈한다.
&lt;ul&gt;
&lt;li&gt;teardown은 테스트 끝날때 한번만 수행되며 VU 코드가 종료되고 난뒤 바로 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="setup-teardown-스킵"&gt;
 setup, teardown 스킵
 &lt;a class="heading-anchor" href="#setup-teardown-%ec%8a%a4%ed%82%b5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--no-setup&lt;/code&gt; 옵션을 이용하여 셋업을 스킵한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--no-teardown&lt;/code&gt; 옵션을 이용하여 teardown 을 스킵한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;k6 run --no-setup --no-teardown ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="setup에서-정의한-데이터를-전달"&gt;
 setup에서 정의한 데이터를 전달
 &lt;a class="heading-anchor" href="#setup%ec%97%90%ec%84%9c-%ec%a0%95%ec%9d%98%ed%95%9c-%eb%8d%b0%ec%9d%b4%ed%84%b0%eb%a5%bc-%ec%a0%84%eb%8b%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;setup에서 정의한 데이터를 default function과 teardown 으로 전달&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;teardown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;incorrect data: &amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;setup에서 데이터를 return을 하게 되면 이 return 된 객체가 전달이 되는 방식이다.&lt;/li&gt;
&lt;li&gt;이후 defult, teardown에서 data를 파라미터로 전달 받을 수 있다.
&lt;ul&gt;
&lt;li&gt;데이터는 오직 json 데이터만 전달가능하며, 함수는 전달불가이다.&lt;/li&gt;
&lt;li&gt;데이터가 너무 크면 더 많은 메모리가 사용된다.&lt;/li&gt;
&lt;li&gt;default() 에서 데이터를 변경할 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Test Life Cycle&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/k6/latest/using-k6/test-lifecycle/"&gt;https://grafana.com/docs/k6/latest/using-k6/test-lifecycle/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="test-code-작성-방법"&gt;
 Test Code 작성 방법
 &lt;a class="heading-anchor" href="#test-code-%ec%9e%91%ec%84%b1-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;k6는 가상 유저를 만들어 애플리케이션에 원하는 요청을 반복적으로 보내게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;k6/http&amp;#34;&lt;/span&gt;		&lt;span class="c1"&gt;// http test
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sleep&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;k6&amp;#34;&lt;/span&gt;		&lt;span class="c1"&gt;// sleep 기능 사용 시 추가 (sleep(n) → 지정한 n 기간 동한 VU 실행을 일시 중지)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="nx"&gt;vus&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 가상의 유저 수
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;1m&amp;#39;&lt;/span&gt; &lt;span class="c1"&gt;// 테스트 진행 시간
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;http://test.k6.io&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;		&lt;span class="c1"&gt;// 테스트 URL
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;getUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;BASE_URL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="nx"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;10명의 가상 유저가 10s 동안 &lt;a href="https://test.k6.io"&gt;https://test.k6.io&lt;/a&gt; 을 호출&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;K6 Web Page Test : &lt;a href="https://test.k6.io"&gt;https://test.k6.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;K6 API Test : &lt;a href="https://test-api.k6.io"&gt;https://test-api.k6.io&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;1명의 가상 유저가 한번만 default function을 호출하는 것이 아닌, 60초 동안 해당 함수를 계속 호출한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;즉, default function을 1명씩 1번 호출해서 총 10번 호출하는 것이 아닌, 1명의 가상유저가 5~10번 정도 호출한다.
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Production 환경이 아닌 Dev 또는 Staging 환경에서 진행&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;성능을 분석할 때, 절대 평균값으로 판단하지 않기&lt;/li&gt;
&lt;li&gt;클라우드 환경을 이용한다면, k6를 테스트할 때 Scale Up, Out에 주의
{: .prompt-warning }&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="test-code-작성-예시"&gt;
 Test Code 작성 예시
 &lt;a class="heading-anchor" href="#test-code-%ec%9e%91%ec%84%b1-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;k6/http&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;k6&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Trend&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;k6/metrics&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;scenario1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Trend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;scenario1_response_time&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;scenario2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Trend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;scenario2_response time&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;VUS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DURATION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;10s&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;scenarios&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;scenario1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;constant-vus&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;scenarioFunc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;vus&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;VUS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DURATION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;SCENARIO_ID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;scenario2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;constant-vus&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;scenarioFunc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;vus&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;VUS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DURATION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;SCENARIO_ID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;		&lt;span class="c1"&gt;// token취득
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Authorization&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Bearer XXX&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;teardown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Function teardown : &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;scenarioFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scenarioUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;		&lt;span class="c1"&gt;// 실행할 API
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scenario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scenarioUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;57&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;58&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Authorization&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sb"&gt;`Bearer &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;59&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;60&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;61&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;__ENV&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SCENARIO_ID&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;62&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;trends&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scenario1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;63&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;trends&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scenario2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;64&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;65&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Function default : &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;66&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;67&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;68&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;scenario status is 200&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;69&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;70&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;71&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="option-관련"&gt;
 Option 관련
 &lt;a class="heading-anchor" href="#option-%ea%b4%80%eb%a0%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;scenarios&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;scenario1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;constant-vus&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;scenarioFunc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;vus&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;VUS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DURATION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;SCENARIO_ID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;executor&lt;/strong&gt; : k6의 실행 엔진을 나타낸다.
&lt;ul&gt;
&lt;li&gt;여기에서 VU(Virtual user)나 스크립트 실행 패턴을 지정할 수 있다.&lt;/li&gt;
&lt;li&gt;자세한 내용은 k6의 &lt;a href="https://grafana.com/docs/k6/latest/using-k6/scenarios/executors/"&gt;executors&lt;/a&gt;를 참조&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;exec&lt;/strong&gt; : 실행하고자 하는 시나리오를 지정&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;vus&lt;/strong&gt; : Virtual Users API를 실행할 가상 유저. 필요한 만큼의 병렬 실행 수를 여기에 설정&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;duration&lt;/strong&gt; : VUS가 반복 시나리오를 실행하는 시간을 설정&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;env&lt;/strong&gt; : 공통으로 사용되는 변수를 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/k6/latest/using-k6/k6-options/reference/"&gt;https://grafana.com/docs/k6/latest/using-k6/k6-options/reference/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="trend-관련"&gt;
 Trend 관련
 &lt;a class="heading-anchor" href="#trend-%ea%b4%80%eb%a0%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;scenario1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Trend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;scenario1_response_time&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;scenario2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Trend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;scenario2_response_time&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Trend는 실행 결과에 포함할 User 지정 Metric&lt;/li&gt;
&lt;li&gt;시나리오별 응답 시간을 통해 실행 결과에 포함시키기 위해 추가&lt;/li&gt;
&lt;li&gt;Trend를 추가하면 아래와 같이 실행 결과에서 볼 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;scenario1_response_time.......: avg=1.29s min=1.26s med=1.29s max=1.35s p(90)=1.34s p(95)=1.34s
scenario2_response_time.......: avg=1.29s min=1.25s med=1.29s max=1.36s p(90)=1.32s p(95)=1.34s&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="setup-관련"&gt;
 Setup 관련
 &lt;a class="heading-anchor" href="#setup-%ea%b4%80%eb%a0%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Authorization&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Bearer XXX&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;여기에서 토큰 취득 등 시나리오를 실행하기 전에 실행되어야할 처리를 설정하는 곳&lt;/li&gt;
&lt;li&gt;로그인이 필요한 서비스를 가정하여 토큰을 취득&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="scenario-관련"&gt;
 scenario 관련
 &lt;a class="heading-anchor" href="#scenario-%ea%b4%80%eb%a0%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;scenarioFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scenarioUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scenario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scenarioUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Authorization&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sb"&gt;`Bearer &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;__ENV&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SCENARIO_ID&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;trends&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scenario1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;trends&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scenario2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;scenario status is 200&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;여기서 실행하고 싶은 시나리오를 작성&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;같은 API를 실행하는 시나리오가 2개이기 때문에 그에 따라 Trend를 실행 시나리오 아이디로 분리&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;check메서드는 값에 대해 true/false를 반환&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;여기에서 API실행이 성공했는지 실패했는지 확인하고 결과에 기록&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;실패해도 중간에 멈추지 않고 실행하기 때문에 유연하게 대응할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;K6 HTTP Module&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/k6/latest/javascript-api/k6-http/"&gt;https://grafana.com/docs/k6/latest/javascript-api/k6-http/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;K6 JavaScript API&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/k6/latest/javascript-api/"&gt;https://grafana.com/docs/k6/latest/javascript-api/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="result"&gt;
 Result
 &lt;a class="heading-anchor" href="#result" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; /\ |‾‾| /‾‾/ /‾‾/
 /\ / \ | |/ / / /
 / \/ \ | ( / ‾‾\
 / \ | |\ \ | (‾) |
 / __________ \ |__| \__\ \_____/ .io

 execution: local
 script: scripts.js
 output: -

 scenarios: (100.00%) 2 scenario, 200 max VUs, 40s max duration (incl. graceful stop):
 * scenario1: 1 looping VUS for 10s (exec: scenarioFunc, gracefulStop: 30s)
 * scenario2: 1 looping VUS for 10s (exec: scenarioFunc, gracefulStop: 30s)


running (11.9s), 0/2 VUS, 16 complete and interrupted iterations
scenario1 ✓ [======================================] 1 VUS 10s
scenario2 ✓ [======================================] 1 VUS 10s

 ✓ scenario status is 200
	 
 ▮ setup

 checks.........................: 100.00% ✓ 2893 ✗ 0
 data_received..................: 3.5 MB 58 kB/s
 data_sent......................: 416 kB 6.9 kB/s
 http_req_blocked...............: avg=49.33ms min=1µs med=3µs max=3.45s p(90)=16µs p(95)=377.18ms
 http_req_connecting............: avg=13.09ms min=0s med=0s max=199.77ms p(90)=0s p(95)=186.36ms
 http_req_duration..............: avg=2.14s min=190.5ms med=1.32s max=5.79s p(90)=5.39s p(95)=5.57s
 { expected_response:true }...: avg=2.14s min=190.5ms med=1.32s max=5.79s p(90)=5.39s p(95)=5.57s
 http_req_failed................: 0.00% ✓ 0 ✗ 2893
 http_req_receiving.............: avg=81.97µs min=19µs med=61µs max=2.43ms p(90)=141.8µs p(95)=205.4µs
 http_req_sending...............: avg=22.37µs min=5µs med=16µs max=687µs p(90)=38µs p(95)=57µs
 http_req_tls_handshaking.......: avg=36.2ms min=0s med=0s max=3.2s p(90)=0s p(95)=190.18ms
 http_req_waiting...............: avg=2.14s min=190.38ms med=1.32s max=5.79s p(90)=5.39s p(95)=5.57s
 http_reqs......................: 2893 48.176768/s
 iteration_duration.............: avg=2.19s min=190.7ms med=1.39s max=6.05s p(90)=5.4s p(95)=5.58s
 iterations.....................: 2893 48.176768/s
 scenario1) Response time.......: avg=1.29s min=1.26s med=1.29s max=1.36s p(90)=1.32s p(95)=1.34s
 scenario2) Response time.......: avg=1.29s min=1.25s med=1.29s max=1.36s p(90)=1.32s p(95)=1.34s
 vus............................: 2 min=0 max=2
 vus_max........................: 2 min=2 max=2&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;checks&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : 100.00% ✓ 2893 ✗ 0&lt;/li&gt;
&lt;li&gt;의미 : 요청이 성공한 비율(%)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;data_received&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : 3.5 MB 58 kB/s&lt;/li&gt;
&lt;li&gt;의미 : 응답한 데이터 양 (Total, /s)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;data_sent&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : 416 kB 6.9 kB/s&lt;/li&gt;
&lt;li&gt;의미 : 요청한 데이터 양 (Total, /s)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;http_req_blocked&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : avg=49.33ms min=1µs med=3µs max=3.45s p(90)=16µs p(95)=377.18ms&lt;/li&gt;
&lt;li&gt;의미 : TCP 접속 대기시간(avg, min, med, max, p(90), p(95)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;http_req_connecting&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : avg=13.09ms min=0s med=0s max=199.77ms p(90)=0s p(95)=186.36ms&lt;/li&gt;
&lt;li&gt;의미 : TCP 접속에 걸린시간(avg, min, med, max, p(90), p(95)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;http_req_duration&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : avg=2.14s min=190.5ms med=1.32s max=5.79s p(90)=5.39s p(95)=5.57s&lt;/li&gt;
&lt;li&gt;의미 : 요청 → 응답 까지 얼마나 걸렸는지를 나타내는 지표. http_req_sending + http_req_waiting + http_req_receiveing(avg, min, med, max, p(90), p(95)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;{ expected_response:true }&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : avg=2.14s min=190.5ms med=1.32s max=5.79s p(90)=5.39s p(95)=5.57s&lt;/li&gt;
&lt;li&gt;의미 : 정상응답만 http_req_duration(avg, min, med, max, p(90), p(95) 정상응답이 없을 경우 이 항목은 표시되지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;http_req_failed&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : 0.00% ✓ 0 ✗ 2893&lt;/li&gt;
&lt;li&gt;의미 : 요청이 실패한 비율(%)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;http_req_receiving&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : avg=81.97µs min=19µs med=61µs max=2.43ms p(90)=141.8µs p(95)=205.4µs&lt;/li&gt;
&lt;li&gt;의미 : 응답의 1바이트가 도달하고 나서 마지막 바이트를 수신할 때까지의 시간(avg, min, med, max, p(90), p(95)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;http_req_sending&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : avg=22.37µs min=5µs med=16µs max=687µs p(90)=38µs p(95)=57µs&lt;/li&gt;
&lt;li&gt;의미 : 요청을 전송하는데 걸린시간(avg, min, med, max, p(90), p(95)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;http_req_tls_handshaking&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : avg=36.2ms min=0s med=0s max=3.2s p(90)=0s p(95)=190.18ms&lt;/li&gt;
&lt;li&gt;의미 : TLS 세션의 핸드쉐이크에 걸린 시간(avg, min, med, max, p(90), p(95) http에서는 0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;http_req_waiting&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : avg=2.14s min=190.38ms med=1.32s max=5.79s p(90)=5.39s p(95)=5.57s&lt;/li&gt;
&lt;li&gt;의미 : 요청이 전송 완료된 후 응답이 시작될 때까지의 시간(avg, min, med, max, p(90), p(95) TTFB(Time To First Byte)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;http_reqs&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : 2893 48.176768/s&lt;/li&gt;
&lt;li&gt;의미 : 총 리퀘스트수 (Total, /s)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;iteration_duration&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : avg=2.19s min=190.7ms med=1.39s max=6.05s p(90)=5.4s p(95)=5.58s&lt;/li&gt;
&lt;li&gt;의미 : 시나리오 1회 반복에 걸린 시간(avg, min, med, max, p(90), p(95)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;iterations&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : 2893 48.176768/s&lt;/li&gt;
&lt;li&gt;의미 : 시나리오 반복 횟수(Total, /s)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;vus&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : 2 min=0 max=2&lt;/li&gt;
&lt;li&gt;의미 : Virtual Users, 시나리오 실행시 유저수(병렬)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;vus_max&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;결과 : 2 min=0 max=2&lt;/li&gt;
&lt;li&gt;의미 : 최대 Virtual Users, 시나리오의 최대 실행유저수(병렬)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="p90과-p95의-의미"&gt;
 p(90)과 p(95)의 의미
 &lt;a class="heading-anchor" href="#p90%ea%b3%bc-p95%ec%9d%98-%ec%9d%98%eb%af%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;p는 percentile을 의미하고 뒤에 90, 95는 각각 90%, 95%를 의미
&lt;ul&gt;
&lt;li&gt;p(90)은 &amp;ldquo;90%의 요청이 주어진 지연보다 빠르거나 동일한 시간 안에 완료된다는 것을 의미&amp;rdquo;&lt;/li&gt;
&lt;li&gt;p(95)는 &amp;ldquo;95%의 요청이 주어진 지연보다 빠르거나 동일한 시간 안에 완료된다는 것을 의미&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="500명의-고객들이-햄버거를-주문했다고-가정"&gt;
 500명의 고객들이 햄버거를 주문했다고 가정
 &lt;a class="heading-anchor" href="#500%eb%aa%85%ec%9d%98-%ea%b3%a0%ea%b0%9d%eb%93%a4%ec%9d%b4-%ed%96%84%eb%b2%84%ea%b1%b0%eb%a5%bc-%ec%a3%bc%eb%ac%b8%ed%96%88%eb%8b%a4%ea%b3%a0-%ea%b0%80%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;80%인 400명은 20초 안에 햄버거를 받았고, 20%인 100명은 햄버거를 받기까지 10분 이상이 걸렸다.&lt;/li&gt;
&lt;li&gt;이때 평균적으로 한 고객이 햄버거를 받기까지 약 4분이 소요&lt;/li&gt;
&lt;li&gt;대부분의 사람들이 20초 내에 햄버거를 받았음에도 불구하고 평균 시간은 4분으로 측정되기 때문에 햄버거를 받기까지의 시간이 오래 걸린다고 생각할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;이렇듯 평균은 실제로 전체 성능을 말해주기엔 함정이 있다.&lt;/li&gt;
&lt;li&gt;따라서 퍼포먼스 측정을 진행 할 때는 평균을 보는 것에 주의를 주어야 하며, 평균보다는 p(90)과 p(95)가 더 중요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="100만-건의-요청을-보냈을-때-모든-요청은-1초-내에-이루어져야-하는데-딱-하나의-요청만이-1분이-걸렸다고-가정"&gt;
 100만 건의 요청을 보냈을 때, 모든 요청은 1초 내에 이루어져야 하는데, 딱 하나의 요청만이 1분이 걸렸다고 가정
 &lt;a class="heading-anchor" href="#100%eb%a7%8c-%ea%b1%b4%ec%9d%98-%ec%9a%94%ec%b2%ad%ec%9d%84-%eb%b3%b4%eb%83%88%ec%9d%84-%eb%95%8c-%eb%aa%a8%eb%93%a0-%ec%9a%94%ec%b2%ad%ec%9d%80-1%ec%b4%88-%eb%82%b4%ec%97%90-%ec%9d%b4%eb%a3%a8%ec%96%b4%ec%a0%b8%ec%95%bc-%ed%95%98%eb%8a%94%eb%8d%b0-%eb%94%b1-%ed%95%98%eb%82%98%ec%9d%98-%ec%9a%94%ec%b2%ad%eb%a7%8c%ec%9d%b4-1%eb%b6%84%ec%9d%b4-%ea%b1%b8%eb%a0%b8%eb%8b%a4%ea%b3%a0-%ea%b0%80%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;일반적인 관점에서는 실패로 볼 수 있지만, Service Level Objective(SLO) 관점에서 바라보면 성공. 왜냐하면 SLO에서 100%는 있을 수 없기 때문이다.&lt;/li&gt;
&lt;li&gt;AWS S3 서비스만 봐도 &lt;a href="https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/userguide/DataDurability.html"&gt;99.999999999%의 내구성과 99.99%의 가용성을 제공&lt;/a&gt;한다고 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="test-표준-측정-항목"&gt;
 &lt;a href="https://grafana.com/docs/k6/latest/using-k6/metrics/reference/#standard-built-in-metrics"&gt;Test 표준 측정 항목&lt;/a&gt;
 &lt;a class="heading-anchor" href="#test-%ed%91%9c%ec%a4%80-%ec%b8%a1%ec%a0%95-%ed%95%ad%eb%aa%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;Metric Name&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Type&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Description&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;vus&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Gauge&lt;/td&gt;
					&lt;td style="text-align: left"&gt;현재 활성화 된 사용자 유저&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;vus_max&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Gauge&lt;/td&gt;
					&lt;td style="text-align: left"&gt;가능한 최대 가상 사용자 수(로드 레벨을 확장할 때 성능에 영향을 미치지 않도록 VU 리소스가 미리 할당됨)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;iterations&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Counter&lt;/td&gt;
					&lt;td style="text-align: left"&gt;테스트에서 Vu가 JS 스크립트를 실행한 총 횟수&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;iteration_duration&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Trend&lt;/td&gt;
					&lt;td style="text-align: left"&gt;default/main function의 전체 반복을 한 번 완료하는데 소요된 시간&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;dropped_iterations&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Counter&lt;/td&gt;
					&lt;td style="text-align: left"&gt;k6 v0.27.0에 도입된 VU lack 또는 lack of time으로 인해 시작할 수 없는 반복 회수&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;data_received&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Counter&lt;/td&gt;
					&lt;td style="text-align: left"&gt;데이터를 전달받은 양&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;data_sent&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Counter&lt;/td&gt;
					&lt;td style="text-align: left"&gt;데이터를 전달한 양&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;checks&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Rate&lt;/td&gt;
					&lt;td style="text-align: left"&gt;성공적으로 체크된 Rate&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="http-측정-항목"&gt;
 &lt;a href="https://grafana.com/docs/k6/latest/using-k6/metrics/reference/#http"&gt;HTTP 측정 항목&lt;/a&gt;
 &lt;a class="heading-anchor" href="#http-%ec%b8%a1%ec%a0%95-%ed%95%ad%eb%aa%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;Metric Name&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Type&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Description&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;http_reqs&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Counter&lt;/td&gt;
					&lt;td style="text-align: left"&gt;총 얼마나 많은 HTTP requests를 k6에서 생성했는지 횟수&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;http_req_blocked&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Trend&lt;/td&gt;
					&lt;td style="text-align: left"&gt;요청을 시작하기 전에 차단된 시간(TCP connection slot 을 기다리는) 단위: float&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;http_req_connecting&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Trend&lt;/td&gt;
					&lt;td style="text-align: left"&gt;원격 호스트에 대한 TCP 연결을 설정하는데 소요된 시간. 단위: float&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;http_req_tls_handshaking&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Trend&lt;/td&gt;
					&lt;td style="text-align: left"&gt;원격 호스트와의 핸드셰이킹 TLS 세션에 소요된 시간&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;http_req_sending&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Trend&lt;/td&gt;
					&lt;td style="text-align: left"&gt;원격 호스트에 데이터를 보내는데 소요된 시간. 단위: float&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;http_req_waiting&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Trend&lt;/td&gt;
					&lt;td style="text-align: left"&gt;원격 호스트로부터의 응답을 대기하는 데 소요된 시간 (a.k.a. “time to first byte”, or “TTFB”). 단위: float&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;http_req_receiving&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Trend&lt;/td&gt;
					&lt;td style="text-align: left"&gt;원격 호스트로부터 응답 데이터를 수신하는 데 소요된 시간. 단위: float&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;http_req_duration&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Trend&lt;/td&gt;
					&lt;td style="text-align: left"&gt;요청의 총 시간. It&amp;rsquo;s equal to http_req_sending + http_req_waiting + http_req_receiving (즉, 초기 DNS 조회/연결 시간 없이 원격 서버가 요청을 처리하고 응답하는 데 소요된 시간s). 단위: float&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;http_req_failed&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Rate&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;a href="https://k6.io/docs/javascript-api/k6-http/setresponsecallback/"&gt;setResponseCallback&lt;/a&gt; 에 따른 요칭 실패 비율.&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;출력 가능한 옵션&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/k6/latest/results-output/real-time/"&gt;https://grafana.com/docs/k6/latest/results-output/real-time/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Swagger API 관련&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://k6.io/blog/load-testing-your-api-with-swagger-openapi-and-k6/"&gt;https://k6.io/blog/load-testing-your-api-with-swagger-openapi-and-k6/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Postman 관련&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/blog/2020/04/19/load-testing-your-api-with-postman/"&gt;https://grafana.com/blog/2020/04/19/load-testing-your-api-with-postman/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;k6-learn&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana/k6-learn"&gt;https://github.com/grafana/k6-learn&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Install K6-operator Using Helm Chart</title><link>https://kyungryeol-yoon.github.io/devops/k6/kubernetes-install-k6-operator-using-helm/</link><pubDate>Mon, 29 Jul 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/k6/kubernetes-install-k6-operator-using-helm/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="install-k6-operator"&gt;
 Install k6-operator
 &lt;a class="heading-anchor" href="#install-k6-operator" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo add grafana https://grafana.github.io/helm-charts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;helm install k6-operator grafana/k6-operator&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;K6-operator 설치 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/k6/latest/set-up/set-up-distributed-k6/install-k6-operator/"&gt;https://grafana.com/docs/k6/latest/set-up/set-up-distributed-k6/install-k6-operator/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="customize-default-configuration"&gt;
 Customize Default Configuration
 &lt;a class="heading-anchor" href="#customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;values.yaml 수정
&lt;blockquote&gt;
&lt;p&gt;최상위 values.yaml을 수정하면 하위 폴더 values.yaml을 override 한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Chart
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana/k6-operator/tree/main/charts/k6-operator"&gt;https://github.com/grafana/k6-operator/tree/main/charts/k6-operator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Release file (.tgz)
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana/k6-operator/releases"&gt;https://github.com/grafana/k6-operator/releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="install-customize-default-configuration"&gt;
 Install Customize Default Configuration
 &lt;a class="heading-anchor" href="#install-customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;Chart.yaml 경로&lt;span class="o"&gt;]&lt;/span&gt; -f &lt;span class="o"&gt;[&lt;/span&gt;YAML 파일 또는 URL에 값 지정 &lt;span class="o"&gt;(&lt;/span&gt;여러 개를 지정가능&lt;span class="o"&gt;)]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install k6-operator grafana/k6-operator -f override-values.yaml -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="k6-resource-설정-관련"&gt;
 k6 resource 설정 관련
 &lt;a class="heading-anchor" href="#k6-resource-%ec%84%a4%ec%a0%95-%ea%b4%80%eb%a0%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Resource yaml 작성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;k6.io/v1alpha1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TestRun&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;k6-sample&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parallelism&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--&lt;span class="l"&gt;out influxdb=http://influxdb:8086/k6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="l"&gt;o xk6-influxdb=http://localhost:8086&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="l"&gt;o xk6-prometheus-rw --tag testid=test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;arguments: -o experimental-prometheus-rw # prometheus &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--&lt;span class="l"&gt;enable-feature=remote-write-receiver&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;post&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# configure the automatic deletion of all resources&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;k6-test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;test.js&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;separate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;&amp;lt;custom-image&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cool-label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;foo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cool-annotation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;bar&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsNonRoot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;200m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1000Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;100m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;500Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;starter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;&amp;lt;custom-image&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cool-label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;foo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cool-annotation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;bar&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsNonRoot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;적용&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f /path/to/your/k6-resource.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;삭제&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl delete -f /path/to/your/k6-resource.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Run k6 사용법&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/k6/latest/set-up/set-up-distributed-k6/usage/"&gt;https://grafana.com/docs/k6/latest/set-up/set-up-distributed-k6/usage/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Stream real-time&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/k6/latest/results-output/real-time/"&gt;https://grafana.com/docs/k6/latest/results-output/real-time/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-install-influxdb-using-helm/"&gt;InfluxDB 설치 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="dockerfile-build-with-xk6-output-influxdb"&gt;
 Dockerfile Build with xk6-output-influxdb
 &lt;a class="heading-anchor" href="#dockerfile-build-with-xk6-output-influxdb" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-Dockerfile" data-lang="Dockerfile"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Build the k6 binary with the extension&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;golang:1.20&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; go install go.k6.io/xk6/cmd/xk6@latest&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# For our example, we&amp;#39;ll add support for output of test metrics to InfluxDB v2.&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Feel free to add other extensions using the &amp;#39;--with ...&amp;#39;.&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; xk6 build &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; --with github.com/grafana/xk6-output-influxdb@latest &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; --output /k6&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Use the operator&amp;#39;s base image and override the k6 binary&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;grafana/k6:latest&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; --from&lt;span class="o"&gt;=&lt;/span&gt;builder /k6 /usr/bin/k6&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="dockerfile-build-with-xk6-output-prometheus-remote"&gt;
 Dockerfile Build with xk6-output-prometheus-remote
 &lt;a class="heading-anchor" href="#dockerfile-build-with-xk6-output-prometheus-remote" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-Dockerfile" data-lang="Dockerfile"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Build the k6 binary with the extension&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;golang:1.18.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; go install go.k6.io/xk6/cmd/xk6@latest&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; xk6 build --output /k6 --with github.com/grafana/xk6-output-prometheus-remote@latest&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Use the operator&amp;#39;s base image and override the k6 binary&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;grafana/k6:latest&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; --from&lt;span class="o"&gt;=&lt;/span&gt;builder /k6 /usr/bin/k6&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="k6-resource-예시"&gt;
 k6 resource 예시
 &lt;a class="heading-anchor" href="#k6-resource-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;k6.io/v1alpha1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;K6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;k6-sample&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="l"&gt;o xk6-prometheus-rw --tag testid=test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parallelism&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;&amp;lt;custom-image&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;K6_PROMETHEUS_RW_SERVER_URL&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://kube-prometheus-stack-prometheus.monitoring:9090/api/v1/write&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;K6_PROMETHEUS_RW_TREND_AS_NATIVE_HISTOGRAM&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;k6-prometheus:v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;starter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;&amp;lt;custom-image&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;scritps.js&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;test-script&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="테스트-javascript"&gt;
 테스트 JavaScript
 &lt;a class="heading-anchor" href="#%ed%85%8c%ec%8a%a4%ed%8a%b8-javascript" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="ex-1"&gt;
 Ex 1.
 &lt;a class="heading-anchor" href="#ex-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;k6/http&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sleep&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;k6&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;stages&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;10s&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;10s&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;10s&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;10s&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;http://test.k6.io&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="ex-2"&gt;
 Ex 2.
 &lt;a class="heading-anchor" href="#ex-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;k6/http&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;k6&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;insecureSkipTLSVerify&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;stages&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;30s&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;30s&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://test-api.k6.io/public/crocodiles/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;http response status code is 200&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="테스트-javascript-적용"&gt;
 테스트 JavaScript 적용
 &lt;a class="heading-anchor" href="#%ed%85%8c%ec%8a%a4%ed%8a%b8-javascript-%ec%a0%81%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt; create configmap test-script --from-file /home/documents/k6/scritps.js &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/k6-load-testing-tool/"&gt;K6 Load Test 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="uninstall-the-chart"&gt;
 Uninstall the Chart
 &lt;a class="heading-anchor" href="#uninstall-the-chart" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm uninstall &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Install InfluxDB Using Helm Chart</title><link>https://kyungryeol-yoon.github.io/database/influxdb/kubernetes-install-influxdb-using-helm/</link><pubDate>Sun, 28 Jul 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/influxdb/kubernetes-install-influxdb-using-helm/</guid><description>&lt;div class="alert alert-info"&gt;
 &lt;span class="alert-label"&gt;참고&lt;/span&gt;
 &lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
&lt;/div&gt;

&lt;h2 id="install-influxdb"&gt;
 Install InfluxDB
 &lt;a class="heading-anchor" href="#install-influxdb" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo add influxdata https://helm.influxdata.com/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;helm install influxdb influxdata/influxdb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;InfluxDB - Helm 설치 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/influxdata/helm-charts"&gt;https://github.com/influxdata/helm-charts&lt;/a&gt;
&lt;div class="alert alert-info"&gt;
 &lt;span class="alert-label"&gt;참고&lt;/span&gt;
 
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="customize-default-configuration"&gt;
 Customize Default Configuration
 &lt;a class="heading-anchor" href="#customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;values.yaml 수정&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;최상위 values.yaml을 수정하면 하위 폴더 values.yaml을 override 한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Chart
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/influxdata/helm-charts/tree/master/charts/influxdb"&gt;https://github.com/influxdata/helm-charts/tree/master/charts/influxdb&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Release file (.tgz)
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/influxdata/helm-charts/releases"&gt;https://github.com/influxdata/helm-charts/releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="alert alert-tip"&gt;
 &lt;span class="alert-label"&gt;팁&lt;/span&gt;
 &lt;a href="https://kyungryeol-yoon.github.io/posts/influxdb/"&gt;InfluxDB 설정 및 사용법 참고&lt;/a&gt;
&lt;/div&gt;

&lt;h3 id="setting-config"&gt;
 Setting config
 &lt;a class="heading-anchor" href="#setting-config" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;reporting_disabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rpc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bind-address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;:8088&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;coordinator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;retention&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;shard_precreation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;monitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bind-address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;:8086&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;flux-enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;subscriber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;graphite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;collectd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;opentsdb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;udp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;continuous_queries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="setting-create-database"&gt;
 Setting create database
 &lt;a class="heading-anchor" href="#setting-create-database" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;initScripts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;scripts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;init.iql&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|+&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; CREATE DATABASE &amp;#34;telegraf&amp;#34; WITH DURATION 30d REPLICATION 1 NAME &amp;#34;rp_30d&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;API Create Database&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -XPOST &lt;span class="s1"&gt;&amp;#39;http://[influxdb-svc].[influxdb-namespace].svc:8086/query&amp;#39;&lt;/span&gt; --data-urlencode &lt;span class="s1"&gt;&amp;#39;q=CREATE DATABASE mydb&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="alert alert-info"&gt;
 &lt;span class="alert-label"&gt;참고&lt;/span&gt;
 
&lt;/div&gt;

&lt;h3 id="install-customize-default-configuration"&gt;
 Install Customize Default Configuration
 &lt;a class="heading-anchor" href="#install-customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;Chart.yaml 경로&lt;span class="o"&gt;]&lt;/span&gt; -f &lt;span class="o"&gt;[&lt;/span&gt;YAML 파일 또는 URL에 값 지정 &lt;span class="o"&gt;(&lt;/span&gt;여러 개를 지정가능&lt;span class="o"&gt;)]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install influxdb influxdata/influxdb -f override-values.yaml -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Install Loki(v3.1.1) Distributed Using Helm Chart</title><link>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-install-lokiv3.1.1-distributed-using-helm/</link><pubDate>Wed, 19 Jun 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-install-lokiv3.1.1-distributed-using-helm/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="install-the-loki-distributed-helm-charts"&gt;
 Install the Loki Distributed Helm charts
 &lt;a class="heading-anchor" href="#install-the-loki-distributed-helm-charts" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo add grafana https://grafana.github.io/helm-charts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;helm install loki-distributed grafana/loki-distributed --namespace &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt; --version &lt;span class="o"&gt;[&lt;/span&gt;VERSION&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Loki Distributed - Helm 설치 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/loki/latest/setup/install/helm/"&gt;https://grafana.com/docs/loki/latest/setup/install/helm/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="customize-default-configuration"&gt;
 Customize Default Configuration
 &lt;a class="heading-anchor" href="#customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;values.yaml 수정&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;최상위 values.yaml을 수정하면 하위 폴더 values.yaml을 override 한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Chart
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana/helm-charts/tree/main/charts/loki-distributed"&gt;https://github.com/grafana/helm-charts/tree/main/charts/loki-distributed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Release file (.tgz)
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana/helm-charts/releases"&gt;https://github.com/grafana/helm-charts/releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="loki-configurations"&gt;
 Loki Configurations
 &lt;a class="heading-anchor" href="#loki-configurations" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Loki 설정 값 문서&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://grafana.com/docs/loki/latest/configuration/"&gt;https://grafana.com/docs/loki/latest/configuration/&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Grafana Loki 모범 사례&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;레이블은 Loki에서 Log를 검색할 때 필터링이 되는 기준이 되는데 여기선 정적 레이블을 가급적이면 사용하라고 가이드하고 있다.
&lt;ul&gt;
&lt;li&gt;레이블은 클라이언트에서 설정한 다음에 Loki에게 Push하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;chunk_target_size를 사용하라고 한다.
&lt;ul&gt;
&lt;li&gt;기본 1.5MB 사이즈로 모든 청크 크기를 채우도록 하는게 좋다고 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;chunk_encoding은 기본값이 gzip인데 snappy를 권고한다고 한다.
&lt;ul&gt;
&lt;li&gt;이게 훨씬 더 압축을 푸는데도 빠르고 쿼리 속도도 더 빠르다고 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;max_chunk_age는 2h을 권고한다고 한다.&lt;/li&gt;
&lt;li&gt;chunk_idle_period은 1h ~ 2h을 권고한다고 한다.&lt;/li&gt;
&lt;li&gt;RF(Replication factor)를 항상 설정할 것을 권고한다.
&lt;ul&gt;
&lt;li&gt;데이티의 손실 가능성을 완화하기 위해 Ingester의 복제 요소를 일반적으로 3개로 설정할 것을 권고하고 있다.&lt;/li&gt;
&lt;li&gt;복제 요소가 데이터 손실을 방지하는 유일한 요소는 아니며, 주요 목적은 롤아웃 및 재시작 중에 쓰기가 중단되지 않도록 하는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://grafana.com/docs/loki/latest/best-practices/"&gt;https://grafana.com/docs/loki/latest/best-practices/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://grafana.com/blog/2021/02/16/the-essential-config-settings-you-should-use-so-you-wont-drop-logs-in-loki/"&gt;https://grafana.com/blog/2021/02/16/the-essential-config-settings-you-should-use-so-you-wont-drop-logs-in-loki/&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Request Validation, Rate-Limit 에러&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;아래의 값으로 설정하면 필히 쓰로틀링이 걸리게 된다. 하여 적절한 값으로 조정이 필요하다.&lt;/li&gt;
&lt;li&gt;ingestion_rate_mb는 기본값 4이며 ingestion_burst_size_mb는 기본값 6이다.
&lt;ul&gt;
&lt;li&gt;ingestion_rate_mb: 20&lt;/li&gt;
&lt;li&gt;ingestion_burst_size_mb: 40&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://grafana.com/docs/loki/latest/operations/request-validation-rate-limits/"&gt;https://grafana.com/docs/loki/latest/operations/request-validation-rate-limits/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://grafana.com/docs/loki/latest/configuration/#limits_config"&gt;https://grafana.com/docs/loki/latest/configuration/#limits_config&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Loki Grafana 모니터링&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Loki는 기본적으로 /metrics 엔드포인트로부터 각 Components들의 Metric들을 확인할 수 있다.&lt;/li&gt;
&lt;li&gt;모든 컴포넌트들의 Service annotation에 아래의 문구를 추가해준다.
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;이렇게 하면 Prometheus가 자동으로 /metrics 엔드포인트로 메트릭들을 scrape 해간다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;prometheus.io/scrape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;prometheus.io/path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/metrics&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;prometheus.io/port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;3100&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Loki에 대한 모니터링 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/loki/latest/operations/observability/"&gt;https://grafana.com/docs/loki/latest/operations/observability/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="analytics-false"&gt;
 analytics false
 &lt;a class="heading-anchor" href="#analytics-false" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;analytics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;reporting_enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="compactor와-table-manager"&gt;
 Compactor와 Table Manager
 &lt;a class="heading-anchor" href="#compactor%ec%99%80-table-manager" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Grafana Loki의 로그 보존(Retention)은 Compactor 혹은 Table Manager에 의해 수행된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;현재 Table Manager를 통한 Retention은 TTL을 통해 달성되며 boltdb-shipper, chunk/index store 모두 작동한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Compactor를 통한 Retention은 boltdb-shipper 저장소에서만 지원된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;만약 Compactor로 Retention을 적용한다면 Table Manager는 필요로 하지 않게 될 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Compactor 설정 예시&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;compactor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;retention_delete_delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;2h&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;delete_request_store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;s3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;working_directory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/var/loki/compactor&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;retention_enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;retention_delete_worker_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;150&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apply_retention_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1h&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;compaction_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;5m&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Compactor의 Retention은 limits_config에 설정해주면 된다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Retention 설정 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/loki/latest/operations/storage/retention/#configuring-the-retention-period"&gt;https://grafana.com/docs/loki/latest/operations/storage/retention/#configuring-the-retention-period&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="storage"&gt;
 storage
 &lt;a class="heading-anchor" href="#storage" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;schema_config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2024-06-19&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;period&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;24h&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tsdb_index_&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;object_store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;s3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v13&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tsdb&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;storage_config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://access_key:secret_key@endpoint:port&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bucketnames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;loki-logs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;s3forcepathstyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tsdb_shipper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;active_index_directory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/loki/tsdb-index&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cache_location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/loki/tsdb-cache&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;index_gateway_client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# only applicable if using microservices where index-gateways are independently deployed.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# This example is using kubernetes-style naming.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;server_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;dns:///index-gateway.&amp;lt;namespace&amp;gt;.svc.cluster.local:9095&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-deploy-minio/"&gt;minio 설치 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="install-customize-default-configuration"&gt;
 Install Customize Default Configuration
 &lt;a class="heading-anchor" href="#install-customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;Chart.yaml 경로&lt;span class="o"&gt;]&lt;/span&gt; -f &lt;span class="o"&gt;[&lt;/span&gt;YAML 파일 또는 URL에 값 지정 &lt;span class="o"&gt;(&lt;/span&gt;여러 개를 지정가능&lt;span class="o"&gt;)]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install loki-distributed grafana/loki-distributed -f override-values.yaml -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="uninstall-the-chart"&gt;
 Uninstall the Chart
 &lt;a class="heading-anchor" href="#uninstall-the-chart" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm uninstall &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] OTel(OpenTelemetry) Collector - Logging</title><link>https://kyungryeol-yoon.github.io/observability/opentelemetry/kubernetes-otel-collector-logging/</link><pubDate>Mon, 10 Jun 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/observability/opentelemetry/kubernetes-otel-collector-logging/</guid><description>&lt;h2 id="-otel-예시-흐름"&gt;
 🔀 OTEL 예시 흐름:
 &lt;a class="heading-anchor" href="#-otel-%ec%98%88%ec%8b%9c-%ed%9d%90%eb%a6%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD
 A[Application] --&amp;gt; B[OTel SDK]
 B --&amp;gt; C[OTel Collector]
 C --&amp;gt; D[Logs]
 C --&amp;gt; E[Metrics]
 C --&amp;gt; F[Traces]
 D --&amp;gt; G[Loki]
 E --&amp;gt; H[Prometheus]
 F --&amp;gt; I[Tempo/Jaeger]&lt;/pre&gt;
&lt;h2 id="opentelemetry-collector"&gt;
 Opentelemetry Collector
 &lt;a class="heading-anchor" href="#opentelemetry-collector" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;아키텍쳐는 OTel Collector와 기존의 로그 수집 도구를 혼합해 구성한 Plan A와 OTel Collector만으로 구성한 Plan B로 나눌 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="opentelemetry-collector-배포-및-구성"&gt;
 OpenTelemetry Collector 배포 및 구성
 &lt;a class="heading-anchor" href="#opentelemetry-collector-%eb%b0%b0%ed%8f%ac-%eb%b0%8f-%ea%b5%ac%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;vi /etc/rsyslog.conf에 아래의 Code 추가&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-conf" data-lang="conf"&gt;*.* action(type=&amp;#34;omfwd&amp;#34; target=&amp;#34;0.0.0.0&amp;#34; port=&amp;#34;54527&amp;#34; protocol=&amp;#34;tcp&amp;#34; action.resumeRetryCount=&amp;#34;10&amp;#34; queue.type=&amp;#34;linkedList&amp;#34; queue.size=&amp;#34;10000&amp;#34;)&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;syslog 및 container log&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;opentelemetry.io/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;OpenTelemetryCollector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-log&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;daemonset&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostNetwork&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podSecurityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tolerations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Exists&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Typically the collector will want access to pod logs and container logs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;varlogpods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/log/pods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;varlibdockercontainers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/lib/docker/containers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;applogs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/appdata/applog&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Mount the volumes to the collector container&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;varlogpods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/log/pods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;varlibdockercontainers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/lib/docker/containers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;applogs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/appdata/applog&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# This is a new configuration file - do not merge this with your metrics configuration!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;syslog&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tcp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;listen_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;0.0.0.0:54527&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rfc3164&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;UTC or Asia/Seoul&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# specify server timezone here&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operators&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;move&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes.message&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;body&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;move&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes.hostname&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;resource[&amp;#34;hostname&amp;#34;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;move&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes.appname&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;resource[&amp;#34;daemon&amp;#34;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;filelog/applog&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;/appdata/applog/*/*/*.log&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operators&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Extract metadata from file path&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;regex_parser&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;extract_metadata_from_filepath&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Pod UID is not always 36 characters long&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;^.*\/(?P&amp;lt;namespace&amp;gt;\S+)\/(?P&amp;lt;pod_name&amp;gt;\S+)\/(?P&amp;lt;log_file_name&amp;gt;\S+)\.log$&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parse_from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes[&amp;#34;log.file.path&amp;#34;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# default maximum amount of Pods per Node is 110&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Rename attributes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;move&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes[&amp;#34;log.file.path&amp;#34;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;resource[&amp;#34;filename&amp;#34;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;move&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes.namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;resource[&amp;#34;namespace&amp;#34;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;move&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes.pod_name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;resource[&amp;#34;pod&amp;#34;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;add&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;resource[&amp;#34;cluster&amp;#34;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;your-cluster-name&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;filelog&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;/var/log/pods/*/*/*.log&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Exclude logs from all containers named otel-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;/var/log/pods/*/otel-collector/*.log&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;start_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;beginning&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;include_file_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;include_file_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operators&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Find out which format is used by kubernetes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;router&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;get-format&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;parser-docker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;body matches &amp;#34;^\\{&amp;#34;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;parser-crio&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;body matches &amp;#34;^[^ Z]+ &amp;#34;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;parser-containerd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;body matches &amp;#34;^[^ Z]+Z&amp;#34;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Parse CRI-O format&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;regex_parser&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;parser-crio&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;^(?P&amp;lt;time&amp;gt;[^ Z]+) (?P&amp;lt;stream&amp;gt;stdout|stderr) (?P&amp;lt;logtag&amp;gt;[^ ]*) ?(?P&amp;lt;log&amp;gt;.*)$&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;extract_metadata_from_filepath&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parse_from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes.time&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;layout_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gotime&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;108&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;2006-01-02T15:04:05.999999999Z07:00&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;109&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Parse CRI-Containerd format&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;110&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;regex_parser&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;111&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;parser-containerd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;112&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;^(?P&amp;lt;time&amp;gt;[^ ^Z]+Z) (?P&amp;lt;stream&amp;gt;stdout|stderr) (?P&amp;lt;logtag&amp;gt;[^ ]*) ?(?P&amp;lt;log&amp;gt;.*)$&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;113&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;extract_metadata_from_filepath&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;114&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;115&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parse_from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes.time&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;116&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%Y-%m-%dT%H:%M:%S.%LZ&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;117&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Parse Docker format&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;118&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;json_parser&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;119&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;parser-docker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;120&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;extract_metadata_from_filepath&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;121&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;122&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parse_from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes.time&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;123&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%Y-%m-%dT%H:%M:%S.%LZ&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;124&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Extract metadata from file path&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;125&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;regex_parser&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;126&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;extract_metadata_from_filepath&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;127&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Pod UID is not always 36 characters long&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;128&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;^.*\/(?P&amp;lt;namespace&amp;gt;[^_]+)_(?P&amp;lt;pod_name&amp;gt;[^_]+)_(?P&amp;lt;uid&amp;gt;[a-f0-9\-]{16,36})\/(?P&amp;lt;container_name&amp;gt;[^\._]+)\/(?P&amp;lt;restart_count&amp;gt;\d+)\.log$&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;129&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parse_from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes[&amp;#34;log.file.path&amp;#34;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;130&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;131&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# default maximum amount of Pods per Node is 110&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;132&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Rename attributes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;133&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;move&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;134&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes[&amp;#34;log.file.path&amp;#34;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;135&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;resource[&amp;#34;filename&amp;#34;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;136&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;move&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;137&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes.container_name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;138&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;resource[&amp;#34;container&amp;#34;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;139&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;move&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;140&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes.namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;141&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;resource[&amp;#34;namespace&amp;#34;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;142&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;move&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;143&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes.pod_name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;144&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;resource[&amp;#34;pod&amp;#34;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;145&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;add&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;146&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;resource[&amp;#34;cluster&amp;#34;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;147&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;your-cluster-name&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Set your cluster name here&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;148&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;move&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;149&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;attributes.log&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;150&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;body&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;151&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;152&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;153&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;154&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;155&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;insert&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;156&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;loki.resource.labels&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;157&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hostname, daemon&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;158&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;159&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;160&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;insert&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;161&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;loki.format&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;162&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;raw&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;163&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;insert&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;164&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;loki.resource.labels&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;165&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod, namespace, container, cluster, filename&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;166&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;167&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;168&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loki&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;169&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://LOKI_USERNAME:ACCESS_POLICY_TOKEN@LOKI_URL/loki/api/v1/push or http://&amp;lt;Loki-svc&amp;gt;.&amp;lt;Loki-Namespace&amp;gt;.svc/loki/api/v1/push&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;170&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;171&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;172&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pipelines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;173&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;174&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;syslog, filelog/applog, filelog]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;175&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;attributes, resource]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;176&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;loki]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;변경될 Container Log 수집 방법&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;opentelemetry.io/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;OpenTelemetryCollector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-log&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;daemonset&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostNetwork&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Typically the collector will want access to pod logs and container logs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;varlogpods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/log/pods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;varlibdockercontainers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/lib/docker/containers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Mount the volumes to the collector container&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;varlogpods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/log/pods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;varlibdockercontainers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/lib/docker/containers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# This is a new configuration file - do not merge this with your metrics configuration!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;filelog&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;include_file_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;/var/log/pods/*/*/*.log&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operators&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;container-parser&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;container&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;insert&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;loki.format&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;raw&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;insert&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;loki.resource.labels&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod, namespace, container, cluster, filename&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loki&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://LOKI_USERNAME:ACCESS_POLICY_TOKEN@LOKI_URL/loki/api/v1/push or http://&amp;lt;Loki-svc&amp;gt;.&amp;lt;Loki-Namespace&amp;gt;.svc/loki/api/v1/push&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pipelines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;filelog]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;resource]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;loki]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;참고 : &lt;a href="https://opentelemetry.io/blog/2024/otel-collector-container-log-parser/"&gt;https://opentelemetry.io/blog/2024/otel-collector-container-log-parser/&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="receiver-configuration---plan-a"&gt;
 Receiver Configuration - Plan A
 &lt;a class="heading-anchor" href="#receiver-configuration---plan-a" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Receiver는 Promtail 및 EventExporter로부터 Log 데이터를 받는 진입점을 위한 loki receiver를 사용한다.&lt;/li&gt;
&lt;li&gt;loki receiver를 사용하면 Otel Collector에 기존의 Loki가 노출하는 endpoint를 동일하게 노출시켜 기존의 Log 수집 컴포넌트들이 동일한 방법으로 OTel Collector에 Log를 보낼 수 있도록 구성할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="receiver-configuration---plan-b"&gt;
 Receiver Configuration - Plan B
 &lt;a class="heading-anchor" href="#receiver-configuration---plan-b" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Receiver는 Container Log 수집을 위한 filelog, System Log 수집을 위한 filelog, Kubernetes Event Log 수집을 위한 k8s_event 3개를 사용한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Container Log는 filelog receiver로 &lt;code&gt;/var/log/pods/*/*/*.log&lt;/code&gt; 경로에서 수집하고, 수집한 파일들을 기반으로 Path 및 Body를 분석해 Container명, Pod명, Namespace명 등의 정보를 추출한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;System Log는 별도의 filelog receiver로 &lt;code&gt;/var/log&lt;/code&gt; 경로에서 수집한 dmesg, messages, secure 파일들에서 syslog_parser로 정보를 추출해 수집한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kubernetes Event Log는 k8s_event receiver를 이용해 Kubernetes API로부터 수집한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="processor-configuration"&gt;
 Processor Configuration
 &lt;a class="heading-anchor" href="#processor-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Processor는 Log에 Kubernetes Attribute를 부착하기 위한 k8sattributes, Loki Label을 구성하기 위한 resource, OOM 방지를 위한 memory_limiter, Log를 batch성으로 전송하기 위한 batch 4개를 사용한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;k8sattributes Processor는 filelog로부터 수집한 Container log를 기반으로 이와 일치하는 Pod, Deployment, Cluster 등의 정보를 데이터에 부착한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;resource Processor는 위에서 부착한 정보를 Loki의 indexing에 필요한 Label로 변환하는 작업을 수행한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;batch와 memory_limiter Processor는 가공한 Log 데이터를 Export하는 방법을 제공한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="exporter-configuration"&gt;
 Exporter Configuration
 &lt;a class="heading-anchor" href="#exporter-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Exporter는 Log를 Loki로 전송하기 위한 loki exporter를 사용한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;loki의 endpoint Attribute에 loki 주소의 &lt;code&gt;/loki/api/v1/push&lt;/code&gt; Path를 붙여 로그 진입점을 값으로 넣어 수집한 Log를 Loki로 전송한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="pipeline-configuration"&gt;
 Pipeline Configuration
 &lt;a class="heading-anchor" href="#pipeline-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;마지막으로 위에서 정의한 Receiver, Processor, Exporter를 순서에 맞게 조합하는 Pipeline을 정의한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;특히 Processor 요소들의 배치 순서에 따라 Log를 가공하는 순서가 달라지기 때문에, 위의 순서를 준수하는 것이 중요하다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Loki Receiver에서 Log 데이터를 수집해 k8sattributes, resource, memory_limiter, batch 순으로 가공한 뒤, Loki Exporter를 사용해 Loki backend로 전송한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="pipeline-configuration---plan-b"&gt;
 Pipeline Configuration - Plan B
 &lt;a class="heading-anchor" href="#pipeline-configuration---plan-b" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;filelog, k8s_events Receiver에서 Log 데이터를 수집해 k8sattributes, resource, memory_limiter, batch순으로 가공한 뒤, Loki Exporter를 사용해 Loki backend로 전송한다.&lt;/p&gt;
&lt;h2 id="node-collectordaemonset"&gt;
 Node Collector(Daemonset)
 &lt;a class="heading-anchor" href="#node-collectordaemonset" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;File Logs&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Host metrics&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kubelet state metrics&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;공식 문서에서 DaemonSet을 권장하는 receiver가 모인 collector이다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="log--filelog"&gt;
 Log | Filelog
 &lt;a class="heading-anchor" href="#log--filelog" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;수집 대상은 stdout/stderr로 생성된 Kubernetes, app log으로,\
사실상 Fluentbit를 대체한다.\
이를 위해 log scraping 및 전달 뿐 아니라 Processors 에서 언급한 다양한 processor 사용을 고려해야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://opentelemetry.io/docs/kubernetes/collector/components/#filelog-receiver"&gt;Filelog Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: &lt;a href="https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/lokiexporter"&gt;Loki exporter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="metric--kubelet-stats"&gt;
 Metric | Kubelet Stats
 &lt;a class="heading-anchor" href="#metric--kubelet-stats" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;node, pod, container, volume, filesystem network I/O and error metrics 등 CPU, memory 등 infra resource에 관한 metric을 다루어,\
각 노드의 kubelet이 노출하는 API에서 추출한다. 사실 상 cAdvisor의 대체이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://opentelemetry.io/docs/kubernetes/collector/components/#kubeletstats-receiver"&gt;Kubelet Stats Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: OTLP/HTTP Exporter&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="metric--host-metrics"&gt;
 Metric | Host Metrics
 &lt;a class="heading-anchor" href="#metric--host-metrics" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;수집 대상은 node (cpu, disk, CPU load, filesystem, memory, network, paging, process..)의 metric으로,\
사실 상 Prometheus Node Exporter를 대체한다.\
Kubelet Stats Receiver와 일부 항목이 겹치므로 동시 운용 시 중복 처리가 필요하다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://opentelemetry.io/docs/kubernetes/collector/components/#host-metrics-receiver"&gt;Host Metrics Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: OTLP/HTTP Exporter&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# otel-node-collector service accounts are created automatically&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRole&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-node-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;nodes/stats&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;nodes/proxy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;watch&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;list&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRoleBinding&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-node-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;roleRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRole&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-node-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;subjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-node-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;opentelemetry.io/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;OpenTelemetryCollector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-node&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-node-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;daemonset&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# requests:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# cpu: 10m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# memory: 10Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;500m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1000Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podAnnotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.io/scrape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.io/port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8888&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NODE_NAME&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;valueFrom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fieldRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fieldPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;spec.nodeName&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# volumes:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - name: hostfs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# hostPath:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# path: /&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# volumeMounts:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - name: hostfs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# mountPath: /hostfs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# readOnly: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# mountPropagation: HostToContainer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;health_check&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# for k8s liveness and readiness probes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;13133&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# buffer up to 10000 spans, metric data points, log records for up to 5 seconds&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;send_batch_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;5s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory_limiter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;check_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# recommended by official README&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limit_percentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# in 1Gi memory environment, hard limit is 800Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spike_limit_percentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# in 1Gi memory environment, soft limit is 500Mi (800 - 250 = 550Mi)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;health_check&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;telemetry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;INFO&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;8888&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pipelines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;kubeletstats&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - hostmetrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;memory_limiter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;batch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;otlphttp/prometheus&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubeletstats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auth_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;serviceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://${env:NODE_NAME}:10250&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;collection_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecure_skip_verify&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extra_metadata_labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;k8s.volume.type&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;k8s_api_config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auth_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;serviceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metric_groups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;node&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;container&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;volume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;108&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;109&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# hostmetrics:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;110&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# collection_interval: 10s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;111&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# root_path: /hostfs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;112&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# scrapers:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;113&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# cpu: # CPU utilization metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;114&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# load: # CPU load metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;115&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# memory: # Memory utilization&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;116&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# disk: # Disk I/O metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;117&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# filesystem: # File System utilization metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;118&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# network: # Network interface I/O metrics &amp;amp; TCP connection metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;119&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# paging: # Paging/Swap space utilization and I/O metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;120&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# processes: # Process count metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;121&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# process: # Per process CPU, Memory, and Disk I/O metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;122&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# # The following settings can be used to handle the error to work hostmetrics: 2024-05-12T01:06:30.683Z error scraperhelper/scrapercontroller.go:197 Error scraping metrics {&amp;#34;kind&amp;#34;: &amp;#34;receiver&amp;#34;, &amp;#34;name&amp;#34;: &amp;#34;hostmetrics&amp;#34;, &amp;#34;data_type&amp;#34;: &amp;#34;metrics&amp;#34;, &amp;#34;error&amp;#34;: &amp;#34;error reading process executable for pid 1: readlink /hostfs/proc/1/exe: permission denied; error reading username for process \&amp;#34;systemd\&amp;#34; (pid 1): open /etc/passwd: no such file or directory;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;123&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# # refer: https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/28661&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;124&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# mute_process_name_error: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;125&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# mute_process_exe_error: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;126&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# mute_process_io_error: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;127&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# mute_process_user_error: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;128&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# mute_process_cgroup_error: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;129&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;130&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;131&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;132&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbosity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;basic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# detailed, basic&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;133&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;134&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;otlphttp/prometheus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;135&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics_endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://prometheus-server.cluster.svc.cluster.local:80/api/v1/otlp/v1/metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;136&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;137&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cluster-collectorsingle-pod"&gt;
 Cluster Collector(Single Pod)
 &lt;a class="heading-anchor" href="#cluster-collectorsingle-pod" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;k8s events(log)&lt;/li&gt;
&lt;li&gt;k8s objects(metrics)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;단일 replica 사용 권장인 receivers 대상으로,\
이들 receiver는 2개 이상의 instance 사용 시 중복이 발생 가능하기 때문이라고 공식 문서에서 논한다.\
두 receiver 모두 cluster 관점에서 추출하기 때문이라고. 이에 따라 deployment type에 1개의 replica로 설정한다.&lt;/p&gt;
&lt;h3 id="log--kubernetes-objects"&gt;
 Log | Kubernetes Objects
 &lt;a class="heading-anchor" href="#log--kubernetes-objects" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;주로 Kubernetes event 수집용으로 Kubernetes API server 출처의 objects(전체 목록은 kubectl api-resources 로 확인) 수집에도 사용한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-objects-receiver"&gt;Kubernetes Objects Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: &lt;a href="https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/lokiexporter"&gt;Loki exporter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="metric--kubernetes-cluster"&gt;
 Metric | Kubernetes Cluster
 &lt;a class="heading-anchor" href="#metric--kubernetes-cluster" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;사실 상 Kube State Metrics의 대체로 Kubernetes API server에서 cluster level의 metric과 entity events를 추출한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-cluster-receiver"&gt;Kubernetes Cluster Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: OTLP/HTTP Exporter&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-collector-opentelemetry-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRole&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-collector-opentelemetry-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;events&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;namespaces&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;namespaces/status&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nodes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nodes/spec&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pods/status&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;replicationcontrollers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;replicationcontrollers/status&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;resourcequotas&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;services&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;get&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;watch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;apps&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;daemonsets&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;deployments&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;replicasets&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;statefulsets&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;get&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;watch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;extensions&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;daemonsets&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;deployments&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;replicasets&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;get&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;watch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;batch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;jobs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;cronjobs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;get&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;watch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;autoscaling&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;horizontalpodautoscalers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;get&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;watch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRoleBinding&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-collector-opentelemetry-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;roleRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRole&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-collector-opentelemetry-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;subjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-collector-opentelemetry-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# otel-cluster-collector service accounts are created automatically&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;opentelemetry.io/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;OpenTelemetryCollector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-cluster-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podAnnotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.io/scrape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.io/port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8888&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;health_check&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# for k8s liveness and readiness probes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;13133&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# buffer up to 10000 spans, metric data points, log records for up to 5 seconds&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;send_batch_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;5s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory_limiter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;check_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# recommended by official README&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limit_percentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# in 1Gi memory environment, hard limit is 800Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spike_limit_percentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# in 1Gi memory environment, soft limit is 500Mi (800 - 250 = 550Mi)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;108&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;109&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;110&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;elasticsearch.index.prefix&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;111&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-k8sobject&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;112&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;insert&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;113&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;114&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;115&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;health_check&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;116&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;117&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;telemetry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;118&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;119&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;DEBUG&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;120&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;121&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;8888&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;122&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;123&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pipelines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;124&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;125&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;126&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;k8sobjects&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;127&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;128&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;memory_limiter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;129&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;batch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;130&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;attributes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;131&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;132&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;debug&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;133&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;elasticsearch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;134&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;135&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;136&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;137&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;k8s_cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;138&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;139&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;memory_limiter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;140&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;batch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;141&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;142&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;otlphttp/prometheus&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;143&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;144&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;145&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;k8sobjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;146&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;147&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;148&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pull&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;149&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;events&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;150&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;watch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;151&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;k8s_cluster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;152&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;collection_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;153&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;node_conditions_to_report&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;154&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;Ready&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;155&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;MemoryPressure&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;156&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;allocatable_types_to_report&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;157&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;cpu&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;158&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;memory&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;159&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ephemeral-storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;160&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;161&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;162&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;163&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;164&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbosity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;detailed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# default is basic&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;165&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;166&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;otlphttp/prometheus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;167&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics_endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://prometheus-server.cluster.svc.cluster.local:80/api/v1/otlp/v1/metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;168&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;169&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;170&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;171&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;elasticsearch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;172&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;173&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;http://elasticsearch-es-http.cluster.svc.cluster.local:9200&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;174&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs_index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;175&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs_dynamic_index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;176&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;177&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logstash_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;178&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;179&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;anyflow&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;180&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mycluster&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;opentelemetry.io/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;OpenTelemetryCollector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-cluster-k8s-events&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-cluster-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;k8s_events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auth_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;serviceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loki&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://LOKI_USERNAME:ACCESS_POLICY_TOKEN@LOKI_URL/loki/api/v1/push or http://&amp;lt;Loki-svc&amp;gt;.&amp;lt;Loki-Namespace&amp;gt;.svc/loki/api/v1/push&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pipelines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;k8s_events]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;batch]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;loki]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="prometheus-collectorstatefulset"&gt;
 prometheus Collector(statefulset)
 &lt;a class="heading-anchor" href="#prometheus-collectorstatefulset" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;prometheus metrics&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="otlp-collectordeployment"&gt;
 OTLP Collector(Deployment)
 &lt;a class="heading-anchor" href="#otlp-collectordeployment" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Traces(OTEL)&lt;/li&gt;
&lt;li&gt;Generic OTEL Logs&lt;/li&gt;
&lt;li&gt;Generic OTEL metrics&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;공용 receiver, exporter 공통적으로 otlp 프로토콜을 사용하고 replica 개수 제약이 없는 signal 대상 collector로서,\
제약이 없을 경우 가장 운용에 유리한 배포 패턴인 Deployment 를 사용한다. MLT 모두를 대상으로 한다.&lt;/p&gt;
&lt;h3 id="trace--generic-otel-trace"&gt;
 Trace | Generic OTEL trace
 &lt;a class="heading-anchor" href="#trace--generic-otel-trace" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.jaegertracing.io/docs/next-release/deployment/"&gt;Jaeger&lt;/a&gt; 및 &lt;a href="https://grafana.com/docs/grafana-cloud/send-data/otlp/send-data-otlp/"&gt;Grafana Tempo&lt;/a&gt;는 OTLP Receiver를 자체적으로 지원한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver/otlpreceiver"&gt;OTLP Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: &lt;a href="https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/otlpexporter"&gt;OTLP Exporter (gRPC)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="metric--generic-otel-metric"&gt;
 Metric | Generic OTEL metric
 &lt;a class="heading-anchor" href="#metric--generic-otel-metric" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;앞서 논한 metric 이외의 app level metrics 등의 여타 metric 수집을 위한 endpoint이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver/otlpreceiver"&gt;OTLP Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: OTLP/HTTP Exporter&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="log--generic-otel-log"&gt;
 Log | Generic OTEL log
 &lt;a class="heading-anchor" href="#log--generic-otel-log" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Istio의 OTel access log를 포함한 여타 log 수집을 위한 endpoint이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver/otlpreceiver"&gt;OTLP Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: &lt;a href="https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/lokiexporter"&gt;Loki exporter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# otel-otlp-collector service accounts are created automatically&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;opentelemetry.io/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;OpenTelemetryCollector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-otlp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-otlp-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;autoscaler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;minReplicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;maxReplicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# requests:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# cpu: 10m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# memory: 10Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;500m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1000Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podAnnotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.io/scrape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.io/port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8888&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;health_check&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# for k8s liveness and readiness probes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;13133&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# buffer up to 10000 spans, metric data points, log records for up to 5 seconds&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;send_batch_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;5s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory_limiter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;check_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# recommended by official README&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limit_percentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# in 1Gi memory environment, hard limit is 800Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spike_limit_percentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# in 1Gi memory environment, soft limit is 500Mi (800 - 250 = 550Mi)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;health_check&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;telemetry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;INFO&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;8888&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pipelines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;traces&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;otlp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;memory_limiter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;batch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;debug&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;otlp/jaeger&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;otlp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;memory_limiter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;batch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;debug&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;elasticsearch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;otlp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;memory_limiter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;batch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;debug&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;otlphttp/prometheus&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;otlp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocols&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;grpc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;4317&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;4318&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbosity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;basic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# detailed, basic&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;otlp/jaeger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;jaeger-collector.istio-system.svc.cluster.local:4317&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;otlphttp/prometheus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics_endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://prometheus-server.cluster.svc.cluster.local:80/api/v1/otlp/v1/metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;elasticsearch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;http://elasticsearch-es-http.cluster.svc.cluster.local:9200&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs_index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;istio-access-log&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs_dynamic_index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;108&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logstash_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;109&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;110&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;anyflow&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;111&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mycluster&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Install OTel(OpenTelemetry) Operator Using Helm Chart</title><link>https://kyungryeol-yoon.github.io/observability/opentelemetry/kubernetes-install-otel-operator-using-helm/</link><pubDate>Sun, 09 Jun 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/observability/opentelemetry/kubernetes-install-otel-operator-using-helm/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="-otel-예시-흐름"&gt;
 🔀 OTEL 예시 흐름:
 &lt;a class="heading-anchor" href="#-otel-%ec%98%88%ec%8b%9c-%ed%9d%90%eb%a6%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD
 A[Application] --&amp;gt; B[OTel SDK]
 B --&amp;gt; C[OTel Collector]
 C --&amp;gt; D[Logs]
 C --&amp;gt; E[Metrics]
 C --&amp;gt; F[Traces]
 D --&amp;gt; G[Loki]
 E --&amp;gt; H[Prometheus]
 F --&amp;gt; I[Tempo/Jaeger]&lt;/pre&gt;
&lt;h2 id="install-cert-manager"&gt;
 Install Cert-manager
 &lt;a class="heading-anchor" href="#install-cert-manager" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="otelopentelemetry-설치-시-cert-manager가-필요한-이유"&gt;
 OTel(OpenTelemetry) 설치 시 Cert-manager가 필요한 이유
 &lt;a class="heading-anchor" href="#otelopentelemetry-%ec%84%a4%ec%b9%98-%ec%8b%9c-cert-manager%ea%b0%80-%ed%95%84%ec%9a%94%ed%95%9c-%ec%9d%b4%ec%9c%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;HTTPS 통신 보안
OTel(OpenTelemetry) Collector는 기본적으로 HTTP를 통해 데이터를 수집하고 전송하지만,\
HTTPS를 사용하여 보안을 강화하는 것이 좋다.\
Cert-manager는 인증서 발급 및 관리를 자동화하여 OTel(OpenTelemetry) Collector가 안전하게 HTTPS를 사용하도록 설정하는 데 도움을 준다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;인증서 자동 갱신
HTTPS 인증서는 만료 기간이 있으며, 만료되면 OTel(OpenTelemetry) Collector가 작동하지 않게 된다.\
Cert-manager는 인증서가 만료되기 전에 자동으로 갱신하여 서비스 중단을 방지한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;사용 편의성 향상
Cert-manager를 사용하면 수동으로 인증서를 발급하고 관리하는 번거로움 없이 OpenTelemetry Collector를 안전하게 배포하고 운영할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;OTel(OpenTelemetry) 설치 시 반드시 Cert-manager가 필요한 것은 아니지만, HTTPS를 사용하여 보안을 강화하려는 경우 필수. Cert-manager는 Kubernetes 환경에서만 사용 가능.
{: .prompt-warning }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="install-opentelemetry-operator"&gt;
 Install OpenTelemetry Operator
 &lt;a class="heading-anchor" href="#install-opentelemetry-operator" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;Install OpenTelemetry Operator&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/open-telemetry/opentelemetry-operator"&gt;OpenTelemetry Operator - 설치 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Install Helm Chart - OpenTelemetry Operator&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;helm install opentelemetry-operator open-telemetry/opentelemetry-operator --set &lt;span class="s2"&gt;&amp;#34;manager.collectorImage.repository=otel/opentelemetry-collector-k8s&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/open-telemetry/opentelemetry-helm-charts/tree/main/charts/opentelemetry-operator"&gt;OpenTelemetry Operator - Helm 설치 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="opentelemetry-operator가-관리하는-기능-두가지"&gt;
 Opentelemetry Operator가 관리하는 기능 두가지
 &lt;a class="heading-anchor" href="#opentelemetry-operator%ea%b0%80-%ea%b4%80%eb%a6%ac%ed%95%98%eb%8a%94-%ea%b8%b0%eb%8a%a5-%eb%91%90%ea%b0%80%ec%a7%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Opentelemetry Collector&lt;/li&gt;
&lt;li&gt;auto-instrumentation of the workloads using OpenTelemetry instrumentation libraries&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;프로젝트가 다수일 경우 매번 Opentelemetry Collector와 auto-instrumentation agent를 같이 띄울 필요 없이 Operator를 활용하여, 프로젝트별로 Collector를 설치할 수 있고 각 서버마다 agent를 명세할 필요 없이 annotation을 통하여 Operator가 해당 Pod에 sidecar 형태로 추가해준다.&lt;/p&gt;
&lt;h2 id="opentelemetry-operator-사용하여-opentelemetry-collector-배포-할-수-있다"&gt;
 OpenTelemetry Operator 사용하여 OpenTelemetry Collector 배포 할 수 있다.
 &lt;a class="heading-anchor" href="#opentelemetry-operator-%ec%82%ac%ec%9a%a9%ed%95%98%ec%97%ac-opentelemetry-collector-%eb%b0%b0%ed%8f%ac-%ed%95%a0-%ec%88%98-%ec%9e%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="opentelemetry-collector"&gt;
 OpenTelemetry Collector
 &lt;a class="heading-anchor" href="#opentelemetry-collector" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;collector에 대한 배포판은 3가지
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;opentelemetry-collector&lt;/strong&gt; : 핵심 기능을 제공&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;opentelemetry-collector-contrib&lt;/strong&gt; : Contrib은 opentelemetry-collector 확장하여 다양한 환경에서 사용될 수 있도록 제작&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;opentelemetry-collector-k8s&lt;/strong&gt; : opentelemetry-collector와 contrib의 구성요소 중 k8s cluster와 구성요소를 모니터링할 수 있도록 특별히 제작&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="node-collectordaemonset"&gt;
 Node Collector(Daemonset)
 &lt;a class="heading-anchor" href="#node-collectordaemonset" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;File Logs&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Host metrics&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kubelet state metrics&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;공식 문서에서 DaemonSet을 권장하는 receiver가 모인 collector이다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="log--filelog"&gt;
 Log | Filelog
 &lt;a class="heading-anchor" href="#log--filelog" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;수집 대상은 stdout/stderr로 생성된 Kubernetes, app log으로,\
사실상 Fluentbit를 대체한다.\
이를 위해 log scraping 및 전달 뿐 아니라 Processors 에서 언급한 다양한 processor 사용을 고려해야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://opentelemetry.io/docs/kubernetes/collector/components/#filelog-receiver"&gt;Filelog Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: &lt;a href="https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/lokiexporter"&gt;Loki exporter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="metric--kubelet-stats"&gt;
 Metric | Kubelet Stats
 &lt;a class="heading-anchor" href="#metric--kubelet-stats" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;node, pod, container, volume, filesystem network I/O and error metrics 등 CPU, memory 등 infra resource에 관한 metric을 다루어,\
각 노드의 kubelet이 노출하는 API에서 추출한다. 사실 상 cAdvisor의 대체이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://opentelemetry.io/docs/kubernetes/collector/components/#kubeletstats-receiver"&gt;Kubelet Stats Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: OTLP/HTTP Exporter&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="metric--host-metrics"&gt;
 Metric | Host Metrics
 &lt;a class="heading-anchor" href="#metric--host-metrics" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;수집 대상은 node (cpu, disk, CPU load, filesystem, memory, network, paging, process..)의 metric으로,\
사실 상 Prometheus Node Exporter를 대체한다.\
Kubelet Stats Receiver와 일부 항목이 겹치므로 동시 운용 시 중복 처리가 필요하다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://opentelemetry.io/docs/kubernetes/collector/components/#host-metrics-receiver"&gt;Host Metrics Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: OTLP/HTTP Exporter&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# otel-node-collector service accounts are created automatically&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRole&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-node-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;nodes/stats&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;nodes/proxy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;watch&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;list&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRoleBinding&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-node-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;roleRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRole&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-node-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;subjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-node-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;opentelemetry.io/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;OpenTelemetryCollector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-node&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-node-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;daemonset&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# requests:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# cpu: 10m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# memory: 10Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;500m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1000Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podAnnotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.io/scrape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.io/port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8888&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NODE_NAME&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;valueFrom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fieldRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fieldPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;spec.nodeName&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# volumes:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - name: hostfs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# hostPath:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# path: /&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# volumeMounts:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - name: hostfs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# mountPath: /hostfs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# readOnly: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# mountPropagation: HostToContainer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;health_check&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# for k8s liveness and readiness probes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;13133&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# buffer up to 10000 spans, metric data points, log records for up to 5 seconds&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;send_batch_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;5s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory_limiter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;check_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# recommended by official README&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limit_percentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# in 1Gi memory environment, hard limit is 800Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spike_limit_percentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# in 1Gi memory environment, soft limit is 500Mi (800 - 250 = 550Mi)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;health_check&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;telemetry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;INFO&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;8888&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pipelines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;kubeletstats&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - hostmetrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;memory_limiter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;batch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;otlphttp/prometheus&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubeletstats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auth_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;serviceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://${env:NODE_NAME}:10250&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;collection_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecure_skip_verify&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extra_metadata_labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;k8s.volume.type&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;k8s_api_config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auth_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;serviceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metric_groups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;node&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;container&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;volume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;108&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;109&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# hostmetrics:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;110&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# collection_interval: 10s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;111&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# root_path: /hostfs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;112&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# scrapers:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;113&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# cpu: # CPU utilization metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;114&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# load: # CPU load metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;115&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# memory: # Memory utilization&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;116&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# disk: # Disk I/O metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;117&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# filesystem: # File System utilization metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;118&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# network: # Network interface I/O metrics &amp;amp; TCP connection metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;119&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# paging: # Paging/Swap space utilization and I/O metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;120&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# processes: # Process count metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;121&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# process: # Per process CPU, Memory, and Disk I/O metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;122&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# # The following settings can be used to handle the error to work hostmetrics: 2024-05-12T01:06:30.683Z error scraperhelper/scrapercontroller.go:197 Error scraping metrics {&amp;#34;kind&amp;#34;: &amp;#34;receiver&amp;#34;, &amp;#34;name&amp;#34;: &amp;#34;hostmetrics&amp;#34;, &amp;#34;data_type&amp;#34;: &amp;#34;metrics&amp;#34;, &amp;#34;error&amp;#34;: &amp;#34;error reading process executable for pid 1: readlink /hostfs/proc/1/exe: permission denied; error reading username for process \&amp;#34;systemd\&amp;#34; (pid 1): open /etc/passwd: no such file or directory;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;123&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# # refer: https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/28661&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;124&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# mute_process_name_error: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;125&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# mute_process_exe_error: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;126&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# mute_process_io_error: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;127&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# mute_process_user_error: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;128&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# mute_process_cgroup_error: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;129&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;130&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;131&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;132&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbosity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;basic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# detailed, basic&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;133&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;134&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;otlphttp/prometheus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;135&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics_endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://prometheus-server.cluster.svc.cluster.local:80/api/v1/otlp/v1/metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;136&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;137&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="cluster-collectorsingle-pod"&gt;
 Cluster Collector(Single Pod)
 &lt;a class="heading-anchor" href="#cluster-collectorsingle-pod" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;k8s events(log)&lt;/li&gt;
&lt;li&gt;k8s objects(metrics)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;단일 replica 사용 권장인 receivers 대상으로,\
이들 receiver는 2개 이상의 instance 사용 시 중복이 발생 가능하기 때문이라고 공식 문서에서 논한다.\
두 receiver 모두 cluster 관점에서 추출하기 때문이라고. 이에 따라 deployment type에 1개의 replica로 설정한다.&lt;/p&gt;
&lt;h4 id="log--kubernetes-objects"&gt;
 Log | Kubernetes Objects
 &lt;a class="heading-anchor" href="#log--kubernetes-objects" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;주로 Kubernetes event 수집용으로 Kubernetes API server 출처의 objects(전체 목록은 kubectl api-resources 로 확인) 수집에도 사용한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-objects-receiver"&gt;Kubernetes Objects Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: &lt;a href="https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/lokiexporter"&gt;Loki exporter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="metric--kubernetes-cluster"&gt;
 Metric | Kubernetes Cluster
 &lt;a class="heading-anchor" href="#metric--kubernetes-cluster" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;사실 상 Kube State Metrics의 대체로 Kubernetes API server에서 cluster level의 metric과 entity events를 추출한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-cluster-receiver"&gt;Kubernetes Cluster Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: OTLP/HTTP Exporter&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-collector-opentelemetry-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRole&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-collector-opentelemetry-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;events&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;namespaces&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;namespaces/status&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nodes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nodes/spec&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pods/status&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;replicationcontrollers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;replicationcontrollers/status&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;resourcequotas&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;services&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;get&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;watch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;apps&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;daemonsets&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;deployments&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;replicasets&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;statefulsets&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;get&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;watch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;extensions&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;daemonsets&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;deployments&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;replicasets&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;get&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;watch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;batch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;jobs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;cronjobs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;get&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;watch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;autoscaling&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;horizontalpodautoscalers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;get&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;watch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRoleBinding&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-collector-opentelemetry-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;roleRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRole&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-collector-opentelemetry-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;subjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-collector-opentelemetry-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# otel-cluster-collector service accounts are created automatically&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;opentelemetry.io/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;OpenTelemetryCollector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-cluster-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podAnnotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.io/scrape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.io/port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8888&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;health_check&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# for k8s liveness and readiness probes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;13133&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# buffer up to 10000 spans, metric data points, log records for up to 5 seconds&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;send_batch_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;5s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory_limiter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;check_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# recommended by official README&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limit_percentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# in 1Gi memory environment, hard limit is 800Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spike_limit_percentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# in 1Gi memory environment, soft limit is 500Mi (800 - 250 = 550Mi)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;108&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;109&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;110&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;elasticsearch.index.prefix&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;111&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-k8sobject&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;112&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;insert&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;113&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;114&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;115&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;health_check&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;116&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;117&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;telemetry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;118&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;119&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;DEBUG&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;120&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;121&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;8888&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;122&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;123&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pipelines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;124&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;125&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;126&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;k8sobjects&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;127&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;128&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;memory_limiter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;129&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;batch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;130&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;attributes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;131&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;132&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;debug&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;133&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;elasticsearch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;134&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;135&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;136&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;137&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;k8s_cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;138&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;139&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;memory_limiter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;140&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;batch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;141&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;142&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;otlphttp/prometheus&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;143&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;144&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;145&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;k8sobjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;146&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;147&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;148&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pull&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;149&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;events&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;150&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;watch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;151&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;k8s_cluster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;152&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;collection_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;153&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;node_conditions_to_report&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;154&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;Ready&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;155&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;MemoryPressure&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;156&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;allocatable_types_to_report&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;157&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;cpu&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;158&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;memory&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;159&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ephemeral-storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;160&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;161&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;162&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;163&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;164&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbosity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;detailed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# default is basic&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;165&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;166&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;otlphttp/prometheus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;167&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics_endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://prometheus-server.cluster.svc.cluster.local:80/api/v1/otlp/v1/metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;168&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;169&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;170&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;171&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;elasticsearch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;172&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;173&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;http://elasticsearch-es-http.cluster.svc.cluster.local:9200&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;174&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs_index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;175&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs_dynamic_index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;176&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;177&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logstash_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;178&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;179&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;anyflow&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;180&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mycluster&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;opentelemetry.io/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;OpenTelemetryCollector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-cluster-k8s-events&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-cluster-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;k8s_events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auth_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;serviceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loki&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://LOKI_USERNAME:ACCESS_POLICY_TOKEN@LOKI_URL/loki/api/v1/push or http://&amp;lt;Loki-svc&amp;gt;.&amp;lt;Loki-Namespace&amp;gt;.svc/loki/api/v1/push&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pipelines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;k8s_events]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;batch]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;loki]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="prometheus-collectorstatefulset"&gt;
 prometheus Collector(statefulset)
 &lt;a class="heading-anchor" href="#prometheus-collectorstatefulset" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;prometheus metrics&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="otlp-collectordeployment"&gt;
 OTLP Collector(Deployment)
 &lt;a class="heading-anchor" href="#otlp-collectordeployment" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Traces(OTEL)&lt;/li&gt;
&lt;li&gt;Generic OTEL Logs&lt;/li&gt;
&lt;li&gt;Generic OTEL metrics&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;공용 receiver, exporter 공통적으로 otlp 프로토콜을 사용하고 replica 개수 제약이 없는 signal 대상 collector로서,\
제약이 없을 경우 가장 운용에 유리한 배포 패턴인 Deployment 를 사용한다. MLT 모두를 대상으로 한다.&lt;/p&gt;
&lt;h4 id="trace--generic-otel-trace"&gt;
 Trace | Generic OTEL trace
 &lt;a class="heading-anchor" href="#trace--generic-otel-trace" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://www.jaegertracing.io/docs/next-release/deployment/"&gt;Jaeger&lt;/a&gt; 및 &lt;a href="https://grafana.com/docs/grafana-cloud/send-data/otlp/send-data-otlp/"&gt;Grafana Tempo&lt;/a&gt;는 OTLP Receiver를 자체적으로 지원한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver/otlpreceiver"&gt;OTLP Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: &lt;a href="https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/otlpexporter"&gt;OTLP Exporter (gRPC)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="metric--generic-otel-metric"&gt;
 Metric | Generic OTEL metric
 &lt;a class="heading-anchor" href="#metric--generic-otel-metric" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;앞서 논한 metric 이외의 app level metrics 등의 여타 metric 수집을 위한 endpoint이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver/otlpreceiver"&gt;OTLP Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: OTLP/HTTP Exporter&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="log--generic-otel-log"&gt;
 Log | Generic OTEL log
 &lt;a class="heading-anchor" href="#log--generic-otel-log" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;Istio의 OTel access log를 포함한 여타 log 수집을 위한 endpoint이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Receiver: &lt;a href="https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver/otlpreceiver"&gt;OTLP Receiver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter: &lt;a href="https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/lokiexporter"&gt;Loki exporter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# otel-otlp-collector service accounts are created automatically&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;opentelemetry.io/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;OpenTelemetryCollector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-otlp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;otel-otlp-collector&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;autoscaler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;minReplicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;maxReplicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# requests:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# cpu: 10m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# memory: 10Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;500m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1000Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podAnnotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.io/scrape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prometheus.io/port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8888&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;health_check&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# for k8s liveness and readiness probes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;13133&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# buffer up to 10000 spans, metric data points, log records for up to 5 seconds&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;send_batch_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;5s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory_limiter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;check_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# recommended by official README&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limit_percentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# in 1Gi memory environment, hard limit is 800Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spike_limit_percentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# in 1Gi memory environment, soft limit is 500Mi (800 - 250 = 550Mi)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;health_check&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;telemetry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;INFO&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;8888&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pipelines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;traces&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;otlp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;memory_limiter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;batch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;debug&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;otlp/jaeger&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;otlp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;memory_limiter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;batch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;debug&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;elasticsearch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;otlp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;processors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;memory_limiter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;batch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;debug&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;otlphttp/prometheus&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;receivers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;otlp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocols&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;grpc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;4317&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;4318&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;exporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbosity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;basic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# detailed, basic&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;otlp/jaeger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;jaeger-collector.istio-system.svc.cluster.local:4317&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;otlphttp/prometheus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics_endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://prometheus-server.cluster.svc.cluster.local:80/api/v1/otlp/v1/metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;elasticsearch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;http://elasticsearch-es-http.cluster.svc.cluster.local:9200&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs_index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;istio-access-log&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logs_dynamic_index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;108&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logstash_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;109&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;110&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;anyflow&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;111&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mycluster&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Install Grafana(v9.5.21) Using Helm Chart</title><link>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-install-grafanav9.5.21-using-helm/</link><pubDate>Sat, 08 Jun 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-install-grafanav9.5.21-using-helm/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="install-the-grafana-helm-charts"&gt;
 Install the Grafana Helm charts
 &lt;a class="heading-anchor" href="#install-the-grafana-helm-charts" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;namespace 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create namespace &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Grafana 배포&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo add grafana https://grafana.github.io/helm-charts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;helm install grafana grafana/grafana --namespace &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt; --set &lt;span class="nv"&gt;adminPassword&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;your_password&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Grafana - Helm 설치 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/grafana/latest/setup-grafana/installation/helm"&gt;https://grafana.com/docs/grafana/latest/setup-grafana/installation/helm&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Password 설정하지 않았을 때, 아래와 같이 찾아보기&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get secret --namespace &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt; grafana -o &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{.data.admin-password}&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; base64 --decode &lt;span class="p"&gt;;&lt;/span&gt; echo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;port-forward로 연결하기&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl --namespace &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt; port-forward &lt;span class="nv"&gt;$POD_NAME&lt;/span&gt; &lt;span class="m"&gt;3000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl port-forward svc/grafana 3000:80 -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="customize-default-configuration"&gt;
 Customize Default Configuration
 &lt;a class="heading-anchor" href="#customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;values.yaml 수정&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;최상위 values.yaml을 수정하면 하위 폴더 values.yaml을 override 한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Chart
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana/helm-charts/tree/main/charts/grafana"&gt;https://github.com/grafana/helm-charts/tree/main/charts/grafana&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Release file (.tgz)
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana/helm-charts/releases"&gt;https://github.com/grafana/helm-charts/releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="setting-admin"&gt;
 Setting Admin
 &lt;a class="heading-anchor" href="#setting-admin" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Administrator credentials when not using an existing secret (see below)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;adminUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;admin&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;adminPassword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;&amp;lt;your_password&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="enable-persistent-storage-recommended"&gt;
 Enable persistent storage (recommended)
 &lt;a class="heading-anchor" href="#enable-persistent-storage-recommended" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;persistence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pvc&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# storageClassName: default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteOnce&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# annotations: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;finalizers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;kubernetes.io/pvc-protection&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# selectorLabels: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## Sub-directory of the PV to mount. Can be templated.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# subPath: &amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## Name of an existing PVC. Can be templated.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# existingClaim:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## Extra labels to apply to a PVC.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;extraPvcLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="외부-접속을-위한-nodeport-설정"&gt;
 외부 접속을 위한 NodePort 설정
 &lt;a class="heading-anchor" href="#%ec%99%b8%eb%b6%80-%ec%a0%91%ec%86%8d%ec%9d%84-%ec%9c%84%ed%95%9c-nodeport-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;## Expose the grafana service to be accessed from outside the cluster (LoadBalancer service).&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;## or access it from within the cluster (ClusterIP service). Set the service type and the port to serve it.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;## ref: http://kubernetes.io/docs/user-guide/services/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;##&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NodePort&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loadBalancerIP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loadBalancerClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loadBalancerSourceRanges&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;targetPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# targetPort: 4181 To be used with a proxy extraContainer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## Service annotations. Can be templated.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;portName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Adds the appProtocol field to the service. This allows to work with istio protocol selection. Ex: &amp;#34;http&amp;#34; or &amp;#34;tcp&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;appProtocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="install-customize-default-configuration"&gt;
 Install Customize Default Configuration
 &lt;a class="heading-anchor" href="#install-customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;Chart.yaml 경로&lt;span class="o"&gt;]&lt;/span&gt; -f &lt;span class="o"&gt;[&lt;/span&gt;YAML 파일 또는 URL에 값 지정 &lt;span class="o"&gt;(&lt;/span&gt;여러 개를 지정가능&lt;span class="o"&gt;)]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install grafana grafana/grafana -f override-values.yaml -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="uninstall-the-chart"&gt;
 Uninstall the Chart
 &lt;a class="heading-anchor" href="#uninstall-the-chart" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm uninstall &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Error] K3S Install Helm</title><link>https://kyungryeol-yoon.github.io/kubernetes/troubleshooting/k3s-error-install-helm/</link><pubDate>Thu, 06 Jun 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/troubleshooting/k3s-error-install-helm/</guid><description>&lt;h2 id="k3s에서-helm-설치시-아래와-같이-error-발생"&gt;
 K3S에서 Helm 설치시 아래와 같이 ERROR 발생
 &lt;a class="heading-anchor" href="#k3s%ec%97%90%ec%84%9c-helm-%ec%84%a4%ec%b9%98%ec%8b%9c-%ec%95%84%eb%9e%98%ec%99%80-%ea%b0%99%ec%9d%b4-error-%eb%b0%9c%ec%83%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Error: INSTALLATION FAILED: Kubernetes cluster unreachable: Get &lt;span class="s2"&gt;&amp;#34;http://localhost:8080/version&amp;#34;&lt;/span&gt;: dial tcp &lt;span class="o"&gt;[&lt;/span&gt;::1&lt;span class="o"&gt;]&lt;/span&gt;:8080: connect: connection refused&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="아래와-같이-설정"&gt;
 아래와 같이 설정
 &lt;a class="heading-anchor" href="#%ec%95%84%eb%9e%98%ec%99%80-%ea%b0%99%ec%9d%b4-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;검색을 해보면 KUBECONFIG를 /etc/rancher/k3s/k3s.yaml 파일로 잡으라는 설명이 나온다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;export KUBECONFIG=/etc/rancher/k3s/k3s.yaml&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; ~/.bashrc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Install Kubernetes using Kubespray(v2.22.2) on VirtualBox</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-kubernetes-using-kubesprayv2.22.2-on-virtualbox/</link><pubDate>Sat, 01 Jun 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-kubernetes-using-kubesprayv2.22.2-on-virtualbox/</guid><description>&lt;h2 id="kubespray"&gt;
 Kubespray?
 &lt;a class="heading-anchor" href="#kubespray" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Kubespray는 Ansible 플레이북, 인벤토리, 프로비저닝 도구와 일반적인 운영체제, 쿠버네티스 클러스터의 설정 관리 작업에 대한 도메인 지식의 결합으로 만들어졌다. Kubespray는 아래와 같은 기능을 제공한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kubespray 지원 사항&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;고가용성을 지닌 클러스터&lt;/li&gt;
&lt;li&gt;구성 가능 (인스턴스를 위한 네트워크 플러그인 선택)&lt;/li&gt;
&lt;li&gt;대부분의 인기있는 리눅스 배포판들에 대한 지원
&lt;ul&gt;
&lt;li&gt;Flatcar Container Linux by Kinvolk&lt;/li&gt;
&lt;li&gt;Debian Bullseye, Buster, Jessie, Stretch&lt;/li&gt;
&lt;li&gt;Ubuntu 16.04, 18.04, 20.04, 22.04&lt;/li&gt;
&lt;li&gt;CentOS/RHEL 7, 8, 9&lt;/li&gt;
&lt;li&gt;Fedora 35, 36&lt;/li&gt;
&lt;li&gt;Fedora CoreOS&lt;/li&gt;
&lt;li&gt;openSUSE Leap 15.x/Tumbleweed&lt;/li&gt;
&lt;li&gt;Oracle Linux 7, 8, 9&lt;/li&gt;
&lt;li&gt;Alma Linux 8, 9&lt;/li&gt;
&lt;li&gt;Rocky Linux 8, 9&lt;/li&gt;
&lt;li&gt;Kylin Linux Advanced Server V10&lt;/li&gt;
&lt;li&gt;Amazon Linux 2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;지속적인 통합 (CI) 테스트&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="vagrant-설정-및-실행"&gt;
 Vagrant 설정 및 실행
 &lt;a class="heading-anchor" href="#vagrant-%ec%84%a4%ec%a0%95-%eb%b0%8f-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="vagrant-설정"&gt;
 Vagrant 설정
 &lt;a class="heading-anchor" href="#vagrant-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;vagrant init&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="vagrantfile-작성"&gt;
 Vagrantfile 작성
 &lt;a class="heading-anchor" href="#vagrantfile-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;require &amp;#34;yaml&amp;#34; 

CONFIG = YAML.load_file(File.join(File.dirname(__FILE__), &amp;#34;config.yaml&amp;#34;))

Vagrant.configure(&amp;#34;2&amp;#34;) do |config|
 # Use the same SSH key for all machines
 config.ssh.insert_key = false

 # masters
 CONFIG[&amp;#34;masters&amp;#34;].each do |master|
 config.vm.define master[&amp;#34;name&amp;#34;] do |cfg|
 cfg.vm.box = master[&amp;#34;box&amp;#34;]
 cfg.vm.network &amp;#34;private_network&amp;#34;, ip: master[&amp;#34;ip&amp;#34;], virtualbox_intnet: true
 cfg.vm.hostname = master[&amp;#34;hostname&amp;#34;]

 cfg.vm.provider &amp;#34;virtualbox&amp;#34; do |v|
 v.memory = master[&amp;#34;memory&amp;#34;]
 v.cpus = master[&amp;#34;cpu&amp;#34;]
 v.name = master[&amp;#34;name&amp;#34;]
 v.customize [&amp;#39;modifyvm&amp;#39;, :id, &amp;#39;--graphicscontroller&amp;#39;, &amp;#39;vmsvga&amp;#39;]
 v.customize [&amp;#39;modifyvm&amp;#39;, :id, &amp;#39;--hwvirtex&amp;#39;, &amp;#39;on&amp;#39;]
 end
 cfg.vm.provision &amp;#34;shell&amp;#34;, inline: &amp;lt;&amp;lt;-SCRIPT
 sed -i -e &amp;#34;s/PasswordAuthentication no/PasswordAuthentication yes/g&amp;#34; /etc/ssh/sshd _config
 systemctl restart sshd
 SCRIPT

 # set timezone &amp;amp; disable swap memory, ufw &amp;amp; enable ip forwarding
 cfg.vm.provision &amp;#34;shell&amp;#34;, inline: &amp;lt;&amp;lt;-SCRIPT
 sudo apt-get update
 sudo timedatectl set-timezone &amp;#34;Asia/Seoul&amp;#34;
 sudo swapoff -a
 sudo sed -i &amp;#34;/swap/d&amp;#34; /etc/fstab
 sudo systemctl stop ufw
 sudo systemctl disable ufw
 sudo sed -i &amp;#34;s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/&amp;#34; /etc/sysctl.conf
 sudo sysctl -p
 SCRIPT

 # install python
 cfg.vm.provision &amp;#34;shell&amp;#34;, inline: &amp;lt;&amp;lt;-SCRIPT
 sudo apt install python3-pip python3-setuptools virtualenv -y
 SCRIPT
 end
 end
 
 # worker nodes
 CONFIG[&amp;#34;workers&amp;#34;].each do |worker|
 config.vm.define worker[&amp;#34;name&amp;#34;] do |cfg|
 cfg.vm.box = worker[&amp;#34;box&amp;#34;]
 cfg.vm.network &amp;#34;private_network&amp;#34;, ip: worker[&amp;#34;ip&amp;#34;], virtualbox_intnet: true
 cfg.vm.hostname = worker[&amp;#34;hostname&amp;#34;]
 
 cfg.vm.provider &amp;#34;virtualbox&amp;#34; do |v|
 v.memory = worker[&amp;#34;memory&amp;#34;]
 v.cpus = worker[&amp;#34;cpu&amp;#34;]
 v.name = worker[&amp;#34;name&amp;#34;]
 v.customize [&amp;#39;modifyvm&amp;#39;, :id, &amp;#39;--graphicscontroller&amp;#39;, &amp;#39;vmsvga&amp;#39;]
 v.customize [&amp;#39;modifyvm&amp;#39;, :id, &amp;#39;--hwvirtex&amp;#39;, &amp;#39;on&amp;#39;]
 end
 cfg.vm.provision &amp;#34;shell&amp;#34;, inline: &amp;lt;&amp;lt;-SCRIPT
 sed -i -e &amp;#34;s/PasswordAuthentication no/PasswordAuthentication yes/g&amp;#34; /etc/ssh/sshd_config
 systemctl restart sshd
 SCRIPT

 # set timezone &amp;amp; disable swap memory &amp;amp; ufw &amp;amp; enable ip forwarding
 cfg.vm.provision &amp;#34;shell&amp;#34;, inline: &amp;lt;&amp;lt;-SCRIPT
 sudo apt-get update
 sudo timedatectl set-timezone &amp;#34;Asia/Seoul&amp;#34;
 sudo swapoff -a
 sudo sed -i &amp;#34;/swap/d&amp;#34; /etc/fstab
 sudo systemctl stop ufw
 sudo systemctl disable ufw
 sudo sed -i &amp;#34;s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/&amp;#34; /etc/sysctl.conf
 sudo sysctl -p
 SCRIPT
 end
 end
end&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="configyaml-작성"&gt;
 config.yaml 작성
 &lt;a class="heading-anchor" href="#configyaml-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;masters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ks-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;box&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;generic/ubuntu2004&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ks-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.10.100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4096&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ks-worker-1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;box&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;generic/ubuntu2004&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ks-worker-1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.10.210&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4096&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ks-worker-2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;box&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;generic/ubuntu2004&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ks-worker-2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.10.220&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4096&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="vagrant-실행"&gt;
 Vagrant 실행
 &lt;a class="heading-anchor" href="#vagrant-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;vagrant up&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="ssh-생성-및-설정"&gt;
 SSH 생성 및 설정
 &lt;a class="heading-anchor" href="#ssh-%ec%83%9d%ec%84%b1-%eb%b0%8f-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;vagrant ssh ks-master&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ssh-keygen -t rsa

ls -al .ssh/
cat .ssh/id_rsa.pub

ssh-copy-id vagrant@192.168.10.100
ssh-copy-id vagrant@192.168.10.210
ssh-copy-id vagrant@192.168.10.220&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;virtualenv --python=python3 venv

. venv/bin/activate

git clone https://github.com/kubernetes-sigs/kubespray
cd kubespray
git checkout v2.22.2

pip install -r requirements.txt

ansible --version

cp -rfp inventory/sample inventory/mycluster

declare -a IPS=(192.168.10.100 192.168.10.210 192.168.10.220)
CONFIG_FILE=inventory/mycluster/hosts.yaml python3 contrib/inventory_builder/inventory.py ${IPS[@]}

ansible all -m ping -i inventory/mycluster/hosts.yaml

vi inventory/mycluster/group_vars/k8s_cluster/addons.yml

ansible-playbook -i inventory/mycluster/hosts.yaml --become --become-user=root cluster.yml

deactivate&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

kubectl get nodes
kubectl get componentstatus
kubectl get --raw=&amp;#39;/readyz?verbose&amp;#39;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="vi-inventorymyclusterhostsyaml"&gt;
 vi inventory/mycluster/hosts.yaml
 &lt;a class="heading-anchor" href="#vi-inventorymyclusterhostsyaml" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;all&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ks-master&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ansible_host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.10.100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.10.100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;access_ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.10.100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ks-worker-1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ansible_host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.10.210&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.10.210&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;access_ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.10.210&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ks-worker-2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ansible_host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.10.220&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.10.220&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;access_ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.10.220&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kube_control_plane&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ks-master&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kube_node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ks-worker-1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ks-worker-2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;etcd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ks-master&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;k8s_cluster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kube_control_plane&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kube_node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;calico_rr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Install K3S(v1.29.5+k3s1) on Multipass</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-k3sv1.29.5+k3s1-on-multipass/</link><pubDate>Mon, 20 May 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-k3sv1.29.5+k3s1-on-multipass/</guid><description>&lt;h2 id="vm-deployments-used-multipass-on-mac"&gt;
 VM deployments used multipass on mac
 &lt;a class="heading-anchor" href="#vm-deployments-used-multipass-on-mac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;master node 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass launch --name k3s-master --cpus &lt;span class="m"&gt;2&lt;/span&gt; --memory 4G --disk 50G focal&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;worker1 node 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass launch --name k3s-worker1 --cpus &lt;span class="m"&gt;2&lt;/span&gt; --memory 4G --disk 50G focal&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;worker2 node 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass launch --name k3s-worker2 --cpus &lt;span class="m"&gt;2&lt;/span&gt; --memory 4G --disk 50G focal&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;registry node 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass launch --name registry --cpus &lt;span class="m"&gt;2&lt;/span&gt; --memory 4G --disk 100G focal&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ubuntu-구동-확인"&gt;
 ubuntu 구동 확인
 &lt;a class="heading-anchor" href="#ubuntu-%ea%b5%ac%eb%8f%99-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass ls&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass info --all&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="ubuntu-swapoff"&gt;
 ubuntu swapoff
 &lt;a class="heading-anchor" href="#ubuntu-swapoff" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;master node swapoff&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; k3s-master -- /bin/bash -c &lt;span class="s2"&gt;&amp;#34;sudo swapoff -a&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;worker1 node swapoff&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; k3s-worker1 -- /bin/bash -c &lt;span class="s2"&gt;&amp;#34;sudo swapoff -a&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;worker2 node swapoff&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; k3s-worker2 -- /bin/bash -c &lt;span class="s2"&gt;&amp;#34;sudo swapoff -a&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;registry node swapoff&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; registry -- /bin/bash -c &lt;span class="s2"&gt;&amp;#34;sudo swapoff -a&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ubuntu-메모리-사용량-확인"&gt;
 ubuntu 메모리 사용량 확인
 &lt;a class="heading-anchor" href="#ubuntu-%eb%a9%94%eb%aa%a8%eb%a6%ac-%ec%82%ac%ec%9a%a9%eb%9f%89-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;master node 메모리 사용량 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; k3s-master -- /bin/bash -c &lt;span class="s2"&gt;&amp;#34;free -m&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;worker1 node 메모리 사용량 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; k3s-worker1 -- /bin/bash -c &lt;span class="s2"&gt;&amp;#34;free -m&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;worker2 node 메모리 사용량 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; k3s-worker2 -- /bin/bash -c &lt;span class="s2"&gt;&amp;#34;free -m&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;registry node 메모리 사용량 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; registry -- /bin/bash -c &lt;span class="s2"&gt;&amp;#34;free -m&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="k3s-master-설치"&gt;
 k3s master 설치
 &lt;a class="heading-anchor" href="#k3s-master-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; k3s-master -- /bin/bash -c &lt;span class="s2"&gt;&amp;#34;curl -sfL https://get.k3s.io | K3S_KUBECONFIG_MODE=&amp;#34;&lt;/span&gt;644&lt;span class="s2"&gt;&amp;#34; sh -&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="k3s-master-token-정보-조회"&gt;
 k3s master Token 정보 조회
 &lt;a class="heading-anchor" href="#k3s-master-token-%ec%a0%95%eb%b3%b4-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; k3s-master -- /bin/bash -c &lt;span class="s2"&gt;&amp;#34;sudo cat /var/lib/rancher/k3s/server/node-token&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="k3s-worker-node-설치"&gt;
 k3s worker Node 설치
 &lt;a class="heading-anchor" href="#k3s-worker-node-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; k3s-node1 -- /bin/bash -c &lt;span class="s2"&gt;&amp;#34;curl -sfL https://get.k3s.io | K3S_TOKEN=\&amp;#34;&amp;lt;토큰 정보&amp;gt;\&amp;#34; K3S_URL=https://&amp;lt;마스터 노드 IP&amp;gt;:6443 sh -&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;K3S_NODEIP_MASTER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;multipass info k3s-master &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="s2"&gt;&amp;#34;IPv4&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; awk -F&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;{print $2}&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;:6443&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;K3S_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; k3s-master -- /bin/bash -c &lt;span class="s2"&gt;&amp;#34;sudo cat /var/lib/rancher/k3s/server/node-token&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; k3s-worker1 -- /bin/bash -c &lt;span class="s2"&gt;&amp;#34;curl -sfL https://get.k3s.io | K3S_TOKEN=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;K3S_TOKEN&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; K3S_URL=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;K3S_NODEIP_MASTER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; sh -&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; k3s-worker2 -- /bin/bash -c &lt;span class="s2"&gt;&amp;#34;curl -sfL https://get.k3s.io | K3S_TOKEN=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;K3S_TOKEN&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; K3S_URL=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;K3S_NODEIP_MASTER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; sh -&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="k3s-노드-정보를-확인-한다"&gt;
 k3s 노드 정보를 확인 한다.
 &lt;a class="heading-anchor" href="#k3s-%eb%85%b8%eb%93%9c-%ec%a0%95%eb%b3%b4%eb%a5%bc-%ed%99%95%ec%9d%b8-%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; k3s-master kubectl get nodes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="copy-multipass-vm-kubectl-config-locally"&gt;
 Copy multipass vm kubectl config locally
 &lt;a class="heading-anchor" href="#copy-multipass-vm-kubectl-config-locally" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;계속 multipass cli를 사용하기는 귀찮으므로 k3s master node에서 k3s.yaml 파일을 로컬 Mac으로 가져온다.&lt;/li&gt;
&lt;li&gt;kubectl은 미리 Mac에 설치 되어 있었고, 없다면 설치 해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass copy-files k3s-master:/etc/rancher/k3s/k3s.yaml &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/.kube/k3s.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sed -ie s,https://127.0.0.1:6443,&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;K3S_NODEIP_MASTER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;,g &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/.kube/k3s.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;kubectl --kubeconfig&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/.kube/k3s.yaml get nodes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="configure-cluster-node-roles-and-taint"&gt;
 Configure cluster node roles and taint
 &lt;a class="heading-anchor" href="#configure-cluster-node-roles-and-taint" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;NAME STATUS ROLES AGE VERSION
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;k3s-master Ready control-plane,master 36m v1.29.5+k3s1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;k3s-worker1 Ready &amp;lt;none&amp;gt; 29m v1.29.5+k3s1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;k3s-worker2 Ready &amp;lt;none&amp;gt; 29m v1.29.5+k3s1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl --kubeconfig&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/.kube/k3s.yaml label node k3s-master node-role.kubernetes.io/master&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl --kubeconfig&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/.kube/k3s.yaml label node k3s-worker1 node-role.kubernetes.io/node&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;kubectl --kubeconfig&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/.kube/k3s.yaml label node k3s-worker2 node-role.kubernetes.io/node&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl --kubeconfig&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/.kube/k3s.yaml taint node k3s-master node-role.kubernetes.io/master&lt;span class="o"&gt;=&lt;/span&gt;effect:NoSchedule
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;kubectl --kubeconfig&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/.kube/k3s.yaml get nodes -o wide&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;NAME STATUS ROLES AGE VERSION
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;k3s-worker1 Ready node 33m v1.29.5+k3s1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;k3s-worker2 Ready node 32m v1.29.5+k3s1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;k3s-master Ready control-plane,master 39m v1.29.5+k3s1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Multipass] Setting Ubuntu</title><link>https://kyungryeol-yoon.github.io/environment/virtualization/linux-multipass/</link><pubDate>Sun, 19 May 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/environment/virtualization/linux-multipass/</guid><description>&lt;h2 id="multipass-설치"&gt;
 Multipass 설치
 &lt;a class="heading-anchor" href="#multipass-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew install --cask multipass&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="공식-홈페이지"&gt;
 공식 홈페이지
 &lt;a class="heading-anchor" href="#%ea%b3%b5%ec%8b%9d-%ed%99%88%ed%8e%98%ec%9d%b4%ec%a7%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://multipass.run"&gt;https://multipass.run&lt;/a&gt; 공식 홈페이지에서 직접 pkg를 받아 다운로드받을 수도 있다. 맥 OS 말고도 리눅스와 윈도우도 지원한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="multipass-사용"&gt;
 Multipass 사용
 &lt;a class="heading-anchor" href="#multipass-%ec%82%ac%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="instance-생성"&gt;
 Instance 생성
 &lt;a class="heading-anchor" href="#instance-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;현재 multipass를 통해 생성할 수 있는 Instance의 모든 Image 목록이 표시된다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass find&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Instance 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass launch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;사용할 버전을 명시해줄 수도 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass launch 20.04&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;위와 같은 옵션 값을 통해 Instance의 스펙을 조절해줄 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass launch --cpus &amp;lt;cpus&amp;gt; --disk &amp;lt;disk&amp;gt; --memory &amp;lt;mem&amp;gt; --name &amp;lt;name&amp;gt; --cloud-init cloud-init.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;-c, --cpus &amp;lt;cpus&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;할당할 CPU의 개수
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;최소값 : 1, 기본값 : &lt;span class="m"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;-d, --disk &amp;lt;disk&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;할당할 저장공간
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;기본적으로 byte 단위이며, K, M, G 접미사를 붙여서 단위를 지정할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;-m, --memory &amp;lt;mem&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;할당할 메모리
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;기본적으로 byte 단위이며, K, M, G 접미사를 붙여서 단위를 지정할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;-n, --name &amp;lt;name&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;Instance의 이름을 지정해준다.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;--cloud-init &amp;lt;file&amp;gt; &lt;span class="p"&gt;|&lt;/span&gt; &amp;lt;url&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;Cloud 초기화 파일을 사용하여 가상 Instance를 설정한다. Cloud 초기화 파일은 yaml 형식의 설정 파일로, Instance 시작 시 다양한 초기 설정을 자동으로 수행할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="instance-목록-조회"&gt;
 Instance 목록 조회
 &lt;a class="heading-anchor" href="#instance-%eb%aa%a9%eb%a1%9d-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;list 명령어로 존재하는 Instance들을 확인할 수 있다. ls로 줄여쓸 수도 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="instance-resource-변경"&gt;
 Instance Resource 변경
 &lt;a class="heading-anchor" href="#instance-resource-%eb%b3%80%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;local.&lt;instance-name&gt;을 통해서 Resource를 변경할 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass stop some-instance
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;set&lt;/span&gt; local.some-instance.cpus&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;set&lt;/span&gt; local.some-instance.disk&lt;span class="o"&gt;=&lt;/span&gt;40G
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;set&lt;/span&gt; local.some-instance.memory&lt;span class="o"&gt;=&lt;/span&gt;8G&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Instance의 Disk 크기를 늘릴 때 Partition이 자동으로 확장되지 않아 새로운 사용 가능한 공간을 사용하지 못할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;이는 일반적으로 Disk 크기를 늘리려고 할 때 Partition이 이미 꽉 찬 경우에 발생한다.
{: .prompt-warning }&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="다음과-같이-파티션을-수동으로-확장해야-한다"&gt;
 다음과 같이 파티션을 수동으로 확장해야 한다.
 &lt;a class="heading-anchor" href="#%eb%8b%a4%ec%9d%8c%ea%b3%bc-%ea%b0%99%ec%9d%b4-%ed%8c%8c%ed%8b%b0%ec%85%98%ec%9d%84-%ec%88%98%eb%8f%99%ec%9c%bc%eb%a1%9c-%ed%99%95%ec%9e%a5%ed%95%b4%ec%95%bc-%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;some-instance Shell에 접속&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;$ multipass shell some-instance
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;ubuntu@some-instance$ sudo parted /dev/sda resizepart &lt;span class="m"&gt;1&lt;/span&gt; 100%
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;Warning: Not all of the space available to /dev/sda appears to be used, you can fix the GPT to use all of the space &lt;span class="o"&gt;(&lt;/span&gt;an extra &lt;span class="m"&gt;4194304&lt;/span&gt; blocks&lt;span class="o"&gt;)&lt;/span&gt; or &lt;span class="k"&gt;continue&lt;/span&gt; with the current setting?
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;Fix/Ignore? fix
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;Partition number? &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;Warning: Partition /dev/sda1 is being used. Are you sure you want to &lt;span class="k"&gt;continue&lt;/span&gt;?
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;Yes/No? yes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;ubuntu@some-instance$ sudo resize2fs /dev/sda1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="instance-shell-접속"&gt;
 Instance Shell 접속
 &lt;a class="heading-anchor" href="#instance-shell-%ec%a0%91%ec%86%8d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;shell 명령어를 통해 해당 Instance의 쉘에 접근할 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass shell &amp;lt;instance name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="instance-명령-실행"&gt;
 Instance 명령 실행
 &lt;a class="heading-anchor" href="#instance-%eb%aa%85%eb%a0%b9-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;어느 Instance가 특정한 명령을 수행하길 원한다면, exec 명령어를 사용하면 된다. &lt;code&gt;--&lt;/code&gt; 하이픈 두개 뒤에 수행할 명령어를 기입해준다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; &amp;lt;instance name&amp;gt; -- &amp;lt;명령어&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="instance-정지"&gt;
 Instance 정지
 &lt;a class="heading-anchor" href="#instance-%ec%a0%95%ec%a7%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;stop 명령어를 통해 Instance를 정지시킬 수 있다. 정지된 Instance는 State가 Stopped가 된다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass stop &amp;lt;instance name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="instance-시작"&gt;
 Instance 시작
 &lt;a class="heading-anchor" href="#instance-%ec%8b%9c%ec%9e%91" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;start 명령어를 통해 정지되어 있던(Stopped 상태) Instance를 실행시킬 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass start &amp;lt;instance name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="instance-삭제"&gt;
 Instance 삭제
 &lt;a class="heading-anchor" href="#instance-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;delete 명령어를 통해 Instance를 삭제할 수 있다. 해당 명령어를 통해 Instance를 삭제할 경우, 완전히 없어지는 것이 아니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ls 명령을 통해 Instance 목록을 조회할 시, State가 deleted인 상태로 남아있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass delete &amp;lt;instance name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="instance-복구"&gt;
 Instance 복구
 &lt;a class="heading-anchor" href="#instance-%eb%b3%b5%ea%b5%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;recover 명령어를 통해 deleted 상태인 Instance를 복구할 수 있다. 복구된 Instance는 Stopped 상태가 된다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass recover &amp;lt;instance name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="instance-영구-삭제"&gt;
 Instance 영구 삭제
 &lt;a class="heading-anchor" href="#instance-%ec%98%81%ea%b5%ac-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;purge 명령어를 통해 deleted 상태인 Instance를 영구 삭제한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass purge&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;delete와 purge를 한 번에 실행할 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass delete --purge &amp;lt;instance-name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="multipass-ssh-접속"&gt;
 Multipass ssh 접속
 &lt;a class="heading-anchor" href="#multipass-ssh-%ec%a0%91%ec%86%8d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;가상 Instance에 일반적인 ssh 명령으로 Shell에 접속 시도하게 되면 permission denied로 접속이 되지 않는다.&lt;/li&gt;
&lt;li&gt;이를 해결하기 위해서 다음 단계를 수행한다.
&lt;ul&gt;
&lt;li&gt;ssh 키 생성&lt;/li&gt;
&lt;li&gt;Instance 생성시 적용될 yaml 파일 작성&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--cloud-init&lt;/code&gt; 옵션을 지정하여 Instance 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ssh-key-생성"&gt;
 ssh key 생성
 &lt;a class="heading-anchor" href="#ssh-key-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;명령을 수행하면 &lt;code&gt;$HOME/.ssh&lt;/code&gt; 경로에 id_rsa_multipass (개인키), id_rsa_multipass.pub (공개키) 파일이 생성된다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ssh-keygen -t rsa -b &lt;span class="m"&gt;2048&lt;/span&gt; -f ~/.ssh/id_rsa_multipass&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="cloud-init-옵션에-적용할-yaml-파일-작성"&gt;
 cloud-init 옵션에 적용할 yaml 파일 작성
 &lt;a class="heading-anchor" href="#cloud-init-%ec%98%b5%ec%85%98%ec%97%90-%ec%a0%81%ec%9a%a9%ed%95%a0-yaml-%ed%8c%8c%ec%9d%bc-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ssh_authorized_keys 설정 항목에 id_rsa_multipass.pub 파일의 내용을 그대로 복사하여 설정하면 Instance 생성 시 지정된 공개키가 Instance에 적용된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Instance의 &lt;code&gt;$HOME/.ssh/authorized_keys&lt;/code&gt; 파일에 공개키가 저장된다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ubuntu&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;sudo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ALL=(ALL) NOPASSWD:ALL&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ssh_authorized_keys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;&amp;lt;id_rsa_multipass.pub 파일 내용&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="instance-생성-1"&gt;
 Instance 생성
 &lt;a class="heading-anchor" href="#instance-%ec%83%9d%ec%84%b1-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;yaml 파일을 &lt;code&gt;$HOME/multipass/cloud-init/cloud-init-ssh.yaml&lt;/code&gt; 경로에 저장한 경우 위와 같이 실행한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass launch focal --name some-instance --cloud-init ~/multipass/cloud-init/cloud-init-ssh.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ssh 접속&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ssh -i &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.ssh/id_rsa_multipass ubuntu@192.168.64.2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-i&lt;/code&gt; 옵션과 함께 개인키 경로를 매번 지정하기 귀찮다면 &lt;code&gt;$HOME/.ssh/config&lt;/code&gt; 파일에 다음과 같이 설정한다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-conf" data-lang="conf"&gt;Host multipass-some-instance
 User ubuntu
 Hostname 192.168.64.2
 IdentityFile ~/.ssh/id_rsa_multipass&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ssh 간편하게 접속&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ssh multipass-some-instance&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="multipass-snapshot"&gt;
 Multipass Snapshot
 &lt;a class="heading-anchor" href="#multipass-snapshot" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="snapshot-생성"&gt;
 Snapshot 생성
 &lt;a class="heading-anchor" href="#snapshot-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass snapshot &amp;lt;instance name&amp;gt; -n, --name &amp;lt;snapshot name&amp;gt; --comment, -c, -m &amp;lt;comment&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;multipass snapshot kk-repo -n kk-repo-snap-test -c test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Snapshot 이름 없이 생성 했을 시, snapshot(1,2,3&amp;hellip;)으로 자동 저장된다.
{: .prompt-tip }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="snapshot-조회"&gt;
 Snapshot 조회
 &lt;a class="heading-anchor" href="#snapshot-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass list --snapshots
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;Instance Snapshot Parent Comment
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kk-repo kk-repo-snap-test -- test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="snapshot-복원"&gt;
 Snapshot 복원
 &lt;a class="heading-anchor" href="#snapshot-%eb%b3%b5%ec%9b%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass restore &amp;lt;instance name&amp;gt;.&amp;lt;snapshot name&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;multipass restore kk-repo.kk-repo-snap-test
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;Do you want to take a snapshot of kk-repo before discarding its current state? &lt;span class="o"&gt;(&lt;/span&gt;Yes/no&lt;span class="o"&gt;)&lt;/span&gt;: yes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;Snapshot taken: kk-repo.snapshot2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;Snapshot restored: kk-repo.kk-repo-snap-test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="snapshot-삭제"&gt;
 Snapshot 삭제
 &lt;a class="heading-anchor" href="#snapshot-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass delete &lt;span class="o"&gt;[&lt;/span&gt;options&lt;span class="o"&gt;]&lt;/span&gt; &amp;lt;instance&amp;gt;&lt;span class="o"&gt;[&lt;/span&gt;.snapshot&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&amp;lt;instance&amp;gt;&lt;span class="o"&gt;[&lt;/span&gt;.snapshot&lt;span class="o"&gt;]&lt;/span&gt; ...&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;multipass delete kk-repo.snapshot2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;Snapshots can only be purged &lt;span class="o"&gt;(&lt;/span&gt;after deletion, they cannot be recovered&lt;span class="o"&gt;)&lt;/span&gt;. Are you sure you want to &lt;span class="k"&gt;continue&lt;/span&gt;? &lt;span class="o"&gt;(&lt;/span&gt;Yes/no&lt;span class="o"&gt;)&lt;/span&gt;: yes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="multipass-alias"&gt;
 Multipass Alias
 &lt;a class="heading-anchor" href="#multipass-alias" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;특정 Instance에서 명령을 실행하는 alias(별칭)을 만들어 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="alias-등록"&gt;
 Alias 등록
 &lt;a class="heading-anchor" href="#alias-%eb%93%b1%eb%a1%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;alias&lt;/span&gt; &amp;lt;instance-name&amp;gt;:&amp;lt;command&amp;gt; &amp;lt;alias-name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="alias-목록"&gt;
 Alias 목록
 &lt;a class="heading-anchor" href="#alias-%eb%aa%a9%eb%a1%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass aliases&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="alias-삭제"&gt;
 Alias 삭제
 &lt;a class="heading-anchor" href="#alias-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;unalias&lt;/span&gt; &amp;lt;alias-name&amp;gt; ... &amp;lt;alias-name&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;unalias&lt;/span&gt; --all&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="alias-실행"&gt;
 Alias 실행
 &lt;a class="heading-anchor" href="#alias-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &amp;lt;alias-name&amp;gt; -- &amp;lt;argument&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Shell 설정파일 (.bashrc, .zshrc, ..) 에 PATH 환경 변수에 아래 경로를 등록하면 multipass prefix는 생략 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;각 OS 마다 경로는 다음과 같지만 환경마다 다를 수 있다.&lt;/li&gt;
&lt;li&gt;macOS의 경우 alias 등록 시 PATH 환경 변수에 추가할 경로가 안내된다.
{: .prompt-tip }&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#MacOS m1 silicon&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/Library/Application Support/multipass/bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#Linux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/snap/multipass/common/bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#Windows&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;https://multipass.run/docs/using-aliases#heading--windows 참조&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;PATH 환경 변수에 경로가 추가되면 다음과 같이 multipass prefix 없이 사용 가능하다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&amp;lt;alias-name&amp;gt; --help
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&amp;lt;alias-name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="multipass-mount"&gt;
 Multipass Mount
 &lt;a class="heading-anchor" href="#multipass-mount" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;multipass mount 명령을 사용하여 Host와 Instance 간의 데이터를 공유할 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Instance 생성시 Mount&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;multipass launch --mount &amp;lt;host-path&amp;gt;:&amp;lt;instance-path&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 이미 존재하는 Mount에 대해서 Mount 설정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;multipass mount &amp;lt;host-path&amp;gt; &amp;lt;instance-name&amp;gt;:&amp;lt;instance-path&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="multipass-복사-및-전송"&gt;
 Multipass 복사 및 전송
 &lt;a class="heading-anchor" href="#multipass-%eb%b3%b5%ec%82%ac-%eb%b0%8f-%ec%a0%84%ec%86%a1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="복사-명령어"&gt;
 복사 명령어
 &lt;a class="heading-anchor" href="#%eb%b3%b5%ec%82%ac-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass copy-files &lt;span class="o"&gt;[&lt;/span&gt;복사할 파일 path&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;설정한 multipass 이름&lt;span class="o"&gt;]&lt;/span&gt;:&lt;span class="o"&gt;[&lt;/span&gt;복사할 path&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;multipass copy-files C:&lt;span class="se"&gt;\P&lt;/span&gt;rogramData&lt;span class="se"&gt;\M&lt;/span&gt;ultipass&lt;span class="se"&gt;\d&lt;/span&gt;ata&lt;span class="se"&gt;\s&lt;/span&gt;sh-keys&lt;span class="se"&gt;\i&lt;/span&gt;d_rsa primary:/home/ubuntu/.ssh/id_rsa&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="전송-명령어"&gt;
 전송 명령어
 &lt;a class="heading-anchor" href="#%ec%a0%84%ec%86%a1-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass transfer &lt;span class="o"&gt;[&lt;/span&gt;options&lt;span class="o"&gt;]&lt;/span&gt; &amp;lt;source&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt;&amp;lt;source&amp;gt; ...&lt;span class="o"&gt;]&lt;/span&gt; &amp;lt;destination&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="instance--host로-파일-전송"&gt;
 Instance ➡ Host로 파일 전송
 &lt;a class="heading-anchor" href="#instance--host%eb%a1%9c-%ed%8c%8c%ec%9d%bc-%ec%a0%84%ec%86%a1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# some-instance의 /home/ubuntu/transfer_file을 Host의 $HOME/multipass_shared 경로에 전송한다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;$ multipass transfer some-instance:/home/ubuntu/transfer_file &lt;span class="nv"&gt;$HOME&lt;/span&gt;/multipass_shared
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# some-instance의 /home/ubuntu/transfer_file 내용을 Host의 stdout 으로 출력한다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;$ multipass transfer some-instance:/home/ubuntu/transfer_file -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;테스트용 전송 데이터
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;테스트용 전송 데이터&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="host--instance로-파일-전송"&gt;
 Host ➡ Instance로 파일 전송
 &lt;a class="heading-anchor" href="#host--instance%eb%a1%9c-%ed%8c%8c%ec%9d%bc-%ec%a0%84%ec%86%a1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Host의 $HOME/multipass_shared/directory1 Directory 전체를 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# some-instance의 /home/ubuntu/directory1 으로 전송한다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;$ multipass transfer -r &lt;span class="nv"&gt;$HOME&lt;/span&gt;/multipass_shared/directory1 some-instance:/home/ubuntu/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Host의 stdin (사용자 입력) 데이터를 some-instance의 /home/ubuntu/console_output 파일에 저장한다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 참고로 stdin 입력 종료는 Ctrl + D 로 종료한다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;$ multipass transfer - some-instance:/home/ubuntu/console_output
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;this is &lt;span class="nb"&gt;test&lt;/span&gt; message1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;this is &lt;span class="nb"&gt;test&lt;/span&gt; message2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;this is &lt;span class="nb"&gt;test&lt;/span&gt; message3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;Ctrl + D
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# some-instance의 /home/ubuntu/console_outpout 파일 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;$ multipass &lt;span class="nb"&gt;exec&lt;/span&gt; some-instance -- cat /home/ubuntu/console_output
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;this is &lt;span class="nb"&gt;test&lt;/span&gt; message1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;this is &lt;span class="nb"&gt;test&lt;/span&gt; message2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;this is &lt;span class="nb"&gt;test&lt;/span&gt; message3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;cloud init examples&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cloudinit.readthedocs.io/en/latest/reference/examples.html"&gt;https://cloudinit.readthedocs.io/en/latest/reference/examples.html&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Install Tempo(v2.4.1) Using Helm Chart</title><link>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-install-tempov2.4.1-using-helm/</link><pubDate>Thu, 09 May 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-install-tempov2.4.1-using-helm/</guid><description>&lt;h2 id="tempo"&gt;
 Tempo
 &lt;a class="heading-anchor" href="#tempo" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;트레이스(Trace)는 시스템, 소프트웨어 응용 프로그램 또는 사용자의 이벤트 또는 활동이 시간 순서대로 기록된 정보를 나타낸다.&lt;/li&gt;
&lt;li&gt;Application이 단일 데이터베이스가 있는 모놀리식이든 여러 서비스가 있는 분산 시스템이든 관계없이 Application에서 요청이 취하는 전체 &amp;ldquo;경로&amp;quot;를 이해하려면 트레이스가 필수적이다.&lt;/li&gt;
&lt;li&gt;메트릭(Metric)과 로그(Log)은 특정 시스템 내부에서의 동작을 볼 수 있지만, 분산 시스템에서의 문제 해결에는 부족하다.&lt;/li&gt;
&lt;li&gt;이러한 이유로 트레이스가 필요하며, 이는 디버깅, 성능 분석 및 다양한 시나리오에서의 Application 동작 이해와 같은 다양한 목적으로 사용될 수 있다.&lt;/li&gt;
&lt;li&gt;Tempo는 Grafana Labs에서 개발한 오픈 소스 분산 추적 백엔드(distributed tracing backend)
&lt;ul&gt;
&lt;li&gt;이는 매우 효율적이고 확장 가능한 방식으로 트레이스 데이터를 저장, 인덱싱 및 검색하기 위해 설계되었다.&lt;/li&gt;
&lt;li&gt;Tempo는 Grafana 옵저버빌리티(Observability) 스택의 일부이며, Grafana, Prometheus 및 Loki와 긴밀하게 통합된다.&lt;/li&gt;
&lt;li&gt;비용 효율적이며 작동하는 데 오브젝트 스토리지만 필요하다.&lt;/li&gt;
&lt;li&gt;Jaeger, Zipkin 또는 OpenTelemetry를 포함한 오픈 소스 추적 프로토콜과 함께 Tempo를 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;Tempo는 LogQL과 PromQL에서 영감을 얻은 추적 우선 쿼리 언어인 TraceQL을 구현한다.
&lt;ul&gt;
&lt;li&gt;이 쿼리 언어를 사용하면 사용자는 매우 정확하고 쉽게 스팬(Span)을 선택하고 지정된 조건을 충족하는 스팬으로 바로 이동할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="install-the-tempo-helm-charts"&gt;
 Install the Tempo Helm charts
 &lt;a class="heading-anchor" href="#install-the-tempo-helm-charts" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo add grafana https://grafana.github.io/helm-charts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;helm install tempo grafana/tempo --namespace &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Tempo - Helm 설치 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/tempo/latest/setup/helm-chart/"&gt;https://grafana.com/docs/tempo/latest/setup/helm-chart/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="customize-default-configuration"&gt;
 Customize Default Configuration
 &lt;a class="heading-anchor" href="#customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;values.yaml 수정&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;최상위 values.yaml을 수정하면 하위 폴더 values.yaml을 override 한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Chart
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana/helm-charts/tree/main/charts/tempo"&gt;https://github.com/grafana/helm-charts/tree/main/charts/tempo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Release file (.tgz)
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana/helm-charts/releases"&gt;https://github.com/grafana/helm-charts/releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="setting-config"&gt;
 Setting Config
 &lt;a class="heading-anchor" href="#setting-config" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h3 id="install-customize-default-configuration"&gt;
 Install Customize Default Configuration
 &lt;a class="heading-anchor" href="#install-customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;Chart.yaml 경로&lt;span class="o"&gt;]&lt;/span&gt; -f &lt;span class="o"&gt;[&lt;/span&gt;YAML 파일 또는 URL에 값 지정 &lt;span class="o"&gt;(&lt;/span&gt;여러 개를 지정가능&lt;span class="o"&gt;)]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install tempo grafana/tempo -f override-values.yaml -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="uninstall-the-chart"&gt;
 Uninstall the Chart
 &lt;a class="heading-anchor" href="#uninstall-the-chart" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm uninstall &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Install Loki(v2.9.4) Stack Using Helm Chart</title><link>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-install-lokiv2.9.4-stack-using-helm/</link><pubDate>Fri, 19 Apr 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-install-lokiv2.9.4-stack-using-helm/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="install-the-loki-stack-helm-charts"&gt;
 Install the Loki Stack Helm charts
 &lt;a class="heading-anchor" href="#install-the-loki-stack-helm-charts" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo add grafana https://grafana.github.io/helm-charts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;helm install loki-stack grafana/loki-stack --namespace &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt; --version &lt;span class="o"&gt;[&lt;/span&gt;VERSION&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Loki Stack - Helm 설치 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/loki/latest/setup/install/helm/"&gt;https://grafana.com/docs/loki/latest/setup/install/helm/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="customize-default-configuration"&gt;
 Customize Default Configuration
 &lt;a class="heading-anchor" href="#customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;values.yaml 수정&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;최상위 values.yaml을 수정하면 하위 폴더 values.yaml을 override 한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Chart
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana/helm-charts/tree/main/charts/loki-stack"&gt;https://github.com/grafana/helm-charts/tree/main/charts/loki-stack&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Release file (.tgz)
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana/helm-charts/releases"&gt;https://github.com/grafana/helm-charts/releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="setting-promtail"&gt;
 Setting Promtail
 &lt;a class="heading-anchor" href="#setting-promtail" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;promtail&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;info&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serverPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3101&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;clients&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://{{ .Release.Name }}:3100/loki/api/v1/push&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-install-promtail(v2.9.4)-using-helm/"&gt;Promtail 설치 및 설정 관련 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="setting-loki"&gt;
 Setting Loki
 &lt;a class="heading-anchor" href="#setting-loki" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;loki&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;isDefault&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://{{(include &amp;#34;loki.serviceName&amp;#34; .)}}:{{ .Values.loki.service.port }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readinessProbe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;httpGet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/ready&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http-metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;livenessProbe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;httpGet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/ready&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http-metrics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;datasource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-loki(v2.9.4)/"&gt;Loki 관련 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="setting-grafana"&gt;
 Setting Grafana
 &lt;a class="heading-anchor" href="#setting-grafana" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;grafana&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;sidecar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;datasources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labelValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;maxLines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10.3.3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-install-grafana(v9.5.21)-using-helm/"&gt;Grafana 설치 및 설정 관련 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="install-customize-default-configuration"&gt;
 Install Customize Default Configuration
 &lt;a class="heading-anchor" href="#install-customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;Chart.yaml 경로&lt;span class="o"&gt;]&lt;/span&gt; -f &lt;span class="o"&gt;[&lt;/span&gt;YAML 파일 또는 URL에 값 지정 &lt;span class="o"&gt;(&lt;/span&gt;여러 개를 지정가능&lt;span class="o"&gt;)]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install loki-stack grafana/loki-stack -f override-values.yaml -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="uninstall-the-chart"&gt;
 Uninstall the Chart
 &lt;a class="heading-anchor" href="#uninstall-the-chart" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm uninstall &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Loki(v2.9.4)</title><link>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-lokiv2.9.4/</link><pubDate>Sun, 07 Apr 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-lokiv2.9.4/</guid><description>&lt;h2 id="loki"&gt;
 Loki
 &lt;a class="heading-anchor" href="#loki" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Loki는 로그 전체 TEXT가 아닌 metadata만 인덱싱하는 방식을 취한다.&lt;/li&gt;
&lt;li&gt;이런 최소 인덱싱 접근 방식은 다른 솔루션보다 적은 저장 공간이 필요함을 의미한다.&lt;/li&gt;
&lt;li&gt;Loki를 위해 만들어진 로그 수집 도구인 Promtail 또는 OpenTelemetry를 통해 로그를 가져와 로그를 저장한다.&lt;/li&gt;
&lt;li&gt;이후 Grafana에서 LogQL이라는 쿼리 언어를 통해 로그를 검색하게 된다.&lt;/li&gt;
&lt;li&gt;또한 경고 규칙을 설정하여 Prometheus Alertmanager로 경고를 보낼 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Loki 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/grafana/loki"&gt;https://github.com/grafana/loki&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ldquo;Like Prometheus, but for logs&amp;rdquo;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Prometheus가 metric을 시계열 데이터로 저장하기 위해 사용된다면 Loki는 log 데이터를 저장하기 위해 사용된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Loki는 log data를 효율적으로 보관하기 위해 최적화된 데이터 저장소이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;다른 logging system과 다르게 Loki index는 label에서 작성되며 원래 log message는 색인화되지 않는다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Prometheus가 저장과 polling을 담당한 것과 달리 Loki는 저장을 담당하고 application에서 push를 해주는 역할을 해주는 agent가 필요하다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Promtail agent는 Loki를 위해 설계되었지만 그 외에 다른 많은 agent(FluentD, LogStash 혹은 기타 서비스 애플리케이션)가 Loki와 원활하게 통합된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Loki는 stream을 indexing 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;각 steam은 고유한 label set과 연결된 log 집합을 식별한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;label의 quality set은 간결하고 효율적인 query 실행을 허용하는 index 생성의 핵심이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LogQL은 Loki의 query language이다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="loki-특징"&gt;
 Loki 특징
 &lt;a class="heading-anchor" href="#loki-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;log indexing을 위한 효율적인 memory 사용&lt;/li&gt;
&lt;li&gt;multi-tenancy&lt;/li&gt;
&lt;li&gt;LogQL - Prometheus의 Query Language인 PromQL과 유사하며, log data에서 metric을 생성하는 것이 용이함.&lt;/li&gt;
&lt;li&gt;Scalability - 단일 바이너리로 사용할 수도 있으나 component 별 microservice로 실행될 수도 있음&lt;/li&gt;
&lt;li&gt;Flexibility - 많은 agent가 플러그인을 지원&lt;/li&gt;
&lt;li&gt;Grafana 통합&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="loki-저장소"&gt;
 Loki 저장소
 &lt;a class="heading-anchor" href="#loki-%ec%a0%80%ec%9e%a5%ec%86%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Manage storage 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://grafana.com/docs/loki/latest/operations/storage/"&gt;https://grafana.com/docs/loki/latest/operations/storage/&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Loki는 chunk와 index라는 두 가지 유형의 데이터를 저장해야 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Loki는 별도의 stream으로 log를 수신하며 각 steam은 tenant ID와 label set으로 고유하게 식별된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;stream의 log 항목이 도착하면 chunk로 압축되어 chunk 저장소에 저장된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;index는 각 steam의 label set를 저장하고 개별 chunk에 연결한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;index에 대해 다음 저장소가 지원&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Single Store (boltdb-shipper)&lt;/li&gt;
&lt;li&gt;Amazon DynamoDB&lt;/li&gt;
&lt;li&gt;Google Bigtable&lt;/li&gt;
&lt;li&gt;Apache Cassandra&lt;/li&gt;
&lt;li&gt;BoltDB&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;chunk에 대해 다음 저장소가 지원&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Amazon DynamoDB&lt;/li&gt;
&lt;li&gt;Google Bigtable&lt;/li&gt;
&lt;li&gt;Apache Cassandra&lt;/li&gt;
&lt;li&gt;Amazon S3&lt;/li&gt;
&lt;li&gt;Google Cloud Storage&lt;/li&gt;
&lt;li&gt;FlieSystem&lt;/li&gt;
&lt;li&gt;Baidu Object Storage&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;기본 설정은 storage가 filesystem이며 Amazon S3의 경우 로컬에서 개발 시 minio를 사용할 수도 있다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;minio 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.min.io/how-to-grafana-loki-minio/"&gt;https://blog.min.io/how-to-grafana-loki-minio/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="loki-설정"&gt;
 Loki 설정
 &lt;a class="heading-anchor" href="#loki-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;설정 파일에 대한 자세한 내용&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://grafana.com/docs/loki/latest/configuration/"&gt;https://grafana.com/docs/loki/latest/configuration/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;common 아래에 설정을 하면 전체가 공통으로 사용할 설정을 하게 된다.
{: .prompt-info }&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Loki는 component별 microservice로 구성할 수 있다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Component 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/loki/latest/fundamentals/architecture/components/"&gt;https://grafana.com/docs/loki/latest/fundamentals/architecture/components/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Loki의 component는 대략 아래와 같이 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Distributor&lt;/strong&gt; : client가 수신하는 stream을 처리하는 역할, steam의 유효성을 확인하고 여러 ingester로 병렬로 전송을 적절하게 제어&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ingester&lt;/strong&gt; : storage에 log data를 저장하고 write path 및 read path의 memory 내 쿼리에 대한 log data를 반환&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Query frontend&lt;/strong&gt; : query 발송의 API endpoint를 제공하는 선택적 서비스&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Querier&lt;/strong&gt; : LogQL을 사용하여 query를 처리하고 ingester와 storage에서 log를 가져옴&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="loki-helm-charts"&gt;
 Loki Helm Charts
 &lt;a class="heading-anchor" href="#loki-helm-charts" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;grafana/loki 관련된 Helm chart들을 살펴보면 대략 5가지 정도가 존재
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;grafana/loki&lt;/strong&gt; : 현재 Grafana Loki에서 중점적으로 관리 및 업데이트하고 있는 Helm chart&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;grafana/loki-distributed&lt;/strong&gt; : Microservice 형태로 Loki를 관리할 수 있도록 해주는 Helm chart
&lt;ul&gt;
&lt;li&gt;Ingester, Querier, Index Gateway, Distributor, Query-Frontend, Ruler 등으로 구분되어 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;grafana/loki-simple-scalable&lt;/strong&gt; : 현재 Deprecated 되었지만 Loki를 아주 간단하게 관리할 수 있도록 도와주는 Helm chart
&lt;ul&gt;
&lt;li&gt;Write와 Read, Nginx gateway로만 구분되어 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;grafana/loki-stack&lt;/strong&gt; : 올인원 모놀리식 형태로 사용할 수 있는 Loki Helm chart&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="1-loki-stack"&gt;
 1. loki-stack
 &lt;a class="heading-anchor" href="#1-loki-stack" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;loki-stack&amp;rdquo; Helm 차트는 Loki를 단일 노드로 구성하여 배포하는 방법을 제공한다.&lt;/li&gt;
&lt;li&gt;이는 기본적인 Loki 설치를 위해 사용되며, 로그 수집, 저장 및 검색을 단일 노드에서 처리한다.&lt;/li&gt;
&lt;li&gt;이 단일 노드는 다수의 컨테이너로 구성되어 Loki 서버, Prometheus, Grafana 및 Prometheus 메트릭 저장소를 모두 단일 클러스터에 배포한다.&lt;/li&gt;
&lt;li&gt;이 단순한 배포 방식은 개발 및 테스트 용도로 적합할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-install-loki(v2.9.4)-stack-using-helm/"&gt;loki-stack 설치 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="2-loki-distributed"&gt;
 2. loki-distributed
 &lt;a class="heading-anchor" href="#2-loki-distributed" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;loki-distributed&amp;rdquo; Helm 차트는 Loki를 분산 환경에서 배포하기 위해 설계되었다.&lt;/li&gt;
&lt;li&gt;이 차트는 Loki의 구성 요소들을 다수의 노드로 분산시키고, 데이터를 보다 효율적으로 처리하고 처리 능력을 확장할 수 있도록 도와준다.&lt;/li&gt;
&lt;li&gt;분산된 Loki를 사용하면 대량의 로그를 처리하는 데 더 적합하며, 고가용성과 확장성을 갖추기 위해 다양한 구성을 가능하게 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-install-loki(v3.1.1)-distributed-using-helm/"&gt;loki-distributed 설치 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="architecture"&gt;
 Architecture
 &lt;a class="heading-anchor" href="#architecture" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;핵심 개념
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Read Path와 Write Path&lt;/strong&gt; : Loki는 로그 데이터 처리를 위한 읽기 경로(Read Path)와 쓰기 경로(Write Path)를 구분한다. 이러한 분리는 데이터 처리의 효율성을 극대화하며, 각 경로는 특정 작업에 최적화된 컴포넌트로 구성된다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consistent Hash Rings&lt;/strong&gt; : 클러스터 내에서 데이터를 균등하게 분배하고 고가용성을 보장하는 메커니즘이다. 이는 클러스터의 스케일링을 용이하게 하며, 데이터 샤딩과 복제를 통한 안정성을 제공한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multi-tenancy&lt;/strong&gt; : Loki는 다중 테넌시를 지원하여, 하나의 Loki 인스턴스를 여러 사용자나 팀이 공유할 수 있게 한다. 이는 리소스의 효율적인 사용과 데이터 분리를 가능하게 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/grafana/loki/loki_architecture_components.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="write-path-distributor-ingester"&gt;
 Write Path: Distributor, Ingester
 &lt;a class="heading-anchor" href="#write-path-distributor-ingester" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="distributor"&gt;
 Distributor
 &lt;a class="heading-anchor" href="#distributor" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;클라이언트로부터 수신한 로그 데이터를 검증 후 Ingester에게 전달하는 역할을 담당한다. 여기서 클라이언트는 Promtail이 될 수도 있고 FluentD, LogStash 혹은 기타 서비스 애플리케이션 쪽 로그 라이브러리가 될 수도 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Distributor의 주요 기능 및 특징&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;유효성 검사(Validation)&lt;/strong&gt; : Distributor는 수신된 스트림이 Grafana LGTM 사양에 부합하는지 첫 번째로 확인한다. 이는 데이터가 올바르게 처리될 수 있는지를 보장하기 위한 필수적인 과정이다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;전처리(Preprocessing)&lt;/strong&gt; : 스트림의 레이블을 정렬하는 과정으로, 이를 통해 Loki는 데이터를 효율적으로 캐시하고 해시할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;속도 제한(Rate limiting)&lt;/strong&gt; : 테넌트별 최대 전송률을 설정하여, 들어오는 로그의 전송률을 제어할 수 있다. 이는 시스템의 안정성을 유지하는 데 중요한 역할을 한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;전달(Forwarding)&lt;/strong&gt; : 모든 유효성 검사와 전처리 작업을 마친 후, 데이터는 Ingester로 전달된다. Ingester는 최종적으로 데이터의 쓰기를 승인하며, 이 과정에서 replication_factor를 참고하여 데이터 손실 위험을 최소화하기 위한 복제본을 생성한다.&lt;/li&gt;
&lt;li&gt;replication_factor가 3이라면 Ingester 내에 3개의 복제본을 생성하도록 3개의 스트림을 전달한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;해싱(Hashing)&lt;/strong&gt; : Distributor는 일관된 해싱을 사용해 특정 스트림이 전달될 Ingester 인스턴스를 결정한다. 이는 데이터가 올바른 대상에게 전달되도록 한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;쿼럼 일관성(Quorum consistency)&lt;/strong&gt; : Distributor는 최소 절반 이상의 Ingester로부터 응답을 받기 전까지는 클라이언트에게 응답을 보류한다. 이는 Dynamo 스타일의 쿼럼 일관성을 통해 데이터의 신뢰성을 높인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이러한 과정과 특징들은 Distributor가 Grafana Loki에서 매우 중요한 역할을 수행하게 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;특히, stateless한 성격 덕분에, 작업을 Ingester로 쉽게 확장하고 오프로드할 수 있으며, DDos 공격으로부터 시스템을 보호할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;또한 distributor는 내부에서 링 component를 사용하여 peers 사이에서 자신을 등록하고 총 active distributors를 얻는다. 이는 ingesters가 링에서 사용하는 것과는 다른 &amp;ldquo;키&amp;quot;이며 distributor의 자체 링 구성에서 비롯된다. 이는 Distributor의 효율성과 안정성을 더욱 높인다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="ingester"&gt;
 Ingester
 &lt;a class="heading-anchor" href="#ingester" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Distributor로부터 받은 로그 데이터를 메모리에 압축하여 chunks 단위로 저장하고 일정 시간 후 장기 저장소 백엔드(DynamoDB, S3, Cassandra 등)에 기록하는 역할을 담당한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ingester는 로그 데이터를 장기 저장소 백엔드(예: DynamoDB, S3, Cassandra 등)에 저장하고, 필요 시 인메모리 쿼리를 통해 이 데이터를 빠르게 검색하는 역할을 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ingester의 주요 기능 및 특징&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;수명 주기 관리&lt;/strong&gt; : Ingester 내에는 lifecycler라고 불리는 컴포넌트가 포함되어 있어, 해시 링을 통해 각 Ingester의 생명 주기를 관리한다. Ingester의 상태는 PENDING, JOINING, ACTIVE, LEAVING, 또는 UNHEALTHY 중 하나이다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;chunk 처리&lt;/strong&gt; : 로그 스트림은 메모리 내에서 여러 &amp;lsquo;chunk&amp;rsquo; 집합으로 관리되며, 설정 가능한 주기에 따라 장기 저장소 백엔드로 플러시된다. chunk는 용량에 도달하거나, 업데이트 없이 일정 시간이 지나거나, 플러시가 발생할 때 압축되고 읽기 전용으로 전환된다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;데이터 복제&lt;/strong&gt; : 갑작스러운 프로세스 종료나 충돌로 인해 아직 플러시되지 않은 데이터 손실을 방지하기 위해, Loki는 로그 데이터를 여러 Ingester에 복제한다(일반적으로 3개,replication_factor). 이는 데이터의 안정성과 가용성을 높인다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Timestamp Ordering&lt;/strong&gt; : Loki는 설정을 통해 시간 순서가 뒤섞인 데이터 쓰기를 허용할 수 있다. 이러한 설정 없이는 Ingester가 순서대로 입력되는 로그 라인을 확인하고, 순서가 맞지 않는 경우 오류를 반환한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;파일 시스템 지원&lt;/strong&gt; : Ingester는 BoltDB를 통해 파일 시스템에 쓰기를 지원하지만, queriers가 동일한 백엔드 저장소에 액세스해야 하고 BoltDB는 주어진 시간에 하나의 프로세스만 DB에 대한 잠금을 가질 수 있도록 허용하기 때문에 단일 프로세스 모드에서만 작동한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;작동 방식&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;플러시&lt;/strong&gt; : 장기 저장소로의 플러시 과정에서, chunk는 테넌트, 레이블, 콘텐츠를 기반으로 해시되어 중복된 데이터의 백업 저장소 쓰기를 방지한다. 그러나 복제본 중 하나에 쓰기가 실패하면 여러 개의 서로 다른 chunk 객체가 생성될 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이러한 기능과 특징들은 Ingester가 Grafana LGTM 아키텍처에서 중요한 역할을 수행하게 한다. 데이터의 안정적인 저장과 효율적인 검색을 보장하는 동시에, 시스템의 전반적인 신뢰성과 성능을 높이는 데 기여한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="write--로그-스트림이-chunk에-저장되는-과정"&gt;
 Write : 로그 스트림이 chunk에 저장되는 과정
 &lt;a class="heading-anchor" href="#write--%eb%a1%9c%ea%b7%b8-%ec%8a%a4%ed%8a%b8%eb%a6%bc%ec%9d%b4-chunk%ec%97%90-%ec%a0%80%ec%9e%a5%eb%90%98%eb%8a%94-%ea%b3%bc%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;distributor는 스트림(로그)에 대한 데이터를 저장하기 위한 HTTP/1 요청을 받는다.&lt;/li&gt;
&lt;li&gt;각 스트림은 해시 링을 사용하여 해시된다.&lt;/li&gt;
&lt;li&gt;distributor는 해시된 데이터를 각 스트림을 적절한 ingesters에 해당 복제본으로 보낸다.&lt;/li&gt;
&lt;li&gt;각 ingesters는 스트림 데이터에 대해 chunk를 생성하거나 기존 chunk에 추가한다.&lt;/li&gt;
&lt;li&gt;distributor는 HTTP/1 연결을 통해 성공 코드로 응답한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="read-path-query-frontend-querier"&gt;
 Read Path: Query frontend, Querier
 &lt;a class="heading-anchor" href="#read-path-query-frontend-querier" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Query Frontend와 Querier의 조합은 Grafana Loki에서 데이터 검색과 분석을 위한 효율적이고 강력한 읽기 경로를 제공한다.&lt;/li&gt;
&lt;li&gt;이러한 구조는 대규모 데이터 세트에 대한 쿼리 처리 시간을 줄이고, 시스템의 전반적인 성능과 확장성을 향상시키는 데 중요한 역할을 한다.&lt;/li&gt;
&lt;li&gt;특히, 캐싱과 쿼리 분할 같은 기능은 쿼리 응답 시간을 단축시키고 사용자 경험을 개선하는 데 크게 기여한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="query-frontendoptional-service"&gt;
 Query-Frontend(optional service)
 &lt;a class="heading-anchor" href="#query-frontendoptional-service" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;실제 쿼리 실행에 필요한 Querier의 역할을 보조하며 읽기 경로를 가속화한다.&lt;/li&gt;
&lt;li&gt;Query frontend는 내부적으로 쿼리를 조정하고 큐에 보관한다.&lt;/li&gt;
&lt;li&gt;Query Frontend는 실제 쿼리를 실행하는 Querier를 보조하여 읽기 경로의 성능을 향상시키는 서비스이다.&lt;/li&gt;
&lt;li&gt;이 서비스는 쿼리 실행을 더 효율적으로 만들기 위해 다음과 같은 주요 기능을 수행한다.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;큐잉(Queueing)&lt;/strong&gt; : 큰 쿼리로 인한 메모리 부족 문제를 방지하고, 공정한 스케줄링을 가능하게 한다. 이는 더 작은 쿼리의 병렬 실행을 통해 전체 소유 비용(TCO)을 줄이는 데 기여한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;분할(Splitting)&lt;/strong&gt; : 큰 쿼리를 여러 작은 쿼리로 분할하여 Querier의 메모리 부족 문제를 예방하고, 쿼리 결과를 더 빠르게 도출할 수 있도록 한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;캐싱(Caching)&lt;/strong&gt; : 쿼리 결과를 캐시하여 후속 쿼리에서 재사용합니다. 이는 쿼리 수행 시간을 단축시키고 전반적인 시스템 성능을 향상시키는 데 도움이 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Query Frontend는 상태를 유지하지 않는 서비스로, 일반적으로 두 개의 복제본으로 운영되며, 이는 가용성을 높이면서도 리소스 사용을 최적화한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="querier"&gt;
 Querier
 &lt;a class="heading-anchor" href="#querier" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Ingester의 in-memory 데이터를 쿼리 후 장기 저장소에서 Query Log를 가져와 Query-Frontend에게 데이터를 반환한다.&lt;/li&gt;
&lt;li&gt;Ingester에서 복제 데이터를 가져올 수 있기 때문에 내부적으로 중복을 제거한다.&lt;/li&gt;
&lt;li&gt;Querier는 LogQL 쿼리 언어를 사용하여 로그 데이터에 대한 쿼리를 처리한다.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;인메모리 데이터 및 장기 저장소 쿼리&lt;/strong&gt; : 모든 Ingester에서 현재 메모리에 있는 데이터를 쿼리한 다음, 같은 쿼리를 장기 저장소에 대해서도 실행한다. 이는 실시간 데이터와 과거 데이터 모두에 대한 쿼리를 가능하게 한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;중복 제거&lt;/strong&gt; : 복제로 인해 중복된 데이터를 수신할 수 있는데, Querier는 동일한 나노초(㎱) 타임스탬프, 레이블 세트 및 로그 메시지를 가진 데이터를 중복 제거하여 최종 쿼리 결과의 정확성을 보장한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Read Path에서 로그 스트림이 읽어지는 과정
&lt;ol&gt;
&lt;li&gt;querier는 데이터에 대한 HTTP/1 요청을 받는다.&lt;/li&gt;
&lt;li&gt;querier는 인메모리 데이터에 대한 쿼리를 모든 ingesters에 전달한다.&lt;/li&gt;
&lt;li&gt;ingesters는 읽기 요청을 수신하고 쿼리와 일치하는 데이터가 있는 경우 반환한다.&lt;/li&gt;
&lt;li&gt;querier는 데이터를 반환한 ingesters가 없는 경우 백업 저장소에서 데이터를 느리게 로드하고 이에 대해 쿼리를 실행한다.&lt;/li&gt;
&lt;li&gt;querier는 수신된 모든 데이터를 반복하고 중복을 제거하여 HTTP/1 연결을 통해 최종 데이터 세트를 반환한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="read"&gt;
 Read
 &lt;a class="heading-anchor" href="#read" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Read 요청 시 querier에서 해당 요청을 수신한다.&lt;/li&gt;
&lt;li&gt;querier는 ingester의 in-memory를 조회한다.&lt;/li&gt;
&lt;li&gt;ingester에 캐시 된 데이터가 있는 경우 querier에게 반환하고, 데이터가 없는 경우 백업 저장소(S3)에서 데이터를 조회한다.&lt;/li&gt;
&lt;li&gt;querier는 수신된 데이터가 중복 됐는지 확인 후 중복제거 진행하여 log를 제공한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="consistent-hash-rings"&gt;
 Consistent Hash Rings
 &lt;a class="heading-anchor" href="#consistent-hash-rings" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;로그 라인의 샤딩, 고가용성 구현, 그리고 클러스터의 수평적 확장성(scaling)을 용이하게 하는 데 사용된다.&lt;/li&gt;
&lt;li&gt;해시 링은 Loki의 다양한 컴포넌트 간의 효율적인 데이터 분배와 관리를 가능하게 한다.&lt;/li&gt;
&lt;li&gt;각각의 노드는 Loki 시스템 내의 특정 컴포넌트 인스턴스를 대표하며, 키-값 저장소에는 해당 인스턴스의 통신 정보가 저장된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="일관된-해시-링의-주요-특징-및-용도"&gt;
 일관된 해시 링의 주요 특징 및 용도
 &lt;a class="heading-anchor" href="#%ec%9d%bc%ea%b4%80%eb%90%9c-%ed%95%b4%ec%8b%9c-%eb%a7%81%ec%9d%98-%ec%a3%bc%ec%9a%94-%ed%8a%b9%ec%a7%95-%eb%b0%8f-%ec%9a%a9%eb%8f%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Distributor Ring&lt;/strong&gt; : Distributor의 수를 계산하는 데 사용된다. 이는 로그 데이터가 어떻게 분산되어야 할지 결정하는 데 중요한 역할을 한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ingester Ring&lt;/strong&gt; : 로그 라인을 어느 Ingester에 전달할지 결정하는 데 사용된다. 이는 데이터의 안정적인 저장과 검색을 위한 효율적인 데이터 분배 메커니즘을 제공한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Query Scheduler Ring&lt;/strong&gt; : 서비스 탐색에 사용된다. 쿼리 요청을 효율적으로 처리할 Querier를 결정하는 데 도움을 준다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compactor Ring&lt;/strong&gt; : 로그 데이터의 압축을 담당할 인스턴스를 식별하는 데 사용된다. 이는 저장 공간의 효율적 사용과 데이터 처리 성능 향상에 기여한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ruler Ring&lt;/strong&gt; : 어떤 규칙 그룹을 평가할지 결정하는 데 사용된다. 이는 경고 및 메트릭 규칙을 효율적으로 관리하고 실행하는 데 중요하다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Index Gateway Ring(선택적)&lt;/strong&gt; : 어떤 게이트웨이가 특정 테넌트의 인덱스를 담당할지 결정하는 데 사용된다. 이는 인덱스 데이터의 관리와 접근성을 향상시킨다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="중요성-및-이점"&gt;
 중요성 및 이점
 &lt;a class="heading-anchor" href="#%ec%a4%91%ec%9a%94%ec%84%b1-%eb%b0%8f-%ec%9d%b4%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;일관된 해시 링은 Grafana Loki의 분산 시스템에서 데이터를 균등하게 분배하고, 컴포넌트 간의 효율적인 통신을 가능하게 하는 핵심 메커니즘이다.&lt;/li&gt;
&lt;li&gt;이는 시스템의 확장성, 고가용성, 그리고 관리 용이성을 보장한다.&lt;/li&gt;
&lt;li&gt;또한, 클러스터의 동적인 스케일 업과 스케일 다운을 지원하여, 변화하는 워크로드에 빠르게 대응할 수 있게 한다.&lt;/li&gt;
&lt;li&gt;일관된 해시 링을 통한 데이터의 효율적인 분배는 리소스 사용 최적화와 시스템의 전반적인 성능 향상을 이끌어내며, Grafana Loki를 대규모 로그 데이터를 처리하는 강력한 도구로 만든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="multi-tenancy"&gt;
 Multi-tenancy
 &lt;a class="heading-anchor" href="#multi-tenancy" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Grafana Loki는 멀티테넌트 모드를 지원하여, 여러 사용자 또는 팀이 동일한 Loki 인스턴스를 공유할 수 있도록 한다.&lt;/li&gt;
&lt;li&gt;이 모드에서는 메모리와 장기 저장소에 있는 모든 데이터가 HTTP 요청의 X-Scope-OrgID 헤더에서 가져온 테넌트 ID에 따라 파티셔닝된다.&lt;/li&gt;
&lt;li&gt;멀티테넌트 모드가 아닐 경우, 테넌트 ID는 &amp;ldquo;fake&amp;quot;로 설정되며, 이는 모든 사용자의 데이터가 동일한 인덱스와 저장된 chunk에 표시됨을 의미한다.&lt;/li&gt;
&lt;li&gt;이 기능은 데이터의 격리와 보안을 강화하며, 리소스 사용의 효율성을 높인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="storage"&gt;
 Storage
 &lt;a class="heading-anchor" href="#storage" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;TSDB
&lt;ul&gt;
&lt;li&gt;Loki 버전 2.8부터는 TSDB(Time Series Database)를 사용하여 인덱스 저장소로서 NoSQL 저장소에 의존하지 않고도 Loki를 실행할 수 있게 되었다.&lt;/li&gt;
&lt;li&gt;이전 버전까지는 **Single Store(boltdb-shipper)**가 이 역할을 담당했다.&lt;/li&gt;
&lt;li&gt;TSDB를 사용하면 모든 데이터(chunk와 인덱스)를 단일 오브젝트 스토리지 백엔드에 저장할 수 있으며, 이는 운영의 단순화, 비용 절감, 그리고 성능 향상을 가능하게 한다.&lt;/li&gt;
&lt;li&gt;TSDB 어댑터를 통한 인덱스 저장은 chunk 저장 방식과 유사하게 진행되어, Loki의 데이터 관리 방식을 더욱 통합하고 효율적으로 만든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이러한 요소들은 Grafana Loki를 효과적으로 운영하기 위한 핵심적인 부분이며, 대규모 로그 데이터 관리 시스템의 설계와 구현에 중요한 기여를 한다.&lt;/li&gt;
&lt;li&gt;Loki의 멀티테넌시 지원과 TSDB를 활용한 스토리지 관리는 사용자가 대규모 로그 데이터를 보다 유연하고 효율적으로 처리할 수 있게 돕는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="deployment-modes"&gt;
 Deployment modes
 &lt;a class="heading-anchor" href="#deployment-modes" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Monolithic mode
&lt;ul&gt;
&lt;li&gt;하루에 최대 약 100GB의 읽기/쓰기 볼륨에 유용하다.&lt;/li&gt;
&lt;li&gt;Shared object store를 사용하여 라운드 로빈 방식 라우팅의 수평적 확장 구성 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Simple scalable deployment mode
&lt;ul&gt;
&lt;li&gt;하루에 수백 GB를 초과하거나 읽기 및 쓰기 문제를 분리하려는 경우에 유용하다.&lt;/li&gt;
&lt;li&gt;이 배포 모드는 하루에 몇 TB 이상의 로그로 확장할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Microservices mode
&lt;ul&gt;
&lt;li&gt;components를 개별 마이크로서비스로 실행하면 마이크로서비스의 양을 늘려 확장할 수 있다.&lt;/li&gt;
&lt;li&gt;마이크로서비스 모드는 규모가 매우 큰 Loki 클러스터 또는 확장 및 클러스터 작업을 더 많이 제어해야 하는 클러스터에 권장된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="compactor"&gt;
 Compactor
 &lt;a class="heading-anchor" href="#compactor" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;chunk 보관주기를 관리하고(retention), 테이블을 단일 인덱스 파일로 압축한다.&lt;/li&gt;
&lt;li&gt;Compactor를 통한 보존은 boltdb-shipper 또는 tsdb store에서만 지원된다.
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Loki 2.8부터는 TSDB Store 사용이 권장이다. 이전에 사용하던 boltdb-shipper보다 효율적이고 빠르며 확장성이 뛰어나다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Loki Storage 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/loki/latest/storage/"&gt;https://grafana.com/docs/loki/latest/storage/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ruler"&gt;
 Ruler
 &lt;a class="heading-anchor" href="#ruler" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;사용자가 정의한 경고 규칙 기반으로 경고를 발생시키는 등 로그 데이터에 대한 경고를 관리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="walwrite-ahead-log"&gt;
 WAL(Write Ahead Log)
 &lt;a class="heading-anchor" href="#walwrite-ahead-log" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Loki에서는 WAL(Write Ahead Log)이라는 걸 사용하는데, 아래와 같은 예기치 않은 장애 상황을 방지해 준다.
&lt;ol&gt;
&lt;li&gt;데이터(chunk)가 Ingesters로 들어오면, 먼저 이 데이터를 메모리 적재 및 WAL에 기록한다. WAL은 로컬 파일 시스템에 저장된다.&lt;/li&gt;
&lt;li&gt;예기치 않은 장애로 프로세스가 갑자기 중단되거나 다운되면, 메모리에 있는 데이터가 손실된다.&lt;/li&gt;
&lt;li&gt;장애가 복구되어 프로세스가 다시 시작되면 WAL에 저장된 데이터를 읽어와 메모리에 적재하여 장애 전의 상태로 복구된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="chunk-store"&gt;
 Chunk Store
 &lt;a class="heading-anchor" href="#chunk-store" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Loki의 로그를 장기 저장하기 위한 저장소이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="index-gateway"&gt;
 Index Gateway
 &lt;a class="heading-anchor" href="#index-gateway" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Querier, Ruler에게 Index 쿼리를 제공하기 위해 Object Storage 및 BoltDB 인덱스를 다운로드하고 동기화한다.
&lt;ul&gt;
&lt;li&gt;이렇게 하면 Grafana로부터 로그 검색 요청이 들어왔을 때 Querier나 Ruler가 불필요하게 일하지 않아도 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="compactor와-table-manager"&gt;
 Compactor와 Table Manager
 &lt;a class="heading-anchor" href="#compactor%ec%99%80-table-manager" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Grafana Loki의 로그 보존(Retention)은 Compactor 혹은 Table Manager에 의해 수행된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;현재 Table Manager를 통한 Retention은 TTL을 통해 달성되며 boltdb-shipper, chunk/index store 모두 작동한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Compactor를 통한 Retention은 boltdb-shipper 저장소에서만 지원된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;만약 Compactor로 Retention을 적용한다면 Table Manager는 필요로 하지 않게 될 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;현재 Grafana Loki에서는 Compactor를 중점적으로 개발중인 것 같다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;다음은 Compactor 설정 예시이다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-config" data-lang="config"&gt;compactor:
 shared_store: s3
 retention_delete_delay: 2h
 retention_enabled: true&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Compactor의 Retention은 &lt;code&gt;limits_config&lt;/code&gt;에 설정해주면 된다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Retention 설정 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/loki/latest/operations/storage/retention/#configuring-the-retention-period"&gt;https://grafana.com/docs/loki/latest/operations/storage/retention/#configuring-the-retention-period&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="api"&gt;
 API
 &lt;a class="heading-anchor" href="#api" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;특정 데이터를 지우기 (Query 작성)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;시간은 RFC3339, RFC3339Nano format만 지원한다.&lt;/li&gt;
&lt;li&gt;post: &lt;code&gt;/loki/api/v1/delete?query={namespace=&amp;quot;testns&amp;quot;, app=&amp;quot;testapp&amp;quot;}&amp;amp;start=1721166554&amp;amp;end=17263647383&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Compactor 설정한 시간 후에 삭제된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;삭제 요청한 id를 삭제&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;del: &lt;code&gt;/loki/api/v1/delete?request_id=7148cf15&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;삭제 요청한 id 모두 삭제&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;del: &lt;code&gt;/loki/api/v1/delete&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;삭제 요청한 id 조회&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;get: &lt;code&gt;/loki/api/v1/delete&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;API 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/loki/latest/reference/loki-http-api/"&gt;https://grafana.com/docs/loki/latest/reference/loki-http-api/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Install Promtail(v2.9.4) Using Helm Chart</title><link>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-install-promtailv2.9.4-using-helm/</link><pubDate>Tue, 02 Apr 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-install-promtailv2.9.4-using-helm/</guid><description>&lt;h2 id="promtail"&gt;
 Promtail
 &lt;a class="heading-anchor" href="#promtail" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Loki가 로그를 저장하는 역할을 하면 Promtail은 application에서 로그를 전달하는 agent의 역할을 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Promtail 이외에도 Bit, Fluentd, LogStash 등을 사용할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;kubernetes는 node 별로 &lt;code&gt;/var/log/pods&lt;/code&gt; 아래에 모든 Pod의 로그가 기록된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;daemonset으로 설정하고 node별로 로그를 수집하도록 처리를 하면 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;설치 방식은 sidecar, daemonset 방식이 있는데 daemonset 방식을 추천한다고 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;daemonset&lt;/strong&gt; : 각 Node마다 promtail Pod가 실행되어 해당 Node 장비에서 실행 중인 Pod의 로그를 추적&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sidecar&lt;/strong&gt; : 각 Pod에 container로 추가되어 실행, 해당 Pod 내부에서 로그 파일을 읽어서 Loki로 전송&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pod마다 agent 형태로 설정하는 것보다 daemonset을 하나 띄워 해당 node의 Pod들을 찾아 로그를 수집하는 것이 훨씬 편한 것 같다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Prometheus가 저장소와 polling 역할을 같이 담당하는 반면 Promtail은 저장소의 역할은 하지 않고 로그를 찾아 저장소로 push 하는 역할을 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;하지만 설정 방식이나 문법은 크게 차이가 없다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="install-the-promtail-helm-charts"&gt;
 Install the Promtail Helm charts
 &lt;a class="heading-anchor" href="#install-the-promtail-helm-charts" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo add grafana https://grafana.github.io/helm-charts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;helm install promtail grafana/promtail --namespace &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Promtail 설치 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/loki/latest/clients/promtail/installation/"&gt;https://grafana.com/docs/loki/latest/clients/promtail/installation/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="customize-default-configuration"&gt;
 Customize Default Configuration
 &lt;a class="heading-anchor" href="#customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;values.yaml 수정&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;최상위 values.yaml을 수정하면 하위 폴더 values.yaml을 override 한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Chart
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana/helm-charts/tree/main/charts/promtail"&gt;https://github.com/grafana/helm-charts/tree/main/charts/promtail&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Release file (.tgz)
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana/helm-charts/releases"&gt;https://github.com/grafana/helm-charts/releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="setting-volumes"&gt;
 Setting Volumes
 &lt;a class="heading-anchor" href="#setting-volumes" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# -- Default volumes that are mounted into pods. In most cases, these should not be changed.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Use `extraVolumes`/`extraVolumeMounts` for additional custom volumes.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# @default -- See `values.yaml`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;defaultVolumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;run&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/run/promtail&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;containers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/lib/docker/containers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/log/pods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;syslogs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/log&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# -- Default volume mounts. Corresponds to `volumes`.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# @default -- See `values.yaml`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;defaultVolumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;run&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/run/promtail&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;containers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/lib/docker/containers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/log/pods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;syslogs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/log&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;readOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="setting-config"&gt;
 Setting Config
 &lt;a class="heading-anchor" href="#setting-config" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Enable Promtail config from Helm chart&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Set `configmap.enabled: true` and this to `false` to manage your own Promtail config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# See default config in `values.yaml`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- The log level of the Promtail server&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Must be reference in `config.file` to configure `server.log_level`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# See default config in `values.yaml`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;info&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- The log format of the Promtail server&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Must be reference in `config.file` to configure `server.log_format`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Valid formats: `logfmt, json`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# See default config in `values.yaml`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logFormat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;logfmt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- The port of the Promtail server&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Must be reference in `config.file` to configure `server.http_listen_port`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# See default config in `values.yaml`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serverPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3101&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- The config of clients of the Promtail server&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Must be reference in `config.file` to configure `clients`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# @default -- See `values.yaml`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;clients&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://loki-gateway/loki/api/v1/push&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;basic_auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${LOKI_BASIC_AUTH_PW}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${LOKI_BASIC_AUTH_USER}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;external_labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${CLUSTER}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${LOKI_URL}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Configures where Promtail will save it&amp;#39;s positions file, to resume reading after restarts.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Must be referenced in `config.file` to configure `positions`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;snippets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pipelineStages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;cri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;common&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;replace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;source_labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;__meta_kubernetes_pod_node_name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;target_label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;node_name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;replace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;source_labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;__meta_kubernetes_namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;target_label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;replace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replacement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;$1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;separator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;source_labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;target_label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;job&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;replace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;source_labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;__meta_kubernetes_pod_name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;target_label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;replace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;source_labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;__meta_kubernetes_pod_container_name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;target_label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;container&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;replace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replacement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/log/pods/*$1/*.log&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;separator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;source_labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;__meta_kubernetes_pod_uid&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;__meta_kubernetes_pod_container_name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;target_label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;__path__&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;replace&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replacement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/log/pods/*$1/*.log&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="l"&gt;/(.*)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;separator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;source_labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;__meta_kubernetes_pod_annotationpresent_kubernetes_io_config_hash&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;__meta_kubernetes_pod_annotation_kubernetes_io_config_hash&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;__meta_kubernetes_pod_container_name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;target_label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;__path__&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;scrapeConfigs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - job_name: syslog
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; static_configs:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - targets:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - localhost
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; job: syslog
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; __path__: /var/log/syslog
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; pipeline_stages:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - regex:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; expression: &amp;#39;^(?P&amp;lt;time&amp;gt;[^ ]* {1,2}[^ ]* [^ ]*) (?P&amp;lt;hostname&amp;gt;[^ ]*) (?P&amp;lt;daemon&amp;gt;[^ :\[]*)(?:\[(?P&amp;lt;pid&amp;gt;[0-9]+)\])?(?:[^\:]*\:)? *(?P&amp;lt;message&amp;gt;.*)$&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; time:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; hostname:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; daemon:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; pid:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; message:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - match:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; selector: &amp;#39;{daemon=~&amp;#34;kubelet|kernel&amp;#34;}&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; stages:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - regex:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; expression: &amp;#39;^(?P&amp;lt;time&amp;gt;[^ ]* {1,2}[^ ]* [^ ]*) (?P&amp;lt;hostname&amp;gt;[^ ]*) (?P&amp;lt;daemon&amp;gt;[^ :\[]*)(?:\[(?P&amp;lt;pid&amp;gt;[0-9]+)\])?(?:[^\:]*\:)? *(?P&amp;lt;message&amp;gt;.*)$&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; time:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; hostname:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; daemon:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; pid:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;108&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; message:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;109&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - timestamp:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;110&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; source: time
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;111&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; format: %b %d %H:%M:%S
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;112&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - job_name: custom-log
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;113&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; static_configs:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;114&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - targets:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;115&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - localhost
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;116&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;117&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; job: custom-log
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;118&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; __path__: /appdata/applog
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;119&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; pipeline_stages:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;120&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - regex:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;121&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; expression: &amp;#39;^(?P&amp;lt;log_type&amp;gt;[^ ]*) &amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;122&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;123&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; log_type:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;124&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - match:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;125&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; selector: &amp;#39;{log_type=&amp;#34;type1&amp;#34;}&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;126&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; stages:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;127&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - regex:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;128&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; expression: &amp;#39;^(?P&amp;lt;log_type&amp;gt;[^ ]*) (?P&amp;lt;log_level&amp;gt;[^ ]*) ~&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;129&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - template:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;130&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; source: log_level
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;131&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; template: &amp;#39;warning&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;132&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;133&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; log_type:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;134&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - match:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;135&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; selector: &amp;#39;{log_type=&amp;#34;type2&amp;#34;}&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;136&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; stages:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;137&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - regex:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;138&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; expression: &amp;#39;^(?P&amp;lt;log_type&amp;gt;[^ ]*) (?P&amp;lt;log_level&amp;gt;[^ ]*) (?P&amp;lt;message&amp;gt;.*) ~&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;139&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - template:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;140&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; source: log_type
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;141&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; template: &amp;#39;API&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;142&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;143&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; log_type:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;144&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; log_level:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;145&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; message:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;146&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - match:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;147&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; selector: &amp;#39;{log_level=&amp;#34;I&amp;#34;}&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;148&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; stages:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;149&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - regex:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;150&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; expression: &amp;#39;^(?P&amp;lt;log_type&amp;gt;[^ ]*) (?P&amp;lt;log_level&amp;gt;[^ ]*) (?P&amp;lt;message&amp;gt;.*) ~&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;151&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - template:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;152&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; source: log_level
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;153&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; template: &amp;#39;INFO&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;154&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;155&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; log_type:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;156&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; log_level:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;157&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; message:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;158&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - match:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;159&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; selector: &amp;#39;{log_level=~&amp;#34;W|E&amp;#34;}&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;160&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; stages:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;161&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - regex:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;162&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; expression: &amp;#39;^(?P&amp;lt;log_type&amp;gt;[^ ]*) (?P&amp;lt;log_level&amp;gt;[^ ]*) (?P&amp;lt;message&amp;gt;.*) ~&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;163&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - template:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;164&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; source: log_level
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;165&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; template: &amp;#39;{{ if eq .Value &amp;#34;W&amp;#34; }}{{ Replace .Value &amp;#34;W&amp;#34; &amp;#34;WARNING&amp;#34; -1 }}{{ else if eq .Value &amp;#34;E&amp;#34; }}{{ Replace .Value &amp;#34;E&amp;#34; &amp;#34;ERROR&amp;#34; -1 }}{{ else }}{{ .Value }}{{ end }}&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;166&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;167&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; log_type:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;168&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; log_level:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;169&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; message:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;170&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;171&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # See also https://github.com/grafana/loki/blob/master/production/ksonnet/promtail/scrape_config.libsonnet for reference
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;172&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - job_name: kubernetes-pods
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;173&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; pipeline_stages:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;174&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{- toYaml .Values.config.snippets.pipelineStages | nindent 4 }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;175&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; kubernetes_sd_configs:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;176&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - role: pod
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;177&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; namespaces:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;178&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; names:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;179&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - kube-system
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;180&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - ...✂...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;181&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - ...✂...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;182&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; relabel_configs:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;183&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - source_labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;184&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - __meta_kubernetes_pod_controller_name
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;185&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; regex: ([0-9a-z-.]+?)(-[0-9a-f]{8,10})?
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;186&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; action: replace
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;187&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; target_label: __tmp_controller_name
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;188&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - source_labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;189&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - __meta_kubernetes_pod_label_app_kubernetes_io_name
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;190&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - __meta_kubernetes_pod_label_app
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;191&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - __tmp_controller_name
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;192&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - __meta_kubernetes_pod_name
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;193&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; regex: ^;*([^;]+)(;.*)?$
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;194&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; action: replace
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;195&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; target_label: app
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;196&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - source_labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;197&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - __meta_kubernetes_pod_label_app_kubernetes_io_instance
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;198&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - __meta_kubernetes_pod_label_instance
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;199&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; regex: ^;*([^;]+)(;.*)?$
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;200&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; action: replace
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;201&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; target_label: instance
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;202&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - source_labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;203&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - __meta_kubernetes_pod_label_app_kubernetes_io_component
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;204&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - __meta_kubernetes_pod_label_component
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;205&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; regex: ^;*([^;]+)(;.*)?$
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;206&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; action: replace
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;207&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; target_label: component
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;208&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{- if .Values.config.snippets.addScrapeJobLabel }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;209&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; - replacement: kubernetes-pods
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;210&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; target_label: scrape_job
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;211&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{- end }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;212&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{- toYaml .Values.config.snippets.common | nindent 4 }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;213&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{- with .Values.config.snippets.extraRelabelConfigs }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;214&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{- toYaml . | nindent 4 }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;215&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{- end }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;216&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;217&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# -- Config file contents for Promtail.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;218&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Must be configured as string.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;219&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# It is templated so it can be assembled from reusable snippets in order to avoid redundancy.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;220&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# @default -- See `values.yaml`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;221&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;222&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; server:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;223&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; log_level: {{ .Values.config.logLevel }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;224&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; log_format: {{ .Values.config.logFormat }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;225&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; http_listen_port: {{ .Values.config.serverPort }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;226&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{- with .Values.httpPathPrefix }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;227&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; http_path_prefix: {{ . }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;228&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{- end }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;229&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{- tpl .Values.config.snippets.extraServerConfigs . | nindent 2 }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;230&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;231&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; clients:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;232&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{- tpl (toYaml .Values.config.clients) . | nindent 2 }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;233&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;234&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; positions:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;235&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{- tpl (toYaml .Values.config.positions) . | nindent 2 }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;236&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;237&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; scrape_configs:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;238&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{- tpl .Values.config.snippets.scrapeConfigs . | nindent 2 }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;239&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{- tpl .Values.config.snippets.extraScrapeConfigs . | nindent 2 }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;240&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;241&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; limits_config:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;242&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{- tpl .Values.config.snippets.extraLimitsConfig . | nindent 2 }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;243&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;244&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; tracing:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;245&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; enabled: {{ .Values.config.enableTracing }}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="syslog-regex"&gt;
 syslog regex
 &lt;a class="heading-anchor" href="#syslog-regex" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;^(?P&amp;lt;time&amp;gt;[^ ]* {1,2}[^ ]* [^ ]*) (?P&amp;lt;hostname&amp;gt;[^ ]*) (?P&amp;lt;daemon&amp;gt;[^ :\[]*)(?:\[(?P&amp;lt;pid&amp;gt;[0-9]+)\])?(?:[^\:]*\:)? *(?P&amp;lt;message&amp;gt;.*)$&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="install-customize-default-configuration"&gt;
 Install Customize Default Configuration
 &lt;a class="heading-anchor" href="#install-customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;Chart.yaml 경로&lt;span class="o"&gt;]&lt;/span&gt; -f &lt;span class="o"&gt;[&lt;/span&gt;YAML 파일 또는 URL에 값 지정 &lt;span class="o"&gt;(&lt;/span&gt;여러 개를 지정가능&lt;span class="o"&gt;)]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install promtail grafana/promtail -f override-values.yaml -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="uninstall-the-chart"&gt;
 Uninstall the Chart
 &lt;a class="heading-anchor" href="#uninstall-the-chart" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm uninstall &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Error] BusyBox initramfs 발생할 때</title><link>https://kyungryeol-yoon.github.io/linux/system/linux-ubuntu-busebox-initramfs/</link><pubDate>Tue, 05 Mar 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/system/linux-ubuntu-busebox-initramfs/</guid><description>&lt;ul&gt;
&lt;li&gt;VirtualBox의 Ubuntu 제대로 종료되지 않아 올바른 파티션을 찾지 못해 BusyBox 진입했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="파일-시스템-복원fsck"&gt;
 파일 시스템 복원(fsck)
 &lt;a class="heading-anchor" href="#%ed%8c%8c%ec%9d%bc-%ec%8b%9c%ec%8a%a4%ed%85%9c-%eb%b3%b5%ec%9b%90fsck" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;시스템이 갑작스럽게 종료되거나 비정상적으로 종료되었을 때, 파일 시스템이 손상될 수 있다.&lt;/li&gt;
&lt;li&gt;fsck는 파일 시스템을 검사하여 손상된 부분을 찾아내어 손상된 파일이나 Directory를 복구하고 잘못된 포맷팅, 중복 블록, 불필요 파일 정리 등을 통해 정상 상태로 복원한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;fsck &lt;span class="o"&gt;[&lt;/span&gt;옵션&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;파일 시스템 경로&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;clear 질문이 계속 나오는데 모두 y를 입력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;exit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;exit로 나온다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="error-example"&gt;
 Error Example
 &lt;a class="heading-anchor" href="#error-example" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;BusyBox v1.xx.x&lt;span class="o"&gt;(&lt;/span&gt;Ubuntu 1:1:xx.x-x ubuntu1&lt;span class="o"&gt;)&lt;/span&gt; built in shell &lt;span class="o"&gt;(&lt;/span&gt;ash&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;Enter &lt;span class="s1"&gt;&amp;#39;help&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; a list of built-in commands.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;initramfs&lt;span class="o"&gt;)&lt;/span&gt;_&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="방법-1"&gt;
 방법 1.
 &lt;a class="heading-anchor" href="#%eb%b0%a9%eb%b2%95-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;fsck -y /dev/sda1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;reboot or exit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="방법-2"&gt;
 방법 2.
 &lt;a class="heading-anchor" href="#%eb%b0%a9%eb%b2%95-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;위의 &lt;code&gt;fsck -y /dev/sda1&lt;/code&gt; 명령어 없이 바로 exit를 해도 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="방법-3"&gt;
 방법 3.
 &lt;a class="heading-anchor" href="#%eb%b0%a9%eb%b2%95-3" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;명령어 쳤지만 부팅이 안될 때 &lt;code&gt;fsck -y /dev/sda1&lt;/code&gt; 명령어를 치고 나면 재부팅이 되어야 하는데 다시 initramfs가 나올 수 있다.&lt;/li&gt;
&lt;li&gt;이 때는 바로 &lt;code&gt;fsck [대상경로]&lt;/code&gt;의 명령어로 실행시키면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;/dev/sda3: UNEXPRECTED INCONSISTENCY&lt;span class="p"&gt;;&lt;/span&gt; RUN fskc MANUALLY.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;fsck exited with status code &lt;span class="m"&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;The root filesystem on /dev/sda9 requires a manual fsck
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;Busybox v1.xx.x &lt;span class="o"&gt;(&lt;/span&gt;Ubuntu 1:1.xx.x-x ubuntu1&lt;span class="o"&gt;)&lt;/span&gt; built in shell&lt;span class="o"&gt;(&lt;/span&gt;ash&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;Enter &lt;span class="s1"&gt;&amp;#39;help&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; a list of built-in commands.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;initramfs&lt;span class="o"&gt;)&lt;/span&gt;_&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;이렇게 나오면 바로 대상경로를 실행시키면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;fsck /dev/sda3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;대상경로는 사용자마다 다를 수 있으니 본인의 실행시켜야하는 대상경로를 확인해야 한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;대상경로확인은 exit 치면 나온다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] Upgrade Kubernetes(v1.29.x) using Kubekey(v3.0.13) Artifact</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/upgrade-kubernetesv1.29.x-using-kubekeyv3.0.13-artifact/</link><pubDate>Tue, 05 Mar 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/upgrade-kubernetesv1.29.x-using-kubekeyv3.0.13-artifact/</guid><description>&lt;blockquote&gt;
&lt;p&gt;offline 설치 위한 artifact 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;version 참고
&lt;ul&gt;
&lt;li&gt;kubernetes와 관련된 image는 &lt;a href="https://github.com/kubesphere/ks-installer/releases"&gt;https://github.com/kubesphere/ks-installer/releases&lt;/a&gt;에서 주요 release에만 포함되는 image-list.txt파일을 참고&lt;/li&gt;
&lt;li&gt;kubekey의 버전별로 kubernetes, kubesphere의 최신 지원 버전이 있음
&lt;ul&gt;
&lt;li&gt;kubekey/version/components.json&lt;/li&gt;
&lt;li&gt;kubekey/cmd/kk/pkg/version/kubesphere/version_enum.go&lt;/li&gt;
&lt;li&gt;kubekey/cmd/kk/pkg/version/kubernetes/version_enum.go&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;default 버전에 대한 설정은 kubekey/cmd/kk/apis/kubekey/v1alpha2/default.go 파일에 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/kubekey/blob/v3.0.13/docs/manifest_and_artifact.md"&gt;https://github.com/kubesphere/kubekey/blob/v3.0.13/docs/manifest_and_artifact.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/ks-installer/releases/download/v3.4.1/images-list.txt"&gt;https://github.com/kubesphere/ks-installer/releases/download/v3.4.1/images-list.txt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubesphere.io/docs/v3.4/installing-on-linux/introduction/air-gapped-installation"&gt;https://kubesphere.io/docs/v3.4/installing-on-linux/introduction/air-gapped-installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/kubekey/blob/v3.0.13/docs/manifest-example.md"&gt;https://github.com/kubesphere/kubekey/blob/v3.0.13/docs/manifest-example.md&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="script-다운로드"&gt;
 script 다운로드
 &lt;a class="heading-anchor" href="#script-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -sfL https://get-kk.kubesphere.io &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v3.0.13 sh -&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="artifact-3013yaml-작성"&gt;
 artifact-3.0.13.yaml 작성
 &lt;a class="heading-anchor" href="#artifact-3013yaml-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubekey.kubesphere.io/v1alpha2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Manifest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;artifact-v3.0.13&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;arches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;amd64&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operatingSystems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;arch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;amd64&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;linux&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ubuntu&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;20.04&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;osImage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Ubuntu 20.04.4 LTS&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;iso&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;localPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://github.com/kubesphere/kubekey/releases/download/v3.0.13/ubuntu-20.04-debs-amd64.iso&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubernetesDistributions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.26.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;helm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.9.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cni&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;etcd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.4.13&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;calicoctl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.26.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## For now, if your cluster container runtime is containerd, KubeKey will add a docker 20.10.8 container runtime in the below list.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## The reason is KubeKey creates a cluster with containerd by installing a docker first and making kubelet connect the socket file of containerd which docker contained.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerRuntimes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;docker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;20.10.8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;containerd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1.6.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;crictl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.24.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;docker-registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;harbor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v2.5.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;docker-compose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v2.2.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;images&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-apiserver:v1.27.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-apiserver:v1.26.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-controller-manager:v1.27.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-controller-manager:v1.26.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-scheduler:v1.27.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-scheduler:v1.26.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-proxy:v1.27.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-proxy:v1.26.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/pause:3.8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/pause:3.7&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/pause:3.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/coredns/coredns:1.9.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/coredns/coredns:1.8.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/cni:v3.26.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/cni:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/kube-controllers:v3.26.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/kube-controllers:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/node:v3.26.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/node:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/pod2daemon-flexvol:v3.26.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/pod2daemon-flexvol:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/typha:v3.26.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/typha:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/flannel:v0.12.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/openebs/provisioner-localpv:3.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/openebs/linux-utils:3.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/haproxy:2.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/nfs-subdir-external-provisioner:v4.0.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/k8s-dns-node-cache:1.15.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# https://github.com/kubesphere/ks-installer/releases/download/v3.4.1/images-list.txt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##kubesphere-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-installer:v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-installer:v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-apiserver:v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-apiserver:v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-console:v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-console:v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-controller-manager:v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-controller-manager:v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kubectl:v1.22.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kubectl:v1.20.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kubefed:v0.8.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/tower:v0.2.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/tower:v0.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/minio/minio:RELEASE.2019-08-07T01-59-21Z&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/minio/mc:RELEASE.2019-08-07T23-14-43Z&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/csiplugin/snapshot-controller:v4.0.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/nginx-ingress-controller:v1.3.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/nginx-ingress-controller:v1.1.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/mirrorgooglecontainers/defaultbackend-amd64:1.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/metrics-server:v0.4.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/redis:5.0.14-alpine&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/haproxy:2.0.25-alpine&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/alpine:3.14&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/osixia/openldap:1.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/netshoot:v1.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##kubeedge-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubeedge/cloudcore:v1.13.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubeedge/cloudcore:v1.9.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/iptables-manager:v1.13.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubeedge/iptables-manager:v1.9.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/edgeservice:v0.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;108&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/edgeservice:v0.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;109&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##gatekeeper-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;110&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/openpolicyagent/gatekeeper:v3.5.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;111&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##openpitrix-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;112&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/openpitrix-jobs:v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;113&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##kubesphere-devops-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;114&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/devops-apiserver:ks-v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;115&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/devops-apiserver:ks-v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;116&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/devops-controller:ks-v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;117&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/devops-controller:ks-v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;118&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/devops-tools:ks-v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;119&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/devops-tools:ks-v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;120&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/ks-jenkins:v3.4.0-2.319.3-1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;121&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/ks-jenkins:v3.3.0-2.319.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;122&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/jenkins/inbound-agent:4.10-2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;123&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-base:v3.2.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;124&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-nodejs:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;125&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-maven:v3.2.1-jdk11&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;126&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-maven:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;127&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-python:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;128&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-go:v3.2.2-1.18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;129&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-go:v3.2.2-1.17&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;130&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-go:v3.2.2-1.16&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;131&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-go:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;132&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-base:v3.2.2-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;133&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-nodejs:v3.2.0-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;134&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-maven:v3.2.1-jdk11-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;135&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-maven:v3.2.0-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;136&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-python:v3.2.0-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;137&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-go:v3.2.0-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;138&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-go:v3.2.2-1.18-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;139&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-go:v3.2.2-1.17-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;140&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/builder-go:v3.2.2-1.16-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;141&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/s2ioperator:v3.2.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;142&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/s2irun:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;143&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/s2i-binary:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;144&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/tomcat85-java11-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;145&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/tomcat85-java11-runtime:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;146&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/tomcat85-java8-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;147&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/tomcat85-java8-runtime:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;148&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/java-11-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;149&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/java-11-runtime:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;150&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/java-8-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;151&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/java-8-runtime:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;152&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/nodejs-8-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;153&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/nodejs-6-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;154&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/nodejs-4-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;155&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/python-36-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;156&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/python-35-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;157&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/python-34-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;158&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/python-27-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;159&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - quay.io/argoproj/argocd:v2.3.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;160&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - quay.io/argoproj/argocd-applicationset:v0.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;161&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - ghcr.io/dexidp/dex:v2.30.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;162&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/library/redis:6.2.6-alpine&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;163&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##kubesphere-monitoring-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;164&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/jimmidyson/configmap-reload:v0.7.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;165&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/jimmidyson/configmap-reload:v0.5.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;166&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/prom/prometheus:v2.39.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;167&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/prom/prometheus:v2.34.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;168&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/prometheus-config-reloader:v0.55.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;169&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/prometheus-operator:v0.55.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;170&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kube-rbac-proxy:v0.11.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;171&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kube-state-metrics:v2.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;172&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kube-state-metrics:v2.5.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;173&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/prom/node-exporter:v1.3.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;174&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/prom/alertmanager:v0.23.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;175&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/thanosio/thanos:v0.31.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;176&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/thanosio/thanos:v0.25.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;177&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/grafana/grafana:8.3.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;178&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kube-rbac-proxy:v0.11.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;179&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kube-rbac-proxy:v0.8.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;180&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/notification-manager-operator:v2.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;181&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/notification-manager-operator:v1.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;182&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/notification-manager:v2.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;183&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/notification-manager:v1.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;184&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/notification-tenant-sidecar:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;185&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##kubesphere-logging-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;186&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/elasticsearch-curator:v5.7.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;187&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/opensearch-curator:v0.0.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;188&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/elasticsearch-oss:6.8.22&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;189&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/opensearchproject/opensearch:2.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;190&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/opensearchproject/opensearch-dashboards:2.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;191&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/fluentbit-operator:v0.14.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;192&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/fluentbit-operator:v0.13.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;193&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/library/docker:19.03&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;194&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/fluent-bit:v1.9.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;195&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/fluent-bit:v1.8.11&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;196&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/log-sidecar-injector:v1.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;197&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/elastic/filebeat:6.7.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;198&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kube-events-operator:v0.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;199&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kube-events-operator:v0.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;200&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kube-events-exporter:v0.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;201&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kube-events-exporter:v0.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;202&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kube-events-ruler:v0.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;203&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kube-events-ruler:v0.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;204&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kube-auditing-operator:v0.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;205&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kube-auditing-webhook:v0.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;206&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##istio-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;207&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/istio/pilot:1.14.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;208&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/istio/pilot:1.11.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;209&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/istio/proxyv2:1.14.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;210&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/istio/proxyv2:1.11.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;211&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/jaegertracing/jaeger-operator:1.29&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;212&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/jaegertracing/jaeger-operator:1.27&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;213&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/jaegertracing/jaeger-agent:1.29&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;214&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/jaegertracing/jaeger-agent:1.27&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;215&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/jaegertracing/jaeger-collector:1.29&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;216&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/jaegertracing/jaeger-collector:1.27&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;217&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/jaegertracing/jaeger-query:1.29&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;218&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/jaegertracing/jaeger-query:1.27&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;219&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/jaegertracing/jaeger-es-index-cleaner:1.29&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;220&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/jaegertracing/jaeger-es-index-cleaner:1.27&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;221&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kiali-operator:v1.50.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;222&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kiali-operator:v1.38.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;223&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kiali:v1.50&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;224&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/kiali:v1.38&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;225&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ##example-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;226&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/library/busybox:1.31.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;227&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/library/nginx:1.14-alpine&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;228&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/joosthofman/wget:1.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;229&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/nginxdemos/hello:plain-text&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;230&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/library/wordpress:4.8-apache&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;231&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/mirrorgooglecontainers/hpa-example:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;232&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/fluent/fluentd:v1.4.2-2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;233&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/library/perl:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;234&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/examples-bookinfo-productpage-v1:1.16.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;235&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/examples-bookinfo-reviews-v1:1.16.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;236&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/examples-bookinfo-reviews-v2:1.16.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;237&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/examples-bookinfo-details-v1:1.16.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;238&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/examples-bookinfo-ratings-v1:1.16.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;239&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ##weave-scope-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;240&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/weaveworks/scope:1.13.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;241&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;242&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;243&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;docker.io&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;244&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;username&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;245&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;password&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="export-artifact"&gt;
 Export Artifact
 &lt;a class="heading-anchor" href="#export-artifact" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk artifact &lt;span class="nb"&gt;export&lt;/span&gt; -m artifact-3.0.13.yaml -o artifact-3.0.13.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cluster-설치를-위한-config-파일-생성-및-작성"&gt;
 Cluster 설치를 위한 config 파일 생성 및 작성
 &lt;a class="heading-anchor" href="#cluster-%ec%84%a4%ec%b9%98%eb%a5%bc-%ec%9c%84%ed%95%9c-config-%ed%8c%8c%ec%9d%bc-%ec%83%9d%ec%84%b1-%eb%b0%8f-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;config 파일 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk create config --with-kubesphere v3.4.1 --with-kubernetes v1.26.5 -f config-sample.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;config 파일 작성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubekey.kubesphere.io/v1alpha2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;sample&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: manage-master, address: 192.168.10.100, internalAddress: 192.168.10.100, user: root, password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;vagrant}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: manage-worker-1, address: 192.168.10.110, internalAddress: 192.168.10.110, user: root, password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;vagrant}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: manage-worker-2, address: 192.168.10.120, internalAddress: 192.168.10.120, user: root, password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;vagrant}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;roleGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;etcd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;manage-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;control-plane&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;manage-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;manage-worker-1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;manage-worker-2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;manage-worker-1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;controlPlaneEndpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## Internal loadbalancer for apiservers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# internalLoadbalancer: haproxy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#domain: lb.kubesphere.local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.10.100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubernetes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.26.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;clusterName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster.local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;autoRenewCerts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerManager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;containerd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;etcd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubekey&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;calico&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubePodsCIDR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10.233.64.0&lt;/span&gt;&lt;span class="l"&gt;/18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubeServiceCIDR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10.233.0.0&lt;/span&gt;&lt;span class="l"&gt;/18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## multus support. https://github.com/k8snetworkplumbingwg/multus-cni&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;multusCNI&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;harbor&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;dockerhub.kubekey.local&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;admin&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Harbor12345&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;privateRegistry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;dockerhub.kubekey.local&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespaceOverride&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;kubesphereio&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registryMirrors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecureRegistries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;addons&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;installer.kubesphere.io/v1alpha1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterConfiguration&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ks-installer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubesphere-system&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persistence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;authentication&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jwtSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;local_registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# dev_tag: &amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;etcd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;monitoring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpointIps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;localhost&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2379&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tlsEnable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;common&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;core&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enableMultiLogin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;30880&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NodePort&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# apiserver:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# controllerManager:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enableHA&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;2Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;openldap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;2Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;minio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;20Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;monitoring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# type: external&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://prometheus-operated.kubesphere-monitoring-system.svc:9090&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;GPUMonitoring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kinds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;resourceName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;nvidia.com/gpu&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resourceType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;GPU&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;es&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# master:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# volumeSize: 4Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# data:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;108&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# volumeSize: 20Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;109&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;110&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;111&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;112&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logMaxAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;113&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;elkPrefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;logstash&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;114&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;basicAuth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;115&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;116&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;117&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;118&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;externalElasticsearchHost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;119&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;externalElasticsearchPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;120&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;opensearch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;121&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# master:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;122&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# volumeSize: 4Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;123&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;124&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;125&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# data:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;126&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# volumeSize: 20Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;127&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;128&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;129&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;130&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logMaxAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;131&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;opensearchPrefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;whizard&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;132&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;basicAuth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;133&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;134&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;135&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;136&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;externalOpensearchHost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;137&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;externalOpensearchPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;138&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dashboard&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;139&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;140&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;alerting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;141&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;142&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# thanosruler:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;143&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;144&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;145&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auditing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;146&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;147&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# operator:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;148&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;149&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# webhook:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;150&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;151&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;devops&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;152&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;153&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jenkinsCpuReq&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;154&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jenkinsCpuLim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;155&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jenkinsMemoryReq&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;4Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;156&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jenkinsMemoryLim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;4Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;157&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jenkinsVolumeSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;16Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;158&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;159&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;160&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# operator:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;161&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;162&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# exporter:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;163&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;164&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;165&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;166&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;167&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;168&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;169&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;170&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logsidecar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;171&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;172&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;173&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;174&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics_server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;175&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;176&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;monitoring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;177&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;178&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;node_exporter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;179&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;180&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;181&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# kube_rbac_proxy:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;182&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;183&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# kube_state_metrics:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;184&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;185&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# prometheus:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;186&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;187&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# volumeSize: 20Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;188&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;189&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# operator:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;190&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;191&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# alertmanager:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;192&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;193&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;194&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# notification_manager:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;195&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;196&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# operator:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;197&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;198&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# proxy:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;199&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;200&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;201&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nvidia_dcgm_exporter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;202&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;203&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;204&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;multicluster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;205&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;clusterRole&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;none&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;206&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;207&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;networkpolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;208&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;209&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ippool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;210&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;none&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;211&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;topology&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;212&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;none&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;213&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;openpitrix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;214&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;215&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;216&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;servicemesh&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;217&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;218&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;istio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;219&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;220&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ingressGateways&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;221&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;istio-ingressgateway&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;222&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;223&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cni&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;224&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;225&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;edgeruntime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;226&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;227&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubeedge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;228&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;229&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudCore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;230&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudHub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;231&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;advertiseAddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;232&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;233&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;234&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudhubNodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30000&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;235&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudhubQuicNodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30001&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;236&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudhubHttpsNodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30002&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;237&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudstreamNodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30003&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;238&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tunnelNodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30004&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;239&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;240&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# hostNetWork: false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;241&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;iptables-manager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;242&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;243&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;external&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;244&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;245&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# edgeService:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;246&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;247&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gatekeeper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;248&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;249&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# controller_manager:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;250&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;251&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# audit:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;252&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;253&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;terminal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;254&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="upgrade"&gt;
 Upgrade
 &lt;a class="heading-anchor" href="#upgrade" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk upgrade -f config-sample.yaml -a artifact-3.0.13.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;--skip-dependency-check&lt;/code&gt;를 추가하면 Kubernetes 및 KubeSphere 버전 의존성 검사를 생략할 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk upgrade -f config-sample.yaml -a artifact-3.0.13.tar.gz --skip-dependency-check&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-tip }&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;image 별도로 push 방법&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk artifact image push -f config-sample.yaml -a artifact-3.0.7.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-tip }&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[ERROR] Harbor에 image push 할 때 Unauthorized 에러 발생 때&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;다시 로그인&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker login &lt;span class="o"&gt;[&lt;/span&gt;your.host.com&lt;span class="o"&gt;]&lt;/span&gt;:port -u username -p password
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo docker login https://cr.harbor.kubekey.com -u admin -p Harbor12345&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-danger }&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;kubekey command 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/kubekey/blob/master/docs/commands/kk-upgrade.md"&gt;https://github.com/kubesphere/kubekey/blob/master/docs/commands/kk-upgrade.md&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="upgrade-log-확인"&gt;
 Upgrade log 확인
 &lt;a class="heading-anchor" href="#upgrade-log-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl logs -n kubesphere-system &lt;span class="k"&gt;$(&lt;/span&gt;kubectl get pod -n kubesphere-system -l &lt;span class="s1"&gt;&amp;#39;app in (ks-install, ks-installer)&amp;#39;&lt;/span&gt; -o &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{.items[0].metadata.name}&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt; -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Install Kubernetes using Kubekey(v3.0.7) Artifact on VirtualBox</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-kubernetes-using-kubekeyv3.0.7-artifact-on-virtualbox/</link><pubDate>Sat, 02 Mar 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-kubernetes-using-kubekeyv3.0.7-artifact-on-virtualbox/</guid><description>&lt;blockquote&gt;
&lt;p&gt;offline 설치 위한 artifact 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;version 참고
&lt;ul&gt;
&lt;li&gt;kubernetes와 관련된 image는 &lt;a href="https://github.com/kubesphere/ks-installer/releases"&gt;https://github.com/kubesphere/ks-installer/releases&lt;/a&gt;에서 주요 release에만 포함되는 image-list.txt파일을 참고&lt;/li&gt;
&lt;li&gt;kubekey의 버전별로 kubernetes, kubesphere의 최신 지원 버전이 있음
&lt;ul&gt;
&lt;li&gt;kubekey/version/components.json&lt;/li&gt;
&lt;li&gt;kubekey/cmd/kk/pkg/version/kubesphere/version_enum.go&lt;/li&gt;
&lt;li&gt;kubekey/cmd/kk/pkg/version/kubernetes/version_enum.go&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;default 버전에 대한 설정은 kubekey/cmd/kk/apis/kubekey/v1alpha2/default.go 파일에 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/kubekey/blob/v3.0.13/docs/manifest_and_artifact.md"&gt;https://github.com/kubesphere/kubekey/blob/v3.0.13/docs/manifest_and_artifact.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/ks-installer/releases/download/v3.4.1/images-list.txt"&gt;https://github.com/kubesphere/ks-installer/releases/download/v3.4.1/images-list.txt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubesphere.io/docs/v3.4/installing-on-linux/introduction/air-gapped-installation"&gt;https://kubesphere.io/docs/v3.4/installing-on-linux/introduction/air-gapped-installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/kubekey/blob/v3.0.13/docs/manifest-example.md"&gt;https://github.com/kubesphere/kubekey/blob/v3.0.13/docs/manifest-example.md&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="script-다운로드"&gt;
 script 다운로드
 &lt;a class="heading-anchor" href="#script-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -sfL https://get-kk.kubesphere.io &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v3.0.7 sh -&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="artifact-307yaml-작성"&gt;
 artifact-3.0.7.yaml 작성
 &lt;a class="heading-anchor" href="#artifact-307yaml-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubekey.kubesphere.io/v1alpha2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Manifest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;artifact-v3.0.7&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;arches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;amd64&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operatingSystems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;arch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;amd64&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;linux&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ubuntu&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;20.04&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;osImage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Ubuntu 20.04.4 LTS&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;iso&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;localPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://github.com/kubesphere/kubekey/releases/download/v3.0.7/ubuntu-20.04-debs-amd64.iso&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubernetesDistributions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.24.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;helm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.9.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cni&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v0.9.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;etcd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.4.13&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;calicoctl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## For now, if your cluster container runtime is containerd, KubeKey will add a docker 20.10.8 container runtime in the below list.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## The reason is KubeKey creates a cluster with containerd by installing a docker first and making kubelet connect the socket file of containerd which docker contained.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerRuntimes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;docker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;20.10.8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;containerd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1.6.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;crictl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.24.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;docker-registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;harbor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v2.5.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;docker-compose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v2.2.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;images&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-apiserver:v1.27.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-apiserver:v1.26.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-apiserver:v1.25.10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-apiserver:v1.24.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-controller-manager:v1.27.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-controller-manager:v1.26.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-controller-manager:v1.25.10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-controller-manager:v1.24.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-scheduler:v1.27.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-scheduler:v1.26.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-scheduler:v1.25.10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-scheduler:v1.24.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-proxy:v1.27.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-proxy:v1.26.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-proxy:v1.25.10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-proxy:v1.24.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/pause:3.8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/pause:3.7&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/pause:3.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/pause:3.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/pause:3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/coredns/coredns:1.8.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/coredns/coredns:1.8.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/cni:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/kube-controllers:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/node:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/pod2daemon-flexvol:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/calico/typha:v3.23.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/flannel:v0.12.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/openebs/provisioner-localpv:3.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/openebs/linux-utils:3.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/haproxy:2.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/nfs-subdir-external-provisioner:v4.0.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/k8s-dns-node-cache:1.15.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# https://github.com/kubesphere/ks-installer/releases/download/v3.3.2/images-list.txt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##kubesphere-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-installer:v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-installer:v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-apiserver:v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-apiserver:v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-console:v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-console:v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-controller-manager:v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-controller-manager:v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kubectl:v1.22.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kubectl:v1.20.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kubefed:v0.8.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/tower:v0.2.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/tower:v0.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/minio/minio:RELEASE.2019-08-07T01-59-21Z&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/minio/mc:RELEASE.2019-08-07T23-14-43Z&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/csiplugin/snapshot-controller:v4.0.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/nginx-ingress-controller:v1.3.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/nginx-ingress-controller:v1.1.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/mirrorgooglecontainers/defaultbackend-amd64:1.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/metrics-server:v0.4.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/redis:5.0.14-alpine&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/haproxy:2.0.25-alpine&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/alpine:3.14&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/osixia/openldap:1.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/netshoot:v1.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##kubeedge-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;108&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubeedge/cloudcore:v1.13.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;109&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubeedge/cloudcore:v1.9.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;110&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/iptables-manager:v1.13.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;111&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubeedge/iptables-manager:v1.9.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;112&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/edgeservice:v0.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;113&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/edgeservice:v0.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;114&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##gatekeeper-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;115&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/openpolicyagent/gatekeeper:v3.5.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;116&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##openpitrix-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;117&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/openpitrix-jobs:v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;118&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##kubesphere-devops-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;119&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/devops-apiserver:ks-v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;120&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/devops-apiserver:ks-v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;121&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/devops-controller:ks-v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;122&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/devops-controller:ks-v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;123&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/devops-tools:ks-v3.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;124&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/devops-tools:ks-v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;125&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-jenkins:v3.4.0-2.319.3-1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;126&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/ks-jenkins:v3.3.0-2.319.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;127&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jenkins/inbound-agent:4.10-2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;128&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-base:v3.2.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;129&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-nodejs:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;130&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-maven:v3.2.1-jdk11&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;131&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-maven:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;132&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-python:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;133&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.2-1.18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;134&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.2-1.17&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;135&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.2-1.16&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;136&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;137&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-base:v3.2.2-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;138&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-nodejs:v3.2.0-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;139&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-maven:v3.2.1-jdk11-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;140&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-maven:v3.2.0-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;141&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-python:v3.2.0-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;142&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.0-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;143&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.2-1.18-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;144&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.2-1.17-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;145&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/builder-go:v3.2.2-1.16-podman&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;146&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/s2ioperator:v3.2.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;147&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/s2irun:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;148&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/s2i-binary:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;149&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/tomcat85-java11-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;150&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/tomcat85-java11-runtime:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;151&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/tomcat85-java8-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;152&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/tomcat85-java8-runtime:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;153&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/java-11-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;154&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/java-11-runtime:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;155&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/java-8-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;156&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/java-8-runtime:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;157&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/nodejs-8-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;158&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/nodejs-6-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;159&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/nodejs-4-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;160&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/python-36-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;161&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/python-35-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;162&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/python-34-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;163&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/python-27-centos7:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;164&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;quay.io/argoproj/argocd:v2.3.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;165&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;quay.io/argoproj/argocd-applicationset:v0.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;166&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ghcr.io/dexidp/dex:v2.30.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;167&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/redis:6.2.6-alpine&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;168&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##kubesphere-monitoring-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;169&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jimmidyson/configmap-reload:v0.7.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;170&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jimmidyson/configmap-reload:v0.5.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;171&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/prom/prometheus:v2.39.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;172&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/prom/prometheus:v2.34.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;173&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/prometheus-config-reloader:v0.55.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;174&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/prometheus-operator:v0.55.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;175&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-rbac-proxy:v0.11.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;176&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-state-metrics:v2.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;177&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-state-metrics:v2.5.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;178&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/prom/node-exporter:v1.3.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;179&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/prom/alertmanager:v0.23.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;180&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/thanosio/thanos:v0.31.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;181&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/thanosio/thanos:v0.25.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;182&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/grafana/grafana:8.3.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;183&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-rbac-proxy:v0.11.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;184&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-rbac-proxy:v0.8.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;185&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/notification-manager-operator:v2.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;186&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/notification-manager-operator:v1.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;187&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/notification-manager:v2.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;188&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/notification-manager:v1.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;189&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/notification-tenant-sidecar:v3.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;190&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##kubesphere-logging-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;191&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/elasticsearch-curator:v5.7.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;192&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/opensearch-curator:v0.0.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;193&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/elasticsearch-oss:6.8.22&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;194&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/opensearchproject/opensearch:2.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;195&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/opensearchproject/opensearch-dashboards:2.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;196&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/fluentbit-operator:v0.14.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;197&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/fluentbit-operator:v0.13.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;198&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/library/docker:19.03&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;199&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/fluent-bit:v1.9.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;200&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/fluent-bit:v1.8.11&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;201&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/log-sidecar-injector:v1.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;202&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/elastic/filebeat:6.7.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;203&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-events-operator:v0.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;204&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-events-operator:v0.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;205&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-events-exporter:v0.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;206&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-events-exporter:v0.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;207&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-events-ruler:v0.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;208&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-events-ruler:v0.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;209&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-auditing-operator:v0.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;210&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kube-auditing-webhook:v0.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;211&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##istio-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;212&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/istio/pilot:1.14.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;213&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/istio/pilot:1.11.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;214&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/istio/proxyv2:1.14.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;215&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/istio/proxyv2:1.11.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;216&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jaegertracing/jaeger-operator:1.29&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;217&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jaegertracing/jaeger-operator:1.27&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;218&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jaegertracing/jaeger-agent:1.29&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;219&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jaegertracing/jaeger-agent:1.27&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;220&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jaegertracing/jaeger-collector:1.29&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;221&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jaegertracing/jaeger-collector:1.27&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;222&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jaegertracing/jaeger-query:1.29&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;223&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jaegertracing/jaeger-query:1.27&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;224&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jaegertracing/jaeger-es-index-cleaner:1.29&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;225&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/jaegertracing/jaeger-es-index-cleaner:1.27&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;226&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kiali-operator:v1.50.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;227&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kiali-operator:v1.38.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;228&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kiali:v1.50&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;229&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker.io/kubesphere/kiali:v1.38&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;230&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ##example-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;231&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/library/busybox:1.31.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;232&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/library/nginx:1.14-alpine&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;233&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/joosthofman/wget:1.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;234&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/nginxdemos/hello:plain-text&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;235&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/library/wordpress:4.8-apache&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;236&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/mirrorgooglecontainers/hpa-example:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;237&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/fluent/fluentd:v1.4.2-2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;238&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/library/perl:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;239&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/examples-bookinfo-productpage-v1:1.16.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;240&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/examples-bookinfo-reviews-v1:1.16.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;241&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/examples-bookinfo-reviews-v2:1.16.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;242&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/examples-bookinfo-details-v1:1.16.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;243&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/kubesphere/examples-bookinfo-ratings-v1:1.16.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;244&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ##weave-scope-images&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;245&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker.io/weaveworks/scope:1.13.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;246&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;247&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;248&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;docker.io&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;249&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;username&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;250&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;password&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="export-artifact"&gt;
 Export Artifact
 &lt;a class="heading-anchor" href="#export-artifact" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk artifact &lt;span class="nb"&gt;export&lt;/span&gt; -m artifact-3.0.7.yaml -o artifact-3.0.7.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cluster-설치를-위한-config-파일-생성-및-작성"&gt;
 Cluster 설치를 위한 config 파일 생성 및 작성
 &lt;a class="heading-anchor" href="#cluster-%ec%84%a4%ec%b9%98%eb%a5%bc-%ec%9c%84%ed%95%9c-config-%ed%8c%8c%ec%9d%bc-%ec%83%9d%ec%84%b1-%eb%b0%8f-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;config 파일 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk create config --with-kubesphere v3.3.2 --with-kubernetes v1.24.9 -f config-sample.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;config 파일 작성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubekey.kubesphere.io/v1alpha2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;sample&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: manage-master, address: 192.168.10.100, internalAddress: 192.168.10.100, user: root, password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;vagrant}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: manage-worker-1, address: 192.168.10.110, internalAddress: 192.168.10.110, user: root, password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;vagrant}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: manage-worker-2, address: 192.168.10.120, internalAddress: 192.168.10.120, user: root, password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;vagrant}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;roleGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;etcd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;manage-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;control-plane&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;manage-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;manage-worker-1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;manage-worker-2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;manage-worker-1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;controlPlaneEndpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## Internal loadbalancer for apiservers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# internalLoadbalancer: haproxy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#domain: lb.kubesphere.local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192.168.10.100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubernetes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.24.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;clusterName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster.local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;autoRenewCerts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerManager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;containerd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;etcd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubekey&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;calico&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubePodsCIDR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10.233.64.0&lt;/span&gt;&lt;span class="l"&gt;/18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubeServiceCIDR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10.233.0.0&lt;/span&gt;&lt;span class="l"&gt;/18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## multus support. https://github.com/k8snetworkplumbingwg/multus-cni&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;multusCNI&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;harbor&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;dockerhub.kubekey.local&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;admin&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Harbor12345&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;privateRegistry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;dockerhub.kubekey.local&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespaceOverride&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;kubesphereio&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registryMirrors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecureRegistries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;addons&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;installer.kubesphere.io/v1alpha1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterConfiguration&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ks-installer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubesphere-system&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v3.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persistence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;authentication&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jwtSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;zone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;local_registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace_override&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# dev_tag: &amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;etcd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;monitoring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpointIps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;localhost&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2379&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tlsEnable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;common&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;core&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enableMultiLogin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;30880&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NodePort&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# apiserver:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# controllerManager:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;2Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;openldap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;2Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;minio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;20Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;monitoring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# type: external&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://prometheus-operated.kubesphere-monitoring-system.svc:9090&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;GPUMonitoring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kinds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;resourceName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;nvidia.com/gpu&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resourceType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;GPU&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;es&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# master:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# volumeSize: 4Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;108&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# data:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;109&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# volumeSize: 20Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;110&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;111&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;112&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logMaxAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;113&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;elkPrefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;logstash&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;114&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;basicAuth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;115&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;116&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;117&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;118&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;externalElasticsearchHost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;119&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;externalElasticsearchPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;120&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;alerting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;121&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;122&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# thanosruler:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;123&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;124&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;125&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;auditing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;126&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;127&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# operator:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;128&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;129&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# webhook:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;130&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;131&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;devops&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;132&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;133&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;134&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jenkinsMemoryLim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;8Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;135&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jenkinsMemoryReq&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;4Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;136&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;jenkinsVolumeSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;8Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;137&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;138&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;139&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# operator:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;140&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;141&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# exporter:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;142&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;143&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ruler:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;144&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# enabled: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;145&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;146&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;147&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;148&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;149&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;logsidecar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;150&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;151&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;152&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;153&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metrics_server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;154&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;155&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;monitoring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;156&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;157&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;node_exporter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;158&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;159&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;160&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# kube_rbac_proxy:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;161&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;162&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# kube_state_metrics:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;163&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;164&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# prometheus:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;165&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;166&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# volumeSize: 20Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;167&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;168&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# operator:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;169&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;170&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# alertmanager:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;171&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# replicas: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;172&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;173&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# notification_manager:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;174&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;175&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# operator:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;176&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;177&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# proxy:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;178&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;179&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;180&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nvidia_dcgm_exporter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;181&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;182&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;183&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;multicluster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;184&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;clusterRole&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;none&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;185&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;186&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;networkpolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;187&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;188&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ippool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;189&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;none&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;190&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;topology&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;191&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;none&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;192&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;openpitrix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;193&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;194&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;195&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;servicemesh&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;196&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;197&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;istio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;198&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;199&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ingressGateways&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;200&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;istio-ingressgateway&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;201&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;202&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cni&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;203&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;204&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;edgeruntime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;205&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;206&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubeedge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;207&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;208&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudCore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;209&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudHub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;210&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;advertiseAddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;211&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;212&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;213&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudhubNodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30000&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;214&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudhubQuicNodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30001&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;215&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudhubHttpsNodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30002&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;216&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cloudstreamNodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30003&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;217&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tunnelNodePort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;30004&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;218&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;219&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# hostNetWork: false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;220&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;iptables-manager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;221&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;222&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;external&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;223&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;224&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# edgeService:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;225&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# resources: {}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;226&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;terminal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;227&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="registry-설치"&gt;
 registry 설치
 &lt;a class="heading-anchor" href="#registry-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk init registry -f config-sample.yaml -a artifact-3.0.7.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[ERROR] ssh error&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;각 node 별로 ssh가 안될시 root passwd가 맞지 않아 발생함.&lt;/li&gt;
&lt;li&gt;vagrant에서 vm이 생성되면 root 비번을 설정해줘야 하는 듯
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo passwd root&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;{: .prompt-info }&lt;/p&gt;
&lt;h2 id="harbor-인증서-복사-및-업데이트-harbor-curl-60-ssl-certificate-problem-unable-to-get-local-issuer-certificate"&gt;
 Harbor 인증서 복사 및 업데이트 (harbor curl: (60) SSL certificate problem: unable to get local issuer certificate)
 &lt;a class="heading-anchor" href="#harbor-%ec%9d%b8%ec%a6%9d%ec%84%9c-%eb%b3%b5%ec%82%ac-%eb%b0%8f-%ec%97%85%eb%8d%b0%ec%9d%b4%ed%8a%b8-harbor-curl-60-ssl-certificate-problem-unable-to-get-local-issuer-certificate" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;sudo cp /etc/docker/certs.d/dockerhub.kubekey.local/ca.crt /usr/local/share/ca-certificates/harbor-ca.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;scp -i /home/vagrant/.ssh/id_rsa /usr/local/share/ca-certificates/harbor-ca.crt root@192.168.10.110:/usr/local/share/ca-certificates/harbor-ca.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;scp -i /home/vagrant/.ssh/id_rsa /usr/local/share/ca-certificates/harbor-ca.crt root@192.168.10.120:/usr/local/share/ca-certificates/harbor-ca.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 각 node 별로 아래 작업&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;sudo update-ca-certificates
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 인증서 적용 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;ls -lrt /etc/ssl/certs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;- harbor-ca.pem -&amp;gt; /usr/local/share/ca-certificates/harbor-ca.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;- ca-certificates.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;systemctl restart containerd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;harbor 주소 : [harbor 설치한 ip]:80
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="harbor-프로젝트-생성-및-수정"&gt;
 Harbor 프로젝트 생성 및 수정
 &lt;a class="heading-anchor" href="#harbor-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%83%9d%ec%84%b1-%eb%b0%8f-%ec%88%98%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -O https://raw.githubusercontent.com/kubesphere/ks-installer/master/scripts/create_project_harbor.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="harbor-프로젝트-수정-및-url-수정"&gt;
 Harbor 프로젝트 수정 및 url 수정(&lt;a href="https://dockerhub.kubekey.local"&gt;https://dockerhub.kubekey.local&lt;/a&gt;)
 &lt;a class="heading-anchor" href="#harbor-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%88%98%ec%a0%95-%eb%b0%8f-url-%ec%88%98%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;파일 편집&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi create_project_harbor.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;url 수정(&lt;a href="https://dockerhub.kubekey.local"&gt;https://dockerhub.kubekey.local&lt;/a&gt;)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Copyright 2018 The KubeSphere Authors.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Licensed under the Apache License, Version 2.0 (the &amp;#34;License&amp;#34;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# you may not use this file except in compliance with the License.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# You may obtain a copy of the License at&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# http://www.apache.org/licenses/LICENSE-2.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Unless required by applicable law or agreed to in writing, software&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# distributed under the License is distributed on an &amp;#34;AS IS&amp;#34; BASIS,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# See the License for the specific language governing permissions and&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# limitations under the License.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://dockerhub.kubekey.local&amp;#34;&lt;/span&gt; &lt;span class="c1"&gt;#Change the value of url to https://dockerhub.kubekey.local.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;passwd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Harbor12345&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;harbor_projects&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;library
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; kubesphereio
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; kubesphere
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; argoproj
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; calico
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; coredns
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; openebs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; csiplugin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; minio
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; mirrorgooglecontainers
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt; osixia
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt; prom
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt; thanosio
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt; jimmidyson
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt; grafana
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt; elastic
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt; istio
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt; jaegertracing
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt; jenkins
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt; weaveworks
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt; openpitrix
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt; joosthofman
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt; nginxdemos
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt; fluent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt; kubeedge
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt; openpolicyagent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; project in &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;harbor_projects&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;creating &lt;/span&gt;&lt;span class="nv"&gt;$project&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt; curl -u &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;passwd&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -X POST -H &lt;span class="s2"&gt;&amp;#34;Content-Type: application/json&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/api/v2.0/projects&amp;#34;&lt;/span&gt; -d &lt;span class="s2"&gt;&amp;#34;{ \&amp;#34;project_name\&amp;#34;: \&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;project&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\&amp;#34;, \&amp;#34;public\&amp;#34;: true}&amp;#34;&lt;/span&gt; -k &lt;span class="c1"&gt;#Add -k at the end of the curl command.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;파일 권한 변경&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chmod +x create_project_harbor.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;실행&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;./create_project_harbor.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="image-별도로-push-방법"&gt;
 image 별도로 push 방법
 &lt;a class="heading-anchor" href="#image-%eb%b3%84%eb%8f%84%eb%a1%9c-push-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk artifact image push -f config-sample.yaml -a artifact-3.0.7.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[ERROR] Harbor에 image push 할 때 Unauthorized 에러 발생 때&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;다시 로그인&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker login &lt;span class="o"&gt;[&lt;/span&gt;your.host.com&lt;span class="o"&gt;]&lt;/span&gt;:port -u username -p password&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-info }&lt;/p&gt;
&lt;h2 id="cluster-설치"&gt;
 Cluster 설치
 &lt;a class="heading-anchor" href="#cluster-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk create cluster -f config-sample.yaml -a artifact-3.0.7.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Install operating system packages&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk create cluster -f config-sample.yaml -a artifact-3.0.7.tar.gz --with-packages&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-tip }&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;--skip-push-images&lt;/code&gt;를 추가하면 harbor에 image를 push하는 과정으로 생략할 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./kk create cluster -f config-sample.yaml -a artifact-3.0.7.tar.gz --skip-push-images&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-tip }&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;kubekey command 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/kubekey/blob/master/docs/commands/kk-upgrade.md"&gt;https://github.com/kubesphere/kubekey/blob/master/docs/commands/kk-upgrade.md&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="cluster-설치하면서-log-확인"&gt;
 Cluster 설치하면서 log 확인
 &lt;a class="heading-anchor" href="#cluster-%ec%84%a4%ec%b9%98%ed%95%98%eb%a9%b4%ec%84%9c-log-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl logs -n kubesphere-system &lt;span class="k"&gt;$(&lt;/span&gt;kubectl get pod -n kubesphere-system -l &lt;span class="s1"&gt;&amp;#39;app in (ks-install, ks-installer)&amp;#39;&lt;/span&gt; -o &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{.items[0].metadata.name}&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt; -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="kubernetes-일반-유저-일-때"&gt;
 Kubernetes 일반 유저 일 때
 &lt;a class="heading-anchor" href="#kubernetes-%ec%9d%bc%eb%b0%98-%ec%9c%a0%ec%a0%80-%ec%9d%bc-%eb%95%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mkdir -p &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo cp -i /etc/kubernetes/admin.conf &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo chown &lt;span class="k"&gt;$(&lt;/span&gt;id -u&lt;span class="k"&gt;)&lt;/span&gt;:&lt;span class="k"&gt;$(&lt;/span&gt;id -g&lt;span class="k"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;만약 일반 계정에서 아래와 sudo 명령어 없이 kubectl 명령어 사용시 아래와 같은 오류가 발생하면&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;[ERROR] error loading config file &lt;code&gt;/etc/kubernetes/admin.conf&lt;/code&gt;: open /etc/kubernetes/admin.conf: permission denied
&lt;ul&gt;
&lt;li&gt;아래 명령어를 입력하면 sudo 없이 사용 가능하다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;{: .prompt-danger }&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[ERROR] error making pod data directories: mkdir /var/lib/kubelet/pods/86cfe394-ba32-4a9f-ad65-1fb21f98a4ba: read-only file system&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chown -R kubelet:kubelet /var/lib/kubelet/pods
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;750&lt;/span&gt; /var/lib/kubelet/pods
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;systemctl restart kubelet&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-danger }&lt;/p&gt;</description></item><item><title>[Kubernetes] Install Kubernetes using Kubekey(v3.0.7) on VirtualBox</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-kubernetes-using-kubekeyv3.0.7-on-virtualbox/</link><pubDate>Fri, 01 Mar 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-kubernetes-using-kubekeyv3.0.7-on-virtualbox/</guid><description>&lt;h2 id="script-다운로드"&gt;
 script 다운로드
 &lt;a class="heading-anchor" href="#script-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -sfL https://get-kk.kubesphere.io &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v3.0.7 sh -&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="binary-downloads"&gt;
 Binary Downloads
 &lt;a class="heading-anchor" href="#binary-downloads" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubesphere/kubekey/releases"&gt;https://github.com/kubesphere/kubekey/releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="build-binary-from-source-code"&gt;
 Build Binary from Source Code
 &lt;a class="heading-anchor" href="#build-binary-from-source-code" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;git clone https://github.com/kubesphere/kubekey.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; kubekey
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;make kk&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="quick-install-cluster"&gt;
 Quick Install Cluster
 &lt;a class="heading-anchor" href="#quick-install-cluster" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;./kk create cluster &lt;span class="o"&gt;[&lt;/span&gt;--with-kubernetes versio&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;--with-kubesphere version&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create a Kubernetes cluster with a specified version.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;./kk create cluster --with-kubernetes v1.24.1 --container-manager containerd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a Kubernetes cluster with KubeSphere installed.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;./kk create cluster --with-kubesphere v3.2.1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="custom-install-cluster"&gt;
 Custom Install Cluster
 &lt;a class="heading-anchor" href="#custom-install-cluster" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="세부-설정을-위한-create-config"&gt;
 세부 설정을 위한 Create Config
 &lt;a class="heading-anchor" href="#%ec%84%b8%eb%b6%80-%ec%84%a4%ec%a0%95%ec%9d%84-%ec%9c%84%ed%95%9c-create-config" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;./kk create config &lt;span class="o"&gt;[&lt;/span&gt;--with-kubernetes version&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;--with-kubesphere version&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[(&lt;/span&gt;-f &lt;span class="p"&gt;|&lt;/span&gt; --filename&lt;span class="o"&gt;)&lt;/span&gt; path&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;다른 파일 이름이나 다른 폴더에 있는 파일을 지정할 수도 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;./kk create config &lt;span class="o"&gt;[&lt;/span&gt;--with-kubernetes version&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[(&lt;/span&gt;-f &lt;span class="p"&gt;|&lt;/span&gt; --file&lt;span class="o"&gt;)&lt;/span&gt; path&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Examples
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;./kk create config --with-kubernetes v1.20.4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;{: .prompt-info }&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;파일 작성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi config-sample.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubekey.kubesphere.io/v1alpha1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Cluster&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;sample&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: master, address: 192.168.0.1, internalAddress: 192.168.0.1, privateKeyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;~/.ssh/id_rsa&amp;#34;&lt;/span&gt;}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: master, address: 192.168.0.1, internalAddress: 192.168.0.1, user: root, password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Testing123}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: worker1, address: 192.168.0.2, internalAddress: 192.168.0.2, user: root, password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Testing123}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- {&lt;span class="nt"&gt;name: worker2, address: 192.168.0.3, internalAddress: 192.168.0.3, user: root, password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Testing123}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;roleGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;etcd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;master&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;worker1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;worker2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;controlPlaneEndpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;lb.kubesphere.local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;6443&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubernetes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1.17.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;imageRepo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubesphere&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;clusterName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster.local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;calico&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubePodsCIDR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10.233.64.0&lt;/span&gt;&lt;span class="l"&gt;/18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubeServiceCIDR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10.233.0.0&lt;/span&gt;&lt;span class="l"&gt;/18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;registryMirrors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecureRegistries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;addons&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="install-cluster"&gt;
 Install Cluster
 &lt;a class="heading-anchor" href="#install-cluster" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;./kk create cluster -f config-sample.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="cluster-설치하면서-log-확인"&gt;
 Cluster 설치하면서 log 확인
 &lt;a class="heading-anchor" href="#cluster-%ec%84%a4%ec%b9%98%ed%95%98%eb%a9%b4%ec%84%9c-log-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl logs -n kubesphere-system &lt;span class="k"&gt;$(&lt;/span&gt;kubectl get pod -n kubesphere-system -l &lt;span class="s1"&gt;&amp;#39;app in (ks-install, ks-installer)&amp;#39;&lt;/span&gt; -o &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{.items[0].metadata.name}&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt; -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="kubernetes-일반-유저-일-때"&gt;
 Kubernetes 일반 유저 일 때
 &lt;a class="heading-anchor" href="#kubernetes-%ec%9d%bc%eb%b0%98-%ec%9c%a0%ec%a0%80-%ec%9d%bc-%eb%95%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mkdir -p &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo cp -i /etc/kubernetes/admin.conf &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo chown &lt;span class="k"&gt;$(&lt;/span&gt;id -u&lt;span class="k"&gt;)&lt;/span&gt;:&lt;span class="k"&gt;$(&lt;/span&gt;id -g&lt;span class="k"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;만약 일반 계정에서 아래와 sudo 명령어 없이 kubectl 명령어 사용시 아래와 같은 오류가 발생하면&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;[ERROR] error loading config file &lt;code&gt;/etc/kubernetes/admin.conf&lt;/code&gt;: open /etc/kubernetes/admin.conf: permission denied
&lt;ul&gt;
&lt;li&gt;아래 명령어를 입력하면 sudo 없이 사용 가능하다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;{: .prompt-danger }&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[ERROR] error making pod data directories: mkdir /var/lib/kubelet/pods/86cfe394-ba32-4a9f-ad65-1fb21f98a4ba: read-only file system&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chown -R kubelet:kubelet /var/lib/kubelet/pods
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;750&lt;/span&gt; /var/lib/kubelet/pods
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;systemctl restart kubelet&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-danger }&lt;/p&gt;</description></item><item><title>[Kubernetes] Helm</title><link>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-helm/</link><pubDate>Mon, 12 Feb 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-helm/</guid><description>&lt;h2 id="install-helm"&gt;
 Install Helm
 &lt;a class="heading-anchor" href="#install-helm" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;설치 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://helm.sh/docs/intro/install/"&gt;https://helm.sh/docs/intro/install/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="script-방식"&gt;
 Script 방식
 &lt;a class="heading-anchor" href="#script-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;chmod +x get_helm.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;./get_helm.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;helm version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="windows"&gt;
 Windows
 &lt;a class="heading-anchor" href="#windows" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="choco-이용"&gt;
 choco 이용
 &lt;a class="heading-anchor" href="#choco-%ec%9d%b4%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;choco install kubernetes-helm&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="scoop-이용"&gt;
 scoop 이용
 &lt;a class="heading-anchor" href="#scoop-%ec%9d%b4%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;scoop install helm&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="apt-이용-debianubuntu"&gt;
 Apt 이용 (Debian/Ubuntu)
 &lt;a class="heading-anchor" href="#apt-%ec%9d%b4%ec%9a%a9-debianubuntu" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl https://baltocdn.com/helm/signing.asc &lt;span class="p"&gt;|&lt;/span&gt; gpg --dearmor &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /usr/share/keyrings/helm.gpg &amp;gt; /dev/null
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get install apt-transport-https --yes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deb [arch=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;dpkg --print-architecture&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get install helm&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="helm-chart-명령어"&gt;
 Helm Chart 명령어
 &lt;a class="heading-anchor" href="#helm-chart-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Helm Commands 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://helm.sh/ko/docs/helm/"&gt;https://helm.sh/ko/docs/helm/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-search"&gt;
 helm search
 &lt;a class="heading-anchor" href="#helm-search" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;chart 찾기
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm search hub [keyword]&lt;/code&gt; 는 여러 저장소들에 있는 헬름 차트들을 포괄하는 helm hub 를 검색한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;helm search repo [keyword]&lt;/code&gt; 는 helm repo add [name] [chars_url] 를 사용하여 로컬 헬름 클라이언트에 추가된 저장소들을 검색한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-install"&gt;
 helm install
 &lt;a class="heading-anchor" href="#helm-install" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;패키지 설치
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm install [chart] --generate-name --debug --dry-run&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--dry-run&lt;/code&gt; : 실제 클러스터에 설치 하지 않고 chart를 시험 설치하는 옵션&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--debug&lt;/code&gt; : 배포를 위한 manifest 파일 내용을 보여줌&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;helm install [release] [chart]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;helm install -f values.yaml [chart] --generate-name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;helm install --set servers[0].port=80 [release] [chart]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;helm install [release] charts.tgz&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;helm install [release] path/to/charts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;helm install [release] [charts_tgz_url]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-status"&gt;
 helm status
 &lt;a class="heading-anchor" href="#helm-status" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;릴리스의 상태 확인
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm status [release]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-show-values"&gt;
 helm show values
 &lt;a class="heading-anchor" href="#helm-show-values" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;차트에 옵션 설정 가능한 values 조회
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm show values [chart]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-get-values"&gt;
 helm get values
 &lt;a class="heading-anchor" href="#helm-get-values" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;해당 릴리스에 대한 옵션 설정 values를 조회
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm get values [release]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-upgrade"&gt;
 helm upgrade
 &lt;a class="heading-anchor" href="#helm-upgrade" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;릴리스 업그레이드
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm upgrade -f values.yaml [release] [chart]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-rollback"&gt;
 helm rollback
 &lt;a class="heading-anchor" href="#helm-rollback" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;릴리스 원복
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm rollback [release] [version]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-history"&gt;
 helm history
 &lt;a class="heading-anchor" href="#helm-history" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;릴리스 버전 이력 조회
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm history [release]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-uninstall"&gt;
 helm uninstall
 &lt;a class="heading-anchor" href="#helm-uninstall" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;릴리스 uninstall
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm uninstall [release]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--keep-history&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;삭제시 릴리스 기록을 보존&lt;/li&gt;
&lt;li&gt;기본적으로는 기록도 삭제&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-list"&gt;
 helm list
 &lt;a class="heading-anchor" href="#helm-list" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;릴리스 목록 조회
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm list --all&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--all&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;실패하거나 삭제된 기록도 모두 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-repo"&gt;
 helm repo
 &lt;a class="heading-anchor" href="#helm-repo" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;저장소 작업하기&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-repo-list"&gt;
 helm repo list
 &lt;a class="heading-anchor" href="#helm-repo-list" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;저장된 저장소 목록 조회
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm repo list&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-repo-add"&gt;
 helm repo add
 &lt;a class="heading-anchor" href="#helm-repo-add" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;새 저장소 추가
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm repo add [name] [url]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-repo-update"&gt;
 helm repo update
 &lt;a class="heading-anchor" href="#helm-repo-update" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;저장소 업데이트
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm repo update [name1] [name2] ...&lt;/code&gt;
&lt;blockquote&gt;
&lt;p&gt;이전에 repository를 추가한 경우, 아래 명령을 실행하여 최신 버전의 패키지를 가져온다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-repo-remove"&gt;
 helm repo remove
 &lt;a class="heading-anchor" href="#helm-repo-remove" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;저장소 삭제
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm repo remove [name1] [name2] ...&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-create"&gt;
 helm create
 &lt;a class="heading-anchor" href="#helm-create" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;내 차트 만들기
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm create [name]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Directory에 차트가 생김&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="helm-package"&gt;
 helm package
 &lt;a class="heading-anchor" href="#helm-package" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;배포용 차트로 패키징
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;helm package [chart_path]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="chart"&gt;
 Chart
 &lt;a class="heading-anchor" href="#chart" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Chart 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://helm.sh/ko/docs/topics/charts/"&gt;https://helm.sh/ko/docs/topics/charts/&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Chart.yaml&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;차트에 대한 정보를 가진 YAML 파일
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;차트 API 버전 (필수)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;차트명 (필수)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;SemVer 2 버전 (필수)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kubeVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;호환되는 쿠버네티스 버전의 SemVer 범위 (선택)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;이 프로젝트에 대한 간략한 설명 (선택)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;차트 타입 (선택)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;이 프로젝트에 대한 키워드 리스트 (선택)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;home&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;프로젝트 홈페이지의 URL (선택)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;sources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;이 프로젝트의 소스코드 URL 리스트 (선택)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 차트 필요조건들의 리스트 (optional)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;차트명 (nginx)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;차트의 버전 (&amp;#34;1.2.3&amp;#34;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;저장소 URL (&amp;#34;https://example.com/charts&amp;#34;) 또는 (&amp;#34;@repo-name&amp;#34;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;condition: (선택) 차트들의 활성/비활성을 결정하는 boolean 값을 만드는 yaml 경로 (예시&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;subchart1.enabled)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# (선택)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;활성화 / 비활성을 함께하기 위해 차트들을 그룹화 할 수 있는 태그들&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;(선택) 차트가 로드될수 있는지 결정하는 boolean&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;import-values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# (선택)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ImportValues 는 가져올 상위 키에 대한 소스 값의 맵핑을 보유한다. 각 항목은 문자열이거나 하위 / 상위 하위 목록 항목 쌍일 수 있다.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;(선택) 차트에 대한 별명으로 사용된다. 같은 차트를 여러번 추가해야할때 유용하다.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;maintainers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# (선택)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;maintainer들의 이름 (각 maintainer마다 필수)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;maintainer들의 email (각 maintainer마다 선택)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;maintainer에 대한 URL (각 maintainer마다 선택)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;아이콘으로 사용될 SVG나 PNG 이미지 URL (선택)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;appVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;이 앱의 버전 (선택). SemVer인 필요는 없다.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;deprecated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;차트의 deprecated 여부 (선택, boolean)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;example&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;키로 매핑된 주석들의 리스트 (선택).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Install AWX Using Helm Chart</title><link>https://kyungryeol-yoon.github.io/devops/ansible/kubernetes-install-awx-using-helm/</link><pubDate>Fri, 02 Feb 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/ansible/kubernetes-install-awx-using-helm/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="install-awx-operator"&gt;
 Install awx-operator
 &lt;a class="heading-anchor" href="#install-awx-operator" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo add awx-operator https://ansible.github.io/awx-operator/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;helm install ansible-awx-operator awx-operator/awx-operator -n awx --create-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;설치 참고&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ansible.readthedocs.io/projects/awx-operator/en/latest/installation/basic-install.html"&gt;https://ansible.readthedocs.io/projects/awx-operator/en/latest/installation/basic-install.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ansible/awx-operator/blob/devel/docs/installation/basic-install.md"&gt;https://github.com/ansible/awx-operator/blob/devel/docs/installation/basic-install.md&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="customize-default-configuration"&gt;
 Customize Default Configuration
 &lt;a class="heading-anchor" href="#customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;values.yaml 수정&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;최상위 values.yaml을 수정하면 하위 폴더 values.yaml을 override 한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Chart : &lt;a href="https://github.com/ansible/awx-operator/tree/%7Btags%7D/.helm/starter"&gt;https://github.com/ansible/awx-operator/tree/{tags}/.helm/starter&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Release file (.tgz) : &lt;a href="https://github.com/ansible/awx-operator/releases"&gt;https://github.com/ansible/awx-operator/releases&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="install-customize-default-configuration"&gt;
 Install Customize Default Configuration
 &lt;a class="heading-anchor" href="#install-customize-default-configuration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install &lt;span class="o"&gt;[&lt;/span&gt;RELEASE NAME&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;Chart.yaml 경로&lt;span class="o"&gt;]&lt;/span&gt; -f &lt;span class="o"&gt;[&lt;/span&gt;YAML 파일 또는 URL에 값 지정 &lt;span class="o"&gt;(&lt;/span&gt;여러 개를 지정가능&lt;span class="o"&gt;)]&lt;/span&gt; -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install ansible-awx-operator awx-operator/awx-operator -f override-values.yaml -n &lt;span class="o"&gt;[&lt;/span&gt;NAMESPACE NAME&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="verify-awx-operator-installation"&gt;
 Verify AWX operator installation
 &lt;a class="heading-anchor" href="#verify-awx-operator-installation" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods -n awx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="create-pv-pvc-and-deploy-awx-yaml-file"&gt;
 Create PV, PVC and deploy AWX yaml file
 &lt;a class="heading-anchor" href="#create-pv-pvc-and-deploy-awx-yaml-file" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;AWX에는 postgres Pod에 대한 영구 볼륨이 필요
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;다만 StorageClass가 설정되어 있다면 자동으로 pv, pvc 생성을 해주므로 AWX instance 바로 배포
{: .prompt-tip }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="storageclass"&gt;
 StorageClass
 &lt;a class="heading-anchor" href="#storageclass" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="storageclass-생성-파일-작성"&gt;
 StorageClass 생성 파일 작성
 &lt;a class="heading-anchor" href="#storageclass-%ec%83%9d%ec%84%b1-%ed%8c%8c%ec%9d%bc-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi local-storage-class.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;storage.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;StorageClass&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local-storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;awx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;provisioner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes.io/no-provisioner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;volumeBindingMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;WaitForFirstConsumer&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="storageclass-생성-및-확인"&gt;
 StorageClass 생성 및 확인
 &lt;a class="heading-anchor" href="#storageclass-%ec%83%9d%ec%84%b1-%eb%b0%8f-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create -f local-storage-class.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get sc -n awx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="persistentvolume"&gt;
 PersistentVolume
 &lt;a class="heading-anchor" href="#persistentvolume" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="persistentvolume-생성-파일-작성"&gt;
 PersistentVolume 생성 파일 작성
 &lt;a class="heading-anchor" href="#persistentvolume-%ec%83%9d%ec%84%b1-%ed%8c%8c%ec%9d%bc-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi pv.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PersistentVolume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgres-pv&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;awx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Filesystem&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteOnce&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persistentVolumeReclaimPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Delete&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClassName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local-storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;local&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/mnt/storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeAffinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeSelectorTerms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;matchExpressions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes.io/hostname&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;In&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;k8s-worker&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="persistentvolume-생성-및-확인"&gt;
 PersistentVolume 생성 및 확인
 &lt;a class="heading-anchor" href="#persistentvolume-%ec%83%9d%ec%84%b1-%eb%b0%8f-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create -f pv.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pv -n awx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="persistentvolumeclaim"&gt;
 PersistentVolumeClaim
 &lt;a class="heading-anchor" href="#persistentvolumeclaim" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="persistentvolumeclaim-생성-파일-작성"&gt;
 PersistentVolumeClaim 생성 파일 작성
 &lt;a class="heading-anchor" href="#persistentvolumeclaim-%ec%83%9d%ec%84%b1-%ed%8c%8c%ec%9d%bc-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi pvc.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PersistentVolumeClaim&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgres-13-ansible-awx-postgres-13-0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;awx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClassName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local-storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteOnce&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10Gi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="persistentvolumeclaim-생성-및-확인"&gt;
 PersistentVolumeClaim 생성 및 확인
 &lt;a class="heading-anchor" href="#persistentvolumeclaim-%ec%83%9d%ec%84%b1-%eb%b0%8f-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create -f pvc.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pvc -n awx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="awx-instance-배포---admin-password-없이-setting"&gt;
 AWX instance 배포 - admin password 없이 Setting
 &lt;a class="heading-anchor" href="#awx-instance-%eb%b0%b0%ed%8f%ac---admin-password-%ec%97%86%ec%9d%b4-setting" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="instance-생성-파일-작성"&gt;
 Instance 생성 파일 작성
 &lt;a class="heading-anchor" href="#instance-%ec%83%9d%ec%84%b1-%ed%8c%8c%ec%9d%bc-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi ansible-awx.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;awx.ansible.com/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;AWX&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ansible-awx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;awx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nodeport&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;postgres_storage_class&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local-storage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# projects_persistence: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# projects_storage_access_mode: ReadWriteOnce&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="instance-배포"&gt;
 Instance 배포
 &lt;a class="heading-anchor" href="#instance-%eb%b0%b0%ed%8f%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create -f ansible-awx.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="instance-확인"&gt;
 Instance 확인
 &lt;a class="heading-anchor" href="#instance-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods -n awx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="awx-web-접속"&gt;
 AWX Web 접속
 &lt;a class="heading-anchor" href="#awx-web-%ec%a0%91%ec%86%8d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="service-없을-시-아래와-같이-생성"&gt;
 service 없을 시 아래와 같이 생성
 &lt;a class="heading-anchor" href="#service-%ec%97%86%ec%9d%84-%ec%8b%9c-%ec%95%84%eb%9e%98%ec%99%80-%ea%b0%99%ec%9d%b4-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl expose deployment ansible-awx-web --name ansible-awx-web-svc --type NodePort -n awx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;service 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get svc ansible-awx-web-svc -n awx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="기본적으로-관리자는-admin이고-비밀번호는--admin-password-확인할-수-있다"&gt;
 기본적으로 관리자는 admin이고 비밀번호는 &lt;resourcename&gt;-admin-password 확인할 수 있다.
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8%ec%a0%81%ec%9c%bc%eb%a1%9c-%ea%b4%80%eb%a6%ac%ec%9e%90%eb%8a%94-admin%ec%9d%b4%ea%b3%a0-%eb%b9%84%eb%b0%80%eb%b2%88%ed%98%b8%eb%8a%94--admin-password-%ed%99%95%ec%9d%b8%ed%95%a0-%ec%88%98-%ec%9e%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get secrets -n awx &lt;span class="p"&gt;|&lt;/span&gt; grep -i admin-password&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get secret ansible-awx-admin-password -o &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{.data.password}&amp;#34;&lt;/span&gt; -n awx &lt;span class="p"&gt;|&lt;/span&gt; base64 --decode &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;or
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;kubectl -n awx get secret ansible-awx-admin-password -o go-template&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{{range $k,$v := .data}}{{printf &amp;#34;%s: &amp;#34; $k}}{{if not $v}}{{$v}}{{else}}{{$v | base64decode}}{{end}}{{&amp;#34;\n&amp;#34;}}{{end}}&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Paasword 설정하지 않았을 때 아래와 같이 Secret 조회가 된다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get secret -n awx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;NAME TYPE DATA AGE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;sh.helm.release.v1.ansible-awx-operator.v1 helm.sh/release.v1 &lt;span class="m"&gt;1&lt;/span&gt; 33m
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;redhat-operators-pull-secret Opaque &lt;span class="m"&gt;1&lt;/span&gt; 25m
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;ansible-awx-app-credentials Opaque &lt;span class="m"&gt;3&lt;/span&gt; 24m
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;ansible-awx-admin-password Opaque &lt;span class="m"&gt;1&lt;/span&gt; 24m
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;ansible-awx-secret-key Opaque &lt;span class="m"&gt;1&lt;/span&gt; 24m
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;ansible-awx-postgres-configuration Opaque &lt;span class="m"&gt;6&lt;/span&gt; 24m
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;ansible-awx-broadcast-websocket Opaque &lt;span class="m"&gt;1&lt;/span&gt; 24m
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;ansible-awx-receptor-ca kubernetes.io/tls &lt;span class="m"&gt;2&lt;/span&gt; 24m
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;ansible-awx-receptor-work-signing Opaque &lt;span class="m"&gt;2&lt;/span&gt; 24m&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="awx-instance-배포---admin-password-없이-setting-1"&gt;
 AWX instance 배포 - admin password 없이 Setting
 &lt;a class="heading-anchor" href="#awx-instance-%eb%b0%b0%ed%8f%ac---admin-password-%ec%97%86%ec%9d%b4-setting-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="instance-secret-파일-작성"&gt;
 Instance Secret 파일 작성
 &lt;a class="heading-anchor" href="#instance-secret-%ed%8c%8c%ec%9d%bc-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi awx-admin-password.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Secret&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;awx-admin-password&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;awx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;stringData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysuperlongpassword&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="instance-secret-배포"&gt;
 Instance Secret 배포
 &lt;a class="heading-anchor" href="#instance-secret-%eb%b0%b0%ed%8f%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f awx-admin-password.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="instance-생성-파일-작성-1"&gt;
 Instance 생성 파일 작성
 &lt;a class="heading-anchor" href="#instance-%ec%83%9d%ec%84%b1-%ed%8c%8c%ec%9d%bc-%ec%9e%91%ec%84%b1-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi ansible-awx.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;awx.ansible.com/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;AWX&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ansible-awx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;awx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nodeport&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;postgres_storage_class&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local-path&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;admin_user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;admin&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;admin_password_secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;awx-admin-password&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# projects_persistence: true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# projects_storage_access_mode: ReadWriteOnce&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="instance-배포-1"&gt;
 Instance 배포
 &lt;a class="heading-anchor" href="#instance-%eb%b0%b0%ed%8f%ac-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create -f ansible-awx.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="paasword-설정했을-시-아래와-같이-secret-조회가-된다"&gt;
 Paasword 설정했을 시 아래와 같이 Secret 조회가 된다.
 &lt;a class="heading-anchor" href="#paasword-%ec%84%a4%ec%a0%95%ed%96%88%ec%9d%84-%ec%8b%9c-%ec%95%84%eb%9e%98%ec%99%80-%ea%b0%99%ec%9d%b4-secret-%ec%a1%b0%ed%9a%8c%ea%b0%80-%eb%90%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get secret -n awx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;NAME TYPE DATA AGE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;sh.helm.release.v1.ansible-awx-operator.v1 helm.sh/release.v1 &lt;span class="m"&gt;1&lt;/span&gt; 63m
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;awx-admin-password Opaque &lt;span class="m"&gt;1&lt;/span&gt; 2m7s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;redhat-operators-pull-secret Opaque &lt;span class="m"&gt;1&lt;/span&gt; 90s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;ansible-awx-secret-key Opaque &lt;span class="m"&gt;1&lt;/span&gt; 87s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;ansible-awx-broadcast-websocket Opaque &lt;span class="m"&gt;1&lt;/span&gt; 86s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;ansible-awx-postgres-configuration Opaque &lt;span class="m"&gt;6&lt;/span&gt; 84s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;ansible-awx-receptor-ca kubernetes.io/tls &lt;span class="m"&gt;2&lt;/span&gt; 73s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;ansible-awx-receptor-work-signing Opaque &lt;span class="m"&gt;2&lt;/span&gt; 71s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;ansible-awx-app-credentials Opaque &lt;span class="m"&gt;3&lt;/span&gt; 70s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[InfluxDB] InfluxDB</title><link>https://kyungryeol-yoon.github.io/database/influxdb/influxdb/</link><pubDate>Thu, 25 Jan 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/influxdb/influxdb/</guid><description>&lt;h2 id="influxdb란"&gt;
 InfluxDB란?
 &lt;a class="heading-anchor" href="#influxdb%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Influx DB란 많은 쓰기 작업과 쿼리 부하를 처리하기 위해 **2013년에 Go 언어로 개발된 오픈소스 Time Series Database(시계열 데이터베이스)**로써 Tick Stack(Telegraf + InfluxDB + Chronograf + Kapacitor)의 필수 컴포넌트 중 하나이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Influx DB는 많은 TSDB들(Prometheus, TimescaleDB, Graphite, 등) 중에서 가장 유명하고, 많이 사용되는 데이터베이스이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Influx DB는 Distributed, Scale horizontally하게 설계되어 새로운 노드만 추가하면 손쉽게 scale-out할 수 있으며, Restful API를 제공하고 있어 API 통신이 가능하다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TICK Stack이란 InfluxData에서 나온 4가지 오픈소스 컴포넌트들을 기반으로 구축한 시스템이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;4가지 컴포넌트들은 조합되어 모니터링할 데이터를 수집하여 저장하고, 알림을 보낸다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Telegraf&lt;/strong&gt; : Metrics와 Events를 수집하고 리포팅하는 모듈&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;InfluxDB&lt;/strong&gt; : Time Series DB(시계열 데이터베이스)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kapacitor&lt;/strong&gt; : Real-time 스트리밍 데이터 전송 엔진&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chronograf&lt;/strong&gt; : 시각화 도구&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Concepts 참고&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;InfluxDB v1&lt;/strong&gt; : &lt;a href="https://docs.influxdata.com/influxdb/v1/concepts/key_concepts/"&gt;https://docs.influxdata.com/influxdb/v1/concepts/key_concepts/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;InfluxDB v2&lt;/strong&gt; : &lt;a href="https://docs.influxdata.com/influxdb/v2/reference/key-concepts/"&gt;https://docs.influxdata.com/influxdb/v2/reference/key-concepts/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Glossary 참고&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;InfluxDB v1&lt;/strong&gt; : &lt;a href="https://docs.influxdata.com/influxdb/v1/concepts/glossary/"&gt;https://docs.influxdata.com/influxdb/v1/concepts/glossary/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;InfluxDB v2&lt;/strong&gt; : &lt;a href="https://docs.influxdata.com/influxdb/v2/reference/glossary/"&gt;https://docs.influxdata.com/influxdb/v2/reference/glossary/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="influxdb는-2가지-핵심-기능"&gt;
 InfluxDB는 2가지 핵심 기능
 &lt;a class="heading-anchor" href="#influxdb%eb%8a%94-2%ea%b0%80%ec%a7%80-%ed%95%b5%ec%8b%ac-%ea%b8%b0%eb%8a%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Continuous Query(Task)&lt;/strong&gt; : 일정 주기마다 데이터를 처리하여 새롭게 저장하는 기능
&lt;ul&gt;
&lt;li&gt;InfluxDB의 핵심 목적은 시간에 따른 데이터(시계열 데이터)의 처리이다.&lt;/li&gt;
&lt;li&gt;InfluxDB는 데이터를 처리하여 새롭게 저장하는 Down Sampling(다운 샘플링)을 일정 주기마다 실행되도록 하는 Continous Query(연속적인 쿼리)를 제공하고 있다.&lt;/li&gt;
&lt;li&gt;InfluxDB2에서는 Continous Query를 대체하는 Task를 제공하고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Retention Policy(Retention Period)&lt;/strong&gt; : 일정 주기마다 데이터를 자동으로 삭제하는 기능
&lt;ul&gt;
&lt;li&gt;Influx DB의 핵심 목적은 시간에 따른 데이터의 삽입과 조회이므로 직접 Delete를 이용하는 경우는 거의 없다.&lt;/li&gt;
&lt;li&gt;하지만 데이터가 계속해서 쌓이면 저장 공간 및 처리 속도 등에 문제가 생기므로 데이터를 자동으로 삭제해주는 Retention Policy(보존 정책)를 지원하고 있다.&lt;/li&gt;
&lt;li&gt;Retention Policy란 오래된 데이터를 자동으로 삭제해주는 정책으로써 데이터베이스 단위로 정의되며 일반적으로 1개의 데이터베이스는 여러 개의 보존 정책을 가지고 있다.&lt;/li&gt;
&lt;li&gt;만약 별도의 설정을 하지 않았다면 autogen이라는 기본 정책으로 적용된다.&lt;/li&gt;
&lt;li&gt;autogen은 보존 기간이 무제한이므로, 별도의 설정을 해주지 않으면 데이터가 계속해서 쌓이고 문제를 일으키게 된다.&lt;/li&gt;
&lt;li&gt;그러므로 별도의 설정을 해줌으로써 오래된 데이터들을 관리하는 작업이 필요하다.&lt;/li&gt;
&lt;li&gt;InfluxDB2에서는 Retention Policy를 대체하는 Retention Period를 제공하고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="retention-policy"&gt;
 RETENTION POLICY
 &lt;a class="heading-anchor" href="#retention-policy" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;RETENTION POLICY 생성
&lt;ul&gt;
&lt;li&gt;데이터베이스를 만들 때 InfluxDB는 무제한 보유 권한을 갖는 autogen이라는 보존 정책을 자동으로 생성한다.&lt;/li&gt;
&lt;li&gt;보존 정책의 이름을 바꾸거나 구성 파일에서 자동 생성을 비활성화 할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="보존-정책을-작성-변경-및-삭제하는-방법"&gt;
 보존 정책을 작성, 변경 및 삭제하는 방법
 &lt;a class="heading-anchor" href="#%eb%b3%b4%ec%a1%b4-%ec%a0%95%ec%b1%85%ec%9d%84-%ec%9e%91%ec%84%b1-%eb%b3%80%ea%b2%bd-%eb%b0%8f-%ec%82%ad%ec%a0%9c%ed%95%98%eb%8a%94-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;CREATE RETENTION POLICY &amp;lt;retention_policy_name&amp;gt; ON &amp;lt;database_name&amp;gt; DURATION &amp;lt;duration&amp;gt; REPLICATION &amp;lt;n&amp;gt; [SHARD DURATION &amp;lt;duration&amp;gt;] [DEFAULT]&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="duration"&gt;
 DURATION
 &lt;a class="heading-anchor" href="#duration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;DURATION 절은 InfluxDB가 데이터를 보관하는 기간을 결정한다.&lt;/li&gt;
&lt;li&gt;Duration은 기간 리터럴 또는 INF (무제한)이다.
&lt;ul&gt;
&lt;li&gt;기간 리터럴로 설정하며 Max : INF , Min : 1시간&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;보존 정책의 최소 기간은 1 시간이고 최대 기간은 무제한이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="replication"&gt;
 REPLICATION
 &lt;a class="heading-anchor" href="#replication" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;REPLICATION절은 클러스터에 저장된 각 POINT의 독립 사본 수를 결정한다.&lt;/li&gt;
&lt;li&gt;여기서 n은 데이터 노드 수이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="shard-duration"&gt;
 SHARD DURATION
 &lt;a class="heading-anchor" href="#shard-duration" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;SHARD DURATION 절은 SHARD 그룹이 적용되는 시간 범위를 결정한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(선택사항)&lt;/code&gt;Duration은 지속 시간 리터럴이며 INF (무한) 기간을 지원하지 않는다.&lt;/li&gt;
&lt;li&gt;기본적으로 SHARD 그룹 기간은 RETENTION POLICY의 DURATION에 의해 결정된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;Retention Policy’s DURATION&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Shard Group Duration&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&amp;lt; 2 days&lt;/td&gt;
					&lt;td style="text-align: left"&gt;1 hour&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&amp;gt;= 2 days and &amp;lt;= 6 months&lt;/td&gt;
					&lt;td style="text-align: left"&gt;1 day&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&amp;gt; 6 months&lt;/td&gt;
					&lt;td style="text-align: left"&gt;7 days&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;허용 가능한 최소 SHARD GROUP DURATION은 1시간이다.&lt;/li&gt;
&lt;li&gt;CREATE RETENTION POLICY 쿼리가 SHARD GROUP DURATION을 1시간 미만으로, 0보다 큰 값으로 설정하려고 시도하면 InfluxDB는 자동으로 SHARD GROUP DURATION을 1h로 설정한다.&lt;/li&gt;
&lt;li&gt;CREATE RETENTION POLICY 쿼리가 SHARD GROUP DURATION을 0으로 설정하려고 시도하면 InfluxDB는 위에 나열된 기본 설정에 따라 SHARD GROUP DURATION을 자동으로 설정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="default"&gt;
 DEFAULT
 &lt;a class="heading-anchor" href="#default" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;(선택사항)&lt;/code&gt;새로운 retention policy을 데이터베이스의 기본 retention policy로 설정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="example"&gt;
 EXAMPLE
 &lt;a class="heading-anchor" href="#example" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Ex1. retention policy 생성&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;CREATE RETENTION POLICY &amp;#34;one_day_only&amp;#34; ON &amp;#34;TEST_water_database&amp;#34; DURATION 1d REPLICATION 1&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;이 쿼리는 데이터베이스 TEST_water_database에 대해 one_day_only라는 retention policy을 생성한다.&lt;/li&gt;
&lt;li&gt;retention policy은 1일의 DURATION과 1개의 REPLICATION 인수를 가진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ex2. DEFAULT retention policy 생성&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;CREATE RETENTION POLICY &amp;#34;one_day_only&amp;#34; ON &amp;#34;TEST_water_database&amp;#34; DURATION 23h60m REPLICATION 1 DEFAULT&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;쿼리는 위의 예와 동일한 보존 정책을 만들고 데이터베이스의 기본 보존 정책으로 설정한다.&lt;/li&gt;
&lt;li&gt;CREATE RETENTION POLICY 쿼리가 성공하면 빈 응답이 반환된다.&lt;/li&gt;
&lt;li&gt;이미 존재하는 것과 동일한 retention policy을 생성하려고 시도하면 InfluxDB가 에러를 리턴하지 않는다.&lt;/li&gt;
&lt;li&gt;기존 retention policy과 이름은 같지만 속성이 다른 retention policy을 만들려고 하면 InfluxDB에서 에러를 반환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;CREATE DATABASE 조회에서 새로운 RETENTION POLICY를 지정할 수도 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="retention-policy-수정"&gt;
 RETENTION POLICY 수정
 &lt;a class="heading-anchor" href="#retention-policy-%ec%88%98%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ALTER RETENTION POLICY 쿼리는 DURATION, REPLICATION, SHARD DURATION 또는 DEFAULT 중 적어도 하나의 RETENTION POLICY 속성을 선언해야 한다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ALTER RETENTION POLICY &amp;lt;retention_policy_name&amp;gt; ON &amp;lt;database_name&amp;gt; DURATION &amp;lt;duration&amp;gt; REPLICATION &amp;lt;n&amp;gt; SHARD DURATION &amp;lt;duration&amp;gt; DEFAULT&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;먼저 DURATION이 2일인 RETENTION POLICY what_is_time을 생성한다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;CREATE RETENTION POLICY &amp;#34;what_is_time&amp;#34; ON &amp;#34;TEST_water_database&amp;#34; DURATION 2d REPLICATION 1&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3주 DURATION, 30분 SHARD 그룹 기간이 되도록 what_is_time을 수정하고 TEST_water_database 대한 DEFAULT RETENTION POLICY을 변경한다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ALTER RETENTION POLICY &amp;#34;what_is_time&amp;#34; ON &amp;#34;TEST_water_database&amp;#34; DURATION 3w SHARD DURATION 30m DEFAULT&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;what_is_time은 원래 REPLICATION 인수 1을 유지한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;성공적인 ALTER RETENTION POLICY 쿼리는 빈 결과를 반환한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="retention-policy-삭제"&gt;
 RETENTION POLICY 삭제
 &lt;a class="heading-anchor" href="#retention-policy-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;DROP RETENTION POLICY &amp;lt;retention_policy_name&amp;gt; ON &amp;lt;database_name&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;TEST_water_database 데이터베이스에서 RETENTION POLICY인 what_is_time을 삭제한다.
&lt;pre tabindex="0"&gt;&lt;code&gt;DROP RETENTION POLICY &amp;#34;what_is_time&amp;#34; ON &amp;#34;TEST_water_database&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;성공적인 DROP RETENTION POLICY 쿼리는 빈 결과를 반환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;존재하지 않는 RETENTION POLICY을 삭제하려고 하면 InfluxDB에서 에러를 반환하지는 않는다.
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="influxdb-config-file-설정"&gt;
 InfluxDB Config file 설정
 &lt;a class="heading-anchor" href="#influxdb-config-file-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;InfluxDB 상에서 기본 설정들을 바꿔주기 위해서는 Influxdb.config 파일을 수정해야 한다.&lt;/li&gt;
&lt;li&gt;파일을 수정한 뒤 InfluxDB의 시스템 상에서 수정된 설정을 적용하기 위해서는 2가지 방식이 있다.
&lt;ol&gt;
&lt;li&gt;conf 파일을 수정한 뒤 influxd를 실행할 때 마다 conf 파일 위치를 인자로 주어 프로세스가 구성 파일을 가리키도록 설정하는 방식
&lt;pre tabindex="0"&gt;&lt;code class="language-conf" data-lang="conf"&gt;influxd -config /etc/influxdb/influxdb.conf&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;환경 변수를 설정하여 구성 파일의 경로를 설정하여 influxd가 적용되어 실행하도록 하는 방식
&lt;pre tabindex="0"&gt;&lt;code class="language-conf" data-lang="conf"&gt;echo $INFLUXDB_CONFIG_PATH
/etc/influxdb/influxdb.conf

influxd&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="influxconfig-설정-가능한-옵션"&gt;
 Influx.config 설정 가능한 옵션
 &lt;a class="heading-anchor" href="#influxconfig-%ec%84%a4%ec%a0%95-%ea%b0%80%eb%8a%a5%ed%95%9c-%ec%98%b5%ec%85%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;InfluxDB는 구성 파일(influxdb.conf)과 환경 변수를 사용하여 구성&lt;/li&gt;
&lt;li&gt;구성 옵션의 주석 처리를 해제하지 않으면 시스템은 기본 설정을 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;Option&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Description&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;[meta]&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;사용자, 데이터베이스, 보존 정책, 샤드 및 연속 쿼리에 대한 정보를 저장하는 InfluxDB 메타스토어에 대한 매개변수를 제어&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;[data]&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;InfluxDB의 실제 샤드 데이터가 있는 위치와 WAL(Write-Ahead Log)에서 데이터를 플러시하는 방법을 제어&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;[coordinator]&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;쿼리 관리를 위한 구성 설정이 포함&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;[retention]&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;보존 정책 설정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;[shard-precreation]&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;샤드 생성 서비스 설정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;[monitor]&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;influx 시스템 자체의 모니터링에 대한 설정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;[http]&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;http관련 인증 및 엔드포인트 설정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;[logging]&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;로거가 로그를 출력으로 내보는 방식을 설정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;[subscriber]&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;kapacitor( 데이터 처리 오픈소스 ) 가 데이터를 수신하는 방식을 제어&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;[[graphite]]&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;graphite 데이터에 대한 리스너 설정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;[[collectd]]&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;수집된 데이터에 대한 리스너 제어&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;[[opentsdb]]&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;OpenTSDB 데이터 수신기를 제어&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;[[udp]]&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;udp 설정 제어&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;[Continuous_queries]&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;연속 쿼리(CQ)에 대한 방식을 제어&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;[tls]&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;전송 계층 보안 설정&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;Config 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://docs.influxdata.com/influxdb/v1/administration/config/"&gt;https://docs.influxdata.com/influxdb/v1/administration/config/&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Influx config에서 retenton policy 설정&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-conf" data-lang="conf"&gt;[retention]

[1] enabled = true/false
InfluxDB가 보존 정책을 시행할지 안할지 결정
(환경 변수 : INFLUXDB_RETENTION_ENABLED)

[2] check-interval = &amp;#34;30m0s&amp;#34;
InfluxDB가 보존 정책을 실행할지 여부를 체크하는 시간 간격
(환경 변수:INFLUXDB_RETENTION_CHECK_INTERVAL)&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Error] kubectl commands error - the server is currently unable to handle the request</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/the-server-is-currently-unable-to-handle-the-requests/</link><pubDate>Sun, 14 Jan 2024 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/the-server-is-currently-unable-to-handle-the-requests/</guid><description>&lt;h2 id="the-server-is-currently-unable-to-handle-the-request-오류-해결법"&gt;
 The server is currently unable to handle the request 오류 해결법
 &lt;a class="heading-anchor" href="#the-server-is-currently-unable-to-handle-the-request-%ec%98%a4%eb%a5%98-%ed%95%b4%ea%b2%b0%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;kubectl 명령어를 입력하면 다음 오류 메시지가 발생하는 경우가 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;couldn&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;t get resource list &lt;span class="k"&gt;for&lt;/span&gt; metrics.k8s.io/v1beta1: the server is currently unable to handle the request
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;or
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;Error from server &lt;span class="o"&gt;(&lt;/span&gt;ServiceUnavailable&lt;span class="o"&gt;)&lt;/span&gt;: the server is currently unable to handle the request &lt;span class="o"&gt;(&lt;/span&gt;get nodes.metrics.k8s.io&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;E0804 15:08:38.034678 &lt;span class="m"&gt;2567&lt;/span&gt; memcache.go:287&lt;span class="o"&gt;]&lt;/span&gt; couldn&lt;span class="s1"&gt;&amp;#39;t get resource list for metrics.k8s.io/v1beta1: the server is currently unable to handle the request
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;E0804 15:08:38.386072 2567 memcache.go:121] couldn&amp;#39;&lt;/span&gt;t get resource list &lt;span class="k"&gt;for&lt;/span&gt; metrics.k8s.io/v1beta1: the server is currently unable to handle the request
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;E0804 15:08:38.452142 &lt;span class="m"&gt;2567&lt;/span&gt; memcache.go:121&lt;span class="o"&gt;]&lt;/span&gt; couldn&lt;span class="s1"&gt;&amp;#39;t get resource list for metrics.k8s.io/v1beta1: the server is currently unable to handle the request
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;E0804 15:08:38.614993 2567 memcache.go:121] couldn&amp;#39;&lt;/span&gt;t get resource list &lt;span class="k"&gt;for&lt;/span&gt; metrics.k8s.io/v1beta1: the server is currently unable to handle the request&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="이-문제는-다음-deploy-수정하면-해결"&gt;
 이 문제는 다음 deploy 수정하면 해결
 &lt;a class="heading-anchor" href="#%ec%9d%b4-%eb%ac%b8%ec%a0%9c%eb%8a%94-%eb%8b%a4%ec%9d%8c-deploy-%ec%88%98%ec%a0%95%ed%95%98%eb%a9%b4-%ed%95%b4%ea%b2%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl edit deploy -n kube-system metrics-server 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;dnsPolicy: ClusterFirst
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;hostNetwork: &lt;span class="nb"&gt;true&lt;/span&gt; &amp;lt;&amp;lt; 추가
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;nodeSelector:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; kubernetes.io/os: linux&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Linux] 🔐 pam_tally2로 로그인 실패 제한 및 계정 잠금 설정하기</title><link>https://kyungryeol-yoon.github.io/linux/system/linux-pam-tally2-account-lockout/</link><pubDate>Tue, 26 Dec 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/system/linux-pam-tally2-account-lockout/</guid><description>&lt;p&gt;리눅스 서버에서 비밀번호를 무한 반복 시도하는 브루트포스(Brute-force) 공격은 가장 기초적이면서도 빈번한 위협입니다.
&lt;strong&gt;PAM(Pluggable Authentication Modules)&lt;/strong&gt; 의 &lt;code&gt;pam_tally2&lt;/code&gt; 모듈을 사용하면 로그인 실패 횟수를 추적하고, 임계값 초과 시 계정을 자동으로 잠글 수 있습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;code&gt;pam_tally2&lt;/code&gt;는 &lt;strong&gt;Deprecated&lt;/strong&gt; 상태입니다. RHEL 8 / CentOS 8 이상 또는 최신 Ubuntu 환경에서는 &lt;code&gt;pam_faillock&lt;/code&gt;을 사용하는 것이 권장됩니다. 이 포스트는 두 가지 모두 다룹니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-pam이란"&gt;
 🧩 PAM이란?
 &lt;a class="heading-anchor" href="#-pam%ec%9d%b4%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;PAM은 리눅스의 인증 프레임워크로, 애플리케이션이 인증 방식을 직접 구현하지 않아도 되도록 &lt;strong&gt;모듈 방식으로 인증 기능을 제공&lt;/strong&gt;합니다.
&lt;code&gt;/etc/pam.d/&lt;/code&gt; 디렉토리 아래에 서비스별 설정 파일이 위치합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;/etc/pam.d/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;├── sshd # SSH 서비스 인증 설정
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;├── login # 로컬 콘솔 로그인 인증 설정
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;├── password-auth # 패스워드 기반 인증 공통 설정 (RHEL/CentOS)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;└── system-auth # 시스템 인증 공통 설정 (RHEL/CentOS)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;PAM 설정은 4가지 타입(&lt;code&gt;auth&lt;/code&gt;, &lt;code&gt;account&lt;/code&gt;, &lt;code&gt;password&lt;/code&gt;, &lt;code&gt;session&lt;/code&gt;)으로 구성되며,
&lt;code&gt;pam_tally2&lt;/code&gt;는 주로 &lt;code&gt;auth&lt;/code&gt;와 &lt;code&gt;account&lt;/code&gt; 타입에 적용됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-pam_tally2-설정하기-rhel-7--centos-7"&gt;
 🔒 pam_tally2 설정하기 (RHEL 7 / CentOS 7)
 &lt;a class="heading-anchor" href="#-pam_tally2-%ec%84%a4%ec%a0%95%ed%95%98%ea%b8%b0-rhel-7--centos-7" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="etcpamdpassword-auth-설정"&gt;
 /etc/pam.d/password-auth 설정
 &lt;a class="heading-anchor" href="#etcpamdpassword-auth-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;SSH 로그인 실패 제한을 적용하려면 아래와 같이 설정합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;# /etc/pam.d/password-auth
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;auth required pam_tally2.so deny=5 unlock_time=1800 no_magic_root reset
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;auth required pam_env.so
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;auth sufficient pam_unix.so nullok try_first_pass
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;auth requisite pam_succeed_if.so uid &amp;gt;= 1000 quiet_success
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;auth required pam_deny.so
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;account required pam_tally2.so no_magic_root
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;account required pam_unix.so
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;account sufficient pam_localuser.so&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="etcpamdsystem-auth-설정"&gt;
 /etc/pam.d/system-auth 설정
 &lt;a class="heading-anchor" href="#etcpamdsystem-auth-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;로컬 콘솔 로그인에도 동일하게 적용하려면 &lt;code&gt;system-auth&lt;/code&gt; 파일에도 추가합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;# /etc/pam.d/system-auth
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;auth required pam_tally2.so deny=5 unlock_time=1800 no_magic_root reset
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;auth required pam_env.so
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;auth sufficient pam_unix.so nullok try_first_pass&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: &lt;code&gt;password-auth&lt;/code&gt;는 SSH 등 원격 접속, &lt;code&gt;system-auth&lt;/code&gt;는 로컬 콘솔 접속에 적용됩니다. 두 파일 모두 수정해야 완전한 적용이 됩니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-주요-옵션-설명"&gt;
 ⚙️ 주요 옵션 설명
 &lt;a class="heading-anchor" href="#-%ec%a3%bc%ec%9a%94-%ec%98%b5%ec%85%98-%ec%84%a4%eb%aa%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;옵션&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;deny=N&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;N회 실패 시 계정 잠금 (예: &lt;code&gt;deny=5&lt;/code&gt;는 5회 실패 시 잠금)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;unlock_time=N&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;N초 후 자동 잠금 해제 (예: &lt;code&gt;unlock_time=1800&lt;/code&gt;은 30분). 생략 시 영구 잠금&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;no_magic_root&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;root 계정은 잠금 대상에서 제외&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;reset&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;로그인 성공 시 실패 횟수를 0으로 초기화&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;onerr=fail&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;PAM 모듈 오류 발생 시 인증 실패로 처리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;even_deny_root&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;root 계정도 잠금 대상에 포함 (보안 강화 시 사용)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-pam_tally2-명령어-사용법"&gt;
 🛠️ pam_tally2 명령어 사용법
 &lt;a class="heading-anchor" href="#-pam_tally2-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="실패-횟수-조회"&gt;
 실패 횟수 조회
 &lt;a class="heading-anchor" href="#%ec%8b%a4%ed%8c%a8-%ed%9a%9f%ec%88%98-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pam_tally2 -u &lt;span class="o"&gt;[&lt;/span&gt;계정명&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 예시&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;pam_tally2 -u testuser
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Login Failures Latest failure From&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# testuser 5 04/26/26 10:30:00 192.168.1.100&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="계정-잠금-해제-실패-횟수-초기화"&gt;
 계정 잠금 해제 (실패 횟수 초기화)
 &lt;a class="heading-anchor" href="#%ea%b3%84%ec%a0%95-%ec%9e%a0%ea%b8%88-%ed%95%b4%ec%a0%9c-%ec%8b%a4%ed%8c%a8-%ed%9a%9f%ec%88%98-%ec%b4%88%ea%b8%b0%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pam_tally2 -u &lt;span class="o"&gt;[&lt;/span&gt;계정명&lt;span class="o"&gt;]&lt;/span&gt; -r&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 예시&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;pam_tally2 -u testuser -r
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Login Failures Latest failure From&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# testuser 0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;-r&lt;/code&gt; (&lt;code&gt;--reset&lt;/code&gt;) 옵션을 사용하면 실패 횟수가 0으로 초기화되어 즉시 잠금이 해제됩니다.&lt;/p&gt;
&lt;h3 id="전체-계정-실패-현황-조회"&gt;
 전체 계정 실패 현황 조회
 &lt;a class="heading-anchor" href="#%ec%a0%84%ec%b2%b4-%ea%b3%84%ec%a0%95-%ec%8b%a4%ed%8c%a8-%ed%98%84%ed%99%a9-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pam_tally2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;옵션 없이 실행하면 로그인 실패 이력이 있는 모든 계정 목록을 출력합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-설정-적용-확인"&gt;
 🔎 설정 적용 확인
 &lt;a class="heading-anchor" href="#-%ec%84%a4%ec%a0%95-%ec%a0%81%ec%9a%a9-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;계정이 실제로 잠겼는지 테스트하려면 아래 순서로 확인합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 테스트 계정 잠금 유발 (5회 틀린 패스워드 입력 후)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;ssh testuser@localhost &lt;span class="c1"&gt;# 5회 실패&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 잠금 상태 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;pam_tally2 -u testuser
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Failures: 5 (이상이면 잠금 상태)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. 관리자가 수동으로 잠금 해제&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;pam_tally2 -u testuser -r&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ root 계정으로 &lt;code&gt;pam_tally2 -r&lt;/code&gt; 명령을 실행해야 합니다. 일반 계정으로 실행 시 권한 오류가 발생합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-최신-대안-pam_faillock-rhel-8--centos-8-이상"&gt;
 🆕 최신 대안: pam_faillock (RHEL 8 / CentOS 8 이상)
 &lt;a class="heading-anchor" href="#-%ec%b5%9c%ec%8b%a0-%eb%8c%80%ec%95%88-pam_faillock-rhel-8--centos-8-%ec%9d%b4%ec%83%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;pam_tally2&lt;/code&gt;는 RHEL 8부터 공식 Deprecated 처리되었고, &lt;strong&gt;&lt;code&gt;pam_faillock&lt;/code&gt;&lt;/strong&gt; 이 대체 모듈입니다.
사용법은 유사하지만 설정 방식이 다릅니다.&lt;/p&gt;
&lt;h3 id="etcpamdsshd-설정"&gt;
 /etc/pam.d/sshd 설정
 &lt;a class="heading-anchor" href="#etcpamdsshd-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;auth required pam_faillock.so preauth silent audit deny=5 unlock_time=600
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;auth [success=1 default=bad] pam_unix.so nullok
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;auth [default=die] pam_faillock.so authfail audit deny=5 unlock_time=600
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;auth sufficient pam_faillock.so authsucc audit deny=5 unlock_time=600
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;account required pam_faillock.so&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="pam_faillock-명령어"&gt;
 pam_faillock 명령어
 &lt;a class="heading-anchor" href="#pam_faillock-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 실패 횟수 조회&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;faillock --user &lt;span class="o"&gt;[&lt;/span&gt;계정명&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 계정 잠금 해제&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;faillock --user &lt;span class="o"&gt;[&lt;/span&gt;계정명&lt;span class="o"&gt;]&lt;/span&gt; --reset&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="pam_tally2-vs-pam_faillock-비교"&gt;
 pam_tally2 vs pam_faillock 비교
 &lt;a class="heading-anchor" href="#pam_tally2-vs-pam_faillock-%eb%b9%84%ea%b5%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;pam_tally2&lt;/th&gt;
					&lt;th&gt;pam_faillock&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;지원 OS&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;RHEL 6~7, 구버전&lt;/td&gt;
					&lt;td&gt;RHEL 8+, 최신 Ubuntu&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;상태&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Deprecated&lt;/td&gt;
					&lt;td&gt;현재 권장&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;명령어&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;pam_tally2 -u&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;faillock --user&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;잠금 해제&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;pam_tally2 -u USER -r&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;faillock --user USER --reset&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;설정 복잡도&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;단순&lt;/td&gt;
					&lt;td&gt;다소 복잡&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-요약"&gt;
 ✅ 요약
 &lt;a class="heading-anchor" href="#-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;pam_tally2&lt;/code&gt;는 &lt;code&gt;/etc/pam.d/password-auth&lt;/code&gt; 및 &lt;code&gt;system-auth&lt;/code&gt;에 &lt;code&gt;auth required&lt;/code&gt;와 &lt;code&gt;account required&lt;/code&gt; 두 줄씩 추가합니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;deny=5 unlock_time=1800 no_magic_root reset&lt;/code&gt;이 가장 일반적인 설정입니다.&lt;/li&gt;
&lt;li&gt;계정 잠금 해제는 &lt;code&gt;pam_tally2 -u [계정명] -r&lt;/code&gt;로 수행합니다.&lt;/li&gt;
&lt;li&gt;RHEL 8 / CentOS 8 이상 환경에서는 &lt;code&gt;pam_faillock&lt;/code&gt;과 &lt;code&gt;faillock&lt;/code&gt; 명령어를 사용하세요.&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>[PostgreSQL] Back up 및 Recovery 방법</title><link>https://kyungryeol-yoon.github.io/database/postgresql/postgresql-backup-recovery-file/</link><pubDate>Tue, 05 Dec 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/postgresql/postgresql-backup-recovery-file/</guid><description>&lt;h2 id="backup-및-recovery-방법"&gt;
 BackUp 및 Recovery 방법
 &lt;a class="heading-anchor" href="#backup-%eb%b0%8f-recovery-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;pg_dumpall -U admin &amp;gt; /var/lib/postgresql/dump/backup_20231205.sql&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;psql -U admin &amp;gt; -f /var/lib/postgresql/dump/backup_20231205.sql testdb&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="l"&gt;/bin/bash&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;- -&lt;span class="l"&gt;c&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; ln -snf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; su
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; cd
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;test-svc.test-ns.svc.cluster.local:5432:postgres:admin:admin1!&amp;#34; &amp;gt; .pgpass
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Save pgpass&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; chmod 600 ~/.pgpass
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; BACKUP_DIR=&amp;#34;/var/lib/postgresql/dump&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; BACKUP_FILE=&amp;#34;(date +&amp;#34;%Y-%m-%d_%H-%M-%S&amp;#34;)_day
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo $BACKUP_FILE
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Start BackUp&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; pg_dump -U admin -w -h test-svc.test-ns.svc.cluster.local -p 5432 -T tb_test -F c postgres &amp;gt; ${BACKUP_DIR}/${BACKUP_FILE}.sql
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Finish BackUp&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Start Compress&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; cd ..
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; tar -zcvf /var/lib/postgresql/$BACKUP_FILE.tar.gz /var/lib/postgresql/$BACKUP_FILE.sql
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Finish Compress&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; rm -rf /var/lib/postgresql/$BACKUP_FILE.sql
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Deleted SQL File&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;pg_restore -U admin -C -Fc -d postgres 20231205010801.sql&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="l"&gt;/bin/bash&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;- -&lt;span class="l"&gt;c&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; ln -snf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; su
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; cd
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;test-svc.test-ns.svc.cluster.local:5432:postgres:admin:admin1!&amp;#34; &amp;gt; .pgpass
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Save pgpass&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; chmod 600 ~/.pgpass
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; BACKUP_DIR=&amp;#34;/backups&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; BACKUP_FILE=&amp;#34;(date +&amp;#34;%Y-%m-%d_%H-%M-%S&amp;#34;)_day
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo $BACKUP_FILE
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Start BackUp&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; pg_dump -U admin -w -h test-svc.test-ns.svc.cluster.local -p 5432 -T tb_test -F c postgres &amp;gt; ${BACKUP_DIR}/${BACKUP_FILE}.sql
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Finish BackUp&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Start Compress&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; cd ..
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; tar -zcvf /backups/$BACKUP_FILE.tar.gz /backups/$BACKUP_FILE.sql
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Finish Compress&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; rm -rf /backups/$BACKUP_FILE.sql
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Deleted SQL File&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[PostgreSQL] Delete Back up File</title><link>https://kyungryeol-yoon.github.io/database/postgresql/postgresql-delete-backup-file/</link><pubDate>Sat, 02 Dec 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/postgresql/postgresql-delete-backup-file/</guid><description>&lt;h2 id="backup-file-삭제-command"&gt;
 BackUp File 삭제 Command
 &lt;a class="heading-anchor" href="#backup-file-%ec%82%ad%ec%a0%9c-command" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="7일-기준"&gt;
 7일 기준
 &lt;a class="heading-anchor" href="#7%ec%9d%bc-%ea%b8%b0%ec%a4%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="l"&gt;/bin/bash&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;- -&lt;span class="l"&gt;c&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; delete_date=$(date -d &amp;#34;7 day ago&amp;#34; +&amp;#34;%Y-%m-%d_%H:%M:%S&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; files=$(find /backups -type f)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; for file in $files; do
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; if [[ $file =~ day ]]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; created=$(stat -c %y $file)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo $created
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; if [[ $created &amp;lt; $ delete_date ]]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;삭제할 파일: $file&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; rm $file
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; done&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="24시간-기준"&gt;
 24시간 기준
 &lt;a class="heading-anchor" href="#24%ec%8b%9c%ea%b0%84-%ea%b8%b0%ec%a4%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="l"&gt;/bin/bash&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;- -&lt;span class="l"&gt;c&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; delete_date=$(date -d &amp;#34;24 hour ago&amp;#34; +&amp;#34;%Y-%m-%d_%H:%M:%S&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; files=$(find /backups -type f)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; for file in $files; do
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; if [[ $file =~ min ]]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; created=$(stat -c %y $file)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo $created
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; if [[ $created &amp;lt; $ delete_date ]]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;삭제할 파일: $file&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; rm $file
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; done&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] kubectl wait command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-wait/</link><pubDate>Wed, 29 Nov 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-wait/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;wait&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt; --for&lt;span class="o"&gt;=[&lt;/span&gt;조건&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;조건 값&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 파드가 Ready 상태가 될 때까지 대기할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;wait&lt;/span&gt; pod my-pod --for&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Ready&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--for&lt;/code&gt;: 대기할 조건을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Ready 조건이 충족될 때까지 대기&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;wait&lt;/span&gt; pod my-pod --for&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Ready&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--timeout&lt;/code&gt;: 대기 시간을 지정. 이 시간을 초과하면 명령어가 종료&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Ready 조건이 충족될 때까지 60초 동안 대기&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;wait&lt;/span&gt; pod my-pod --for&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Ready --timeout&lt;span class="o"&gt;=&lt;/span&gt;60s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--namespace&lt;/code&gt;: Namespace를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-namespace Namespace에 있는 my-pod Pod가 Ready 상태가 될 때까지 대기&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;wait&lt;/span&gt; pod my-pod --for&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Ready --namespace&lt;span class="o"&gt;=&lt;/span&gt;my-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubectl exec command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-exec/</link><pubDate>Tue, 21 Nov 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-exec/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;옵션&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;Pod 이름&lt;span class="o"&gt;]&lt;/span&gt; -- &lt;span class="o"&gt;[&lt;/span&gt;Container 이름&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;명령어&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 Pod 내부에서 /app Directory를 조회할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; my-pod -- ls /app&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--namespace&lt;/code&gt;: Pod가 포함된 Namespace를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-namespace Namespace에 속한 my-pod 이름의 Pod 내부에서 /app Directory를 조회할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; my-pod --namespace my-namespace -- ls /app&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--stdin&lt;/code&gt;, &lt;code&gt;-i&lt;/code&gt;: 컨테이너의 표준 입력을 연결&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 Pod 내부에서 /app Directory를 조회하면서 Container의 표준 입력을 연결&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; my-pod -n &lt;span class="o"&gt;[&lt;/span&gt;namespace&lt;span class="o"&gt;]&lt;/span&gt; -i -- ls /app&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--tty&lt;/code&gt;, &lt;code&gt;-t&lt;/code&gt;: TTY 모드를 사용&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 Pod 내부에서 Bash Shell을 실행하면서 TTY 모드를 사용&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; my-pod -n &lt;span class="o"&gt;[&lt;/span&gt;namespace&lt;span class="o"&gt;]&lt;/span&gt; -t -- bash&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubectl annotate command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-annotate/</link><pubDate>Sun, 19 Nov 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-annotate/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl annotate &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;주석 이름&lt;span class="o"&gt;]=[&lt;/span&gt;주석 값&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 Pod에 description=&amp;#34;This is my pod&amp;#34; 주석을 추가할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl annotate pods my-pod &lt;span class="nv"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;This is my pod&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--overwrite&lt;/code&gt;: 이미 존재하는 주석 값을 덮어쓰기 한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 Pod에 이미 존재하는 description 주석 값을 This is my new pod으로 덮어쓴다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl annotate pods my-pod &lt;span class="nv"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;This is my new pod&amp;#34;&lt;/span&gt; --overwrite&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--namespace&lt;/code&gt;: 리소스가 포함된 Namespace를 지정한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-namespace Namespace에 속한 my-pod 이름의 Pod에 description=&amp;#34;This is my pod&amp;#34; 주석을 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl annotate pods my-pod &lt;span class="nv"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;This is my pod&amp;#34;&lt;/span&gt; --namespace my-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubectl label command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-label/</link><pubDate>Sat, 11 Nov 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-label/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl label &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;Label 이름&lt;span class="o"&gt;]=[&lt;/span&gt;Label 값&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 Pod에 app=my-app Label을 추가할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl label pods my-pod &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my-app&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--overwrite&lt;/code&gt;: 이미 존재하는 Label 값을 덮어쓰기 한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 Pod에 이미 존재하는 app Label 값을 my-new-app으로 덮어쓴다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl label pods my-pod &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my-new-app --overwrite&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--namespace&lt;/code&gt;: 리소스가 포함된 Namespace를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-namespace Namespace에 속한 my-pod 이름의 Pod에 app=my-app Label을 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl label pods my-pod &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my-app --namespace my-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--selector&lt;/code&gt;: Label을 추가할 리소스를 선택&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# app=my-app Label을 가진 모든 Pod에 release=beta Label을 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl label pods --selector &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my-app &lt;span class="nv"&gt;release&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;beta&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Python] Background Tasks</title><link>https://kyungryeol-yoon.github.io/backend/python/python-background-tasks/</link><pubDate>Sun, 05 Nov 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/python/python-background-tasks/</guid><description>&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;서버에서 요청을 처리할 때, 작업이 오래 걸리는 요청에 대해서는 응답을 먼저 보내주고 Background에서 나머지 작업을 수행하도록 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이러한 구조를 위해서 보통은 worker thread를 돌리거나 worker queue 등을 사용하여 다른 쓰레드 또는 프로세스를 통해 Background에서 작업을 수행하도록 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;FastAPI에서는 starlette의 BackgroundTasks를 사용하여 요청에 대한 Background 작업을 실행하는 기능을 제공한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;BackgroundTasks에 추가된 task들은 FastAPI에서 asynchronous 하게 실행한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이를 통해서 오래 걸리는 작업은 Background Task로 등록한 후 response를 먼저 반환하도록 할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="1-backgroundtasks"&gt;
 1. BackgroundTasks
 &lt;a class="heading-anchor" href="#1-backgroundtasks" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;BackgroundTasks는 fastapi 모듈의 BackgroundTasks 클래스를 import하여 사용할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;FastAPI app에서 BackgroundTasks를 사용할 때는 path operation function에서 BackgroundTasks 타입으로 변수를 선언하여 사용할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;FastAPI의 path operation function에서 BackgroundTasks 타입 변수를 선언하는 이유는 fastapi에서 router를 조회하여 arguments를 파싱하는 과정에서 BackgroundTasks 객체를 주입해주기 때문인데 이는 아래에서 좀 더 자세하게 설명한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;BackgroundTasks를 사용하는 코드의 예제는 다음과 같다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;다음의 코드는 POST &lt;code&gt;/send-notification/{email}&lt;/code&gt;로 요청이 왔을때, &lt;code&gt;{&amp;quot;message&amp;quot;: &amp;quot;Notification sent in the background&amp;quot;}&lt;/code&gt;를 response로 먼저 반환하고 실제 notification 전송은 Background에서 실행한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;send_notification 함수는 BackgroundTasks 타입의 background_tasks 변수를 선언하고 이 변수에 write_notification이라는 task를 추가한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이렇게 추가된 task는 reponse 전달 이후 실행된다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BackgroundTasks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;write_notification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;log.txt&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;w&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;email_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;notification for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;email_file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/send-notification/&lt;/span&gt;&lt;span class="si"&gt;{email}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_notification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;background_tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BackgroundTasks&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;background_tasks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;write_notification&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;some notification&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;message&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Notification sent in the background&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="task-function"&gt;
 task function
 &lt;a class="heading-anchor" href="#task-function" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;BackgroundTasks에 추가되는 task function은 parameter를 입력받아 실행되는 일반적인 형태의 함수이다.&lt;/li&gt;
&lt;li&gt;BackgroundTasks에서 실행시에 함수의 타입을 확인하기 때문에 async와 sync 모두 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Callable&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BackgroundTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;BackgroundTasks로 추가하기 위해서는 Background에서 실행할 task function과 arguments들을 add_task 함수로 입력해주면 된다.&lt;/li&gt;
&lt;li&gt;add_task 함수는 아래와 같이 task function 을 입력받는 func 와 task function의 arguments를 입력하는 &lt;code&gt;*args&lt;/code&gt;, &lt;code&gt;**kwargs&lt;/code&gt; 로 이루어져 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;write_notification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;log.txt&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;w&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;email_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;notification for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;email_file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;background_tasks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;write_notification&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;some notification&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;send_notification 의 예제에서는 위와 같이 func로 write_notification 함수를 &lt;code&gt;*args&lt;/code&gt;에 email, &lt;code&gt;**kwargs&lt;/code&gt;에 message=&amp;ldquo;some notification&amp;quot;을 arguments로 입력했다.&lt;/li&gt;
&lt;li&gt;이렇게 입력된 값들은 Background에서 다음과 같이 실행된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;write_notification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;some notification&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;func로 입력된 write_notification에 email과 &amp;ldquo;some notification&amp;rdquo; 이 arguments로 입력되어 실행된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2-fastapi와-backgroundtasks-구조"&gt;
 2. FastAPI와 BackgroundTasks 구조
 &lt;a class="heading-anchor" href="#2-fastapi%ec%99%80-backgroundtasks-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="backgroundtask와-backgroundtasks"&gt;
 BackgroundTask와 BackgroundTasks
 &lt;a class="heading-anchor" href="#backgroundtask%ec%99%80-backgroundtasks" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;BackgroundTasks의 클래스 구조는 다음과 같다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;FastAPI는 starlette 프레임워크에 구현된 background 모듈을 import하여 사용한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;BackgroundTasks는 add_task로 추가된 task 함수와 인자들을 tasks 리스트에 저장하고 해당 객체가 호출되면 task 들을 하나씩 실행한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;각 task 들은 BackgroundTask 객체로 저장되는데, BackgroundTask는 func, args, kwargs 를 저장하고 있다가 BackgroundTasks에서 task를 하나씩 await하면 그때 func 으로 저장된 함수를 arguments 들과 함께 실행한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;BackgroundTask는 is_async라는 변수를 통해서 func가 sync 인지 async 인지 저장해놓고 실행할 때 해당 변수의 값을 확인하여 함수 타입에 맞는 방법으로 실행한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이 때문에 task function으로는 sync와 async가 모두 가능한 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BackgroundTask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Callable&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_async&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;is_async_callable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__call__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_async&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;run_in_threadpool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BackgroundTasks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BackgroundTask&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;typing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sequence&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;BackgroundTask&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Callable&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BackgroundTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__call__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="backgroundtasks-injection"&gt;
 BackgroundTasks injection
 &lt;a class="heading-anchor" href="#backgroundtasks-injection" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;FastAPI 문서에 따르면 BackgroundTasks를 사용할때는 path operation function에서 사용하라고 한다.&lt;/li&gt;
&lt;li&gt;그 이유는 FastAPI에서 request의 endpoint path에 맞는 handler를 찾고 request의 값들을 파싱하여 해당 handler function의 arguments로 입력하는 과정에서 BackgroundTasks 객체를 주입해주기 때문이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="err"&gt;✂&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dependant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;background_tasks_param_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;background_tasks&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;background_tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BackgroundTasks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;dependant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;background_tasks_param_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;background_tasks&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="err"&gt;✂&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;위의 코드는 FastAPI에서 함수의 인자로 BackgroundTasks 객체를 생성하여 입력해주는 코드의 일부를 가져온 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이 코드에서 values가 path operation function, 즉 request handler 함수의 keyword arguments로 입력되는 dict 변수이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;dependant는 request handler 함수를 분석하여 해당 함수의 parameter 등에 대한 정보를 가지고 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;만약 parameter 중에 BackgroundTasks 타입으로 선언된 parameter가 있다면 해당 parameter의 이름을 background_tasks_param_name으로 가지고 있는다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이러한 정보를 바탕으로 코드를 해석하면, request handler 함수의 parameter 중에 BackgroundTasks 타입으로 선언된 parameter가 있다면, BackgroundTasks 객체를 해당 함수의 인자로 추가해준다는 것으로 이해할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;FastAPI는 request의 path와 body 등의 값을 request handler의 parameter 형식에 맞게 파싱할 때, 재귀를 통해서 위의 로직을 반복한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그렇기 때문에 BackgroundTasks 타입을 path operation function의 parameter 또는 Depends를 사용하여 dependency, sub-dependency로 선언해도 동일하게 사용할 수 있게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="3-backgroundtasks와-celery"&gt;
 3. BackgroundTasks와 Celery
 &lt;a class="heading-anchor" href="#3-backgroundtasks%ec%99%80-celery" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;FastAPI 의 Background tasks 문서의 마지막 절에는 BackgroundTasks 사용에 대한 주의사항이 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이 글에서는 보다 더 무겁고 같은 프로세스 안에서 동작해야할 필요가 없는 작업에 대해서는 Celery를 사용하는 것을 추천한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;FastAPI의 BackgroundTasks는 FastAPI application의 프로세스 내부에서 실행되기 때문에 무거운 작업의 경우 application이 다른 request를 처리할 때 부하가 발생하여 성능적인 문제를 야기할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;반면에 Celery는 message queue로 통신하여 아예 다른 worker process에서 작업을 수행하기 때문에 성능적으로 더 안정적으로 application을 운영할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;하지만 Celery는 message queu와 여러 설정들을 추가로 해주어야 하고, 다른 프로세스에서 실행되는 만큼 변수와 메모리 등을 공유할 수 없기 때문에 상황에 잘맞는 방식으로 Background 구조를 선택해야 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;FastAPI Background Tasks 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://fastapi.tiangolo.com/tutorial/background-tasks/"&gt;https://fastapi.tiangolo.com/tutorial/background-tasks/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Network] 🔒 Let's Encrypt + Certbot으로 Nginx HTTPS 무료 SSL 적용하기</title><link>https://kyungryeol-yoon.github.io/networking/letsencrypt-nginx-https-ssl-guide/</link><pubDate>Thu, 26 Oct 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/networking/letsencrypt-nginx-https-ssl-guide/</guid><description>&lt;p&gt;웹 서비스를 운영할 때 HTTPS는 선택이 아닌 필수입니다.
&lt;strong&gt;Let&amp;rsquo;s Encrypt&lt;/strong&gt;는 비영리 기관 ISRG(Internet Security Research Group)에서 운영하는 무료 SSL/TLS 인증서 발급 기관입니다.
&lt;strong&gt;Certbot&lt;/strong&gt; 클라이언트를 사용하면 명령어 몇 줄로 인증서 발급부터 Nginx 설정 자동화, 자동 갱신까지 한 번에 처리할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-ssltls와-https-기본-개념"&gt;
 🔑 SSL/TLS와 HTTPS 기본 개념
 &lt;a class="heading-anchor" href="#-ssltls%ec%99%80-https-%ea%b8%b0%eb%b3%b8-%ea%b0%9c%eb%85%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;SSL(Secure Sockets Layer) / TLS(Transport Layer Security)는 클라이언트와 서버 간 통신을 암호화하는 보안 프로토콜입니다.
HTTPS는 이 SSL/TLS 암호화를 적용한 HTTP를 의미합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;HTTP (평문 전송) → 중간자 공격, 도청 가능
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;HTTPS (암호화 전송) → 데이터 무결성 보장, 신뢰할 수 있는 서버 검증&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;TLS 핸드셰이크 동작 원리:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;클라이언트 서버
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; │── ClientHello ────────────→ │ 암호화 방식 제안
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; │← ServerHello + 인증서 ───── │ 서버 인증서 전달
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; │── 인증서 검증 ────────────→ │ CA 서명 확인
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; │── 세션 키 생성 (대칭키) ───→ │ 이후 데이터 암호화
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; │←─────── 암호화 통신 ──────── │&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="인증서-종류"&gt;
 인증서 종류
 &lt;a class="heading-anchor" href="#%ec%9d%b8%ec%a6%9d%ec%84%9c-%ec%a2%85%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;종류&lt;/th&gt;
					&lt;th&gt;보호 범위&lt;/th&gt;
					&lt;th&gt;예시&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;단일 도메인&lt;/td&gt;
					&lt;td&gt;1개 도메인&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;example.com&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;와일드카드&lt;/td&gt;
					&lt;td&gt;1개 도메인 + 모든 서브도메인&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;*.example.com&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;멀티 도메인(SAN)&lt;/td&gt;
					&lt;td&gt;여러 도메인 동시&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;a.com&lt;/code&gt;, &lt;code&gt;b.com&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="lets-encrypt-특징"&gt;
 Let&amp;rsquo;s Encrypt 특징
 &lt;a class="heading-anchor" href="#lets-encrypt-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;내용&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;비용&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;무료&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;유효기간&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;90일 (자동 갱신 필수)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;발급 방식&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;ACME 프로토콜 자동화&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;신뢰도&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;주요 브라우저·OS에서 신뢰&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;제한&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;동일 도메인 주당 5회 발급 제한&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: 유효기간이 90일로 짧은 이유는 보안 사고 발생 시 영향 범위를 줄이고, 자동 갱신 생태계를 유도하기 위해서입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-사전-준비"&gt;
 🛠️ 사전 준비
 &lt;a class="heading-anchor" href="#-%ec%82%ac%ec%a0%84-%ec%a4%80%eb%b9%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;도메인이 서버 IP로 DNS 레코드가 연결되어 있어야 합니다.&lt;/li&gt;
&lt;li&gt;방화벽에서 포트 &lt;strong&gt;80(HTTP)&lt;/strong&gt; 과 &lt;strong&gt;443(HTTPS)&lt;/strong&gt; 이 열려 있어야 합니다.&lt;/li&gt;
&lt;li&gt;Certbot 인증 시 포트 80을 사용하므로 Nginx가 실행 중이어야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 포트 개방 확인 (Ubuntu UFW 기준)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo ufw allow &lt;span class="m"&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo ufw allow &lt;span class="m"&gt;443&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;sudo ufw reload&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-certbot-설치"&gt;
 📦 Certbot 설치
 &lt;a class="heading-anchor" href="#-certbot-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="ubuntu--debian"&gt;
 Ubuntu / Debian
 &lt;a class="heading-anchor" href="#ubuntu--debian" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo apt install nginx -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo apt install certbot python3-certbot-nginx -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="rocky-linux--centos"&gt;
 Rocky Linux / CentOS
 &lt;a class="heading-anchor" href="#rocky-linux--centos" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo dnf install nginx -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo dnf install epel-release -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo dnf install certbot python3-certbot-nginx -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="apache를-사용하는-경우"&gt;
 Apache를 사용하는 경우
 &lt;a class="heading-anchor" href="#apache%eb%a5%bc-%ec%82%ac%ec%9a%a9%ed%95%98%eb%8a%94-%ea%b2%bd%ec%9a%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;python3-certbot-nginx&lt;/code&gt; 대신 &lt;code&gt;python3-certbot-apache&lt;/code&gt;를 설치합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt install certbot python3-certbot-apache -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-nginx-기본-설정-http"&gt;
 ⚙️ Nginx 기본 설정 (HTTP)
 &lt;a class="heading-anchor" href="#-nginx-%ea%b8%b0%eb%b3%b8-%ec%84%a4%ec%a0%95-http" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;인증서 발급 전에 Nginx가 도메인을 인식할 수 있도록 설정합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo vi /etc/nginx/conf.d/example.com.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-nginx" data-lang="nginx"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="s"&gt;[::]:80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt; &lt;span class="s"&gt;www.example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="s"&gt;/var/www/html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri/&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;설정 적용:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo nginx -t &lt;span class="c1"&gt;# 문법 검사&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl reload nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-ssl-인증서-발급"&gt;
 🔐 SSL 인증서 발급
 &lt;a class="heading-anchor" href="#-ssl-%ec%9d%b8%ec%a6%9d%ec%84%9c-%eb%b0%9c%ea%b8%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="nginx-플러그인-방식-권장"&gt;
 Nginx 플러그인 방식 (권장)
 &lt;a class="heading-anchor" href="#nginx-%ed%94%8c%eb%9f%ac%ea%b7%b8%ec%9d%b8-%eb%b0%a9%ec%8b%9d-%ea%b6%8c%ec%9e%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Certbot이 Nginx 설정을 자동으로 수정해줍니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo certbot --nginx -d example.com -d www.example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;발급 과정에서 이메일 주소 입력, 이용약관 동의, HTTP→HTTPS 리다이렉트 설정 여부를 묻습니다.&lt;/p&gt;
&lt;p&gt;발급 성공 시 아래 메시지가 출력됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Successfully received certificate.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;Key is saved at: /etc/letsencrypt/live/example.com/privkey.pem
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;This certificate expires on 2026-07-25.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="standalone-방식-nginx-중지-후-발급"&gt;
 Standalone 방식 (Nginx 중지 후 발급)
 &lt;a class="heading-anchor" href="#standalone-%eb%b0%a9%ec%8b%9d-nginx-%ec%a4%91%ec%a7%80-%ed%9b%84-%eb%b0%9c%ea%b8%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl stop nginx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo certbot certonly --standalone -d example.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl start nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;포트 80을 Certbot이 직접 사용하므로 Nginx를 먼저 중지해야 합니다.&lt;/p&gt;
&lt;h3 id="webroot-방식"&gt;
 Webroot 방식
 &lt;a class="heading-anchor" href="#webroot-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Nginx를 중지하지 않고 발급할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo certbot certonly --webroot &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; -w /var/www/html &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; -d example.com &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; -d www.example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-발급-후-nginx-설정"&gt;
 📄 발급 후 Nginx 설정
 &lt;a class="heading-anchor" href="#-%eb%b0%9c%ea%b8%89-%ed%9b%84-nginx-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;--nginx&lt;/code&gt; 옵션으로 발급하면 설정이 자동으로 수정됩니다. 수동으로 적용하는 경우 아래를 참고하세요.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-nginx" data-lang="nginx"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# HTTP → HTTPS 리다이렉트
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="s"&gt;[::]:80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt; &lt;span class="s"&gt;www.example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;301&lt;/span&gt; &lt;span class="s"&gt;https://&lt;/span&gt;&lt;span class="nv"&gt;$host$request_uri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# HTTPS 서버
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt; &lt;span class="s"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="s"&gt;[::]:443&lt;/span&gt; &lt;span class="s"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt; &lt;span class="s"&gt;www.example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;ssl_certificate&lt;/span&gt; &lt;span class="s"&gt;/etc/letsencrypt/live/example.com/fullchain.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;ssl_certificate_key&lt;/span&gt; &lt;span class="s"&gt;/etc/letsencrypt/live/example.com/privkey.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;include&lt;/span&gt; &lt;span class="s"&gt;/etc/letsencrypt/options-ssl-nginx.conf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;ssl_dhparam&lt;/span&gt; &lt;span class="s"&gt;/etc/letsencrypt/ssl-dhparams.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="s"&gt;/var/www/html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri/&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;설정 적용:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo nginx -t
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl reload nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-자동-갱신-설정"&gt;
 🔄 자동 갱신 설정
 &lt;a class="heading-anchor" href="#-%ec%9e%90%eb%8f%99-%ea%b0%b1%ec%8b%a0-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s Encrypt 인증서는 &lt;strong&gt;90일마다 만료&lt;/strong&gt;됩니다. 자동 갱신을 반드시 설정해야 합니다.&lt;/p&gt;
&lt;h3 id="갱신-테스트"&gt;
 갱신 테스트
 &lt;a class="heading-anchor" href="#%ea%b0%b1%ec%8b%a0-%ed%85%8c%ec%8a%a4%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo certbot renew --dry-run&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;--dry-run&lt;/code&gt;은 실제 갱신 없이 갱신 과정을 시뮬레이션합니다.&lt;/p&gt;
&lt;h3 id="crontab으로-자동-갱신"&gt;
 Crontab으로 자동 갱신
 &lt;a class="heading-anchor" href="#crontab%ec%9c%bc%eb%a1%9c-%ec%9e%90%eb%8f%99-%ea%b0%b1%ec%8b%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo crontab -e&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;아래 라인을 추가합니다. 만료 30일 전부터 갱신을 시도합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 매일 정오에 갱신 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt; * * * /usr/bin/certbot renew --quiet
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 또는 매주 월요일 새벽 3시 + 갱신 후 Nginx 재시작&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; * * &lt;span class="m"&gt;1&lt;/span&gt; /usr/bin/certbot renew --quiet --deploy-hook &lt;span class="s2"&gt;&amp;#34;systemctl reload nginx&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="systemd-timer로-자동-갱신-ubuntu-권장"&gt;
 Systemd Timer로 자동 갱신 (Ubuntu 권장)
 &lt;a class="heading-anchor" href="#systemd-timer%eb%a1%9c-%ec%9e%90%eb%8f%99-%ea%b0%b1%ec%8b%a0-ubuntu-%ea%b6%8c%ec%9e%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Ubuntu 22.04 이상에서는 Certbot 패키지 설치 시 systemd timer가 자동으로 등록됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 타이머 상태 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl status certbot.timer
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 수동으로 갱신 실행&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;sudo certbot renew&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-인증서-관리-명령어"&gt;
 🔍 인증서 관리 명령어
 &lt;a class="heading-anchor" href="#-%ec%9d%b8%ec%a6%9d%ec%84%9c-%ea%b4%80%eb%a6%ac-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 발급된 인증서 목록 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;sudo certbot certificates
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 특정 도메인 인증서 갱신&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;sudo certbot renew --cert-name example.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 인증서 폐기&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;sudo certbot revoke --cert-path /etc/letsencrypt/live/example.com/fullchain.pem
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 인증서 삭제 (로컬 파일만 삭제)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;sudo certbot delete --cert-name example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-트러블슈팅"&gt;
 ❓ 트러블슈팅
 &lt;a class="heading-anchor" href="#-%ed%8a%b8%eb%9f%ac%eb%b8%94%ec%8a%88%ed%8c%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="발급-실패-타임아웃-오류"&gt;
 발급 실패: 타임아웃 오류
 &lt;a class="heading-anchor" href="#%eb%b0%9c%ea%b8%89-%ec%8b%a4%ed%8c%a8-%ed%83%80%ec%9e%84%ec%95%84%ec%9b%83-%ec%98%a4%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Timeout during connect (likely firewall problem)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;→ 방화벽에서 포트 80/443 개방 여부를 확인합니다. 클라우드 환경이라면 보안 그룹(Security Group)도 확인합니다.&lt;/p&gt;
&lt;h3 id="발급-실패-도메인-확인-오류"&gt;
 발급 실패: 도메인 확인 오류
 &lt;a class="heading-anchor" href="#%eb%b0%9c%ea%b8%89-%ec%8b%a4%ed%8c%a8-%eb%8f%84%eb%a9%94%ec%9d%b8-%ed%99%95%ec%9d%b8-%ec%98%a4%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;DNS problem: NXDOMAIN looking up A for example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;→ DNS A 레코드가 서버 IP로 올바르게 설정되어 있는지 확인합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;dig A example.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;nslookup example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="nginx-설정-오류"&gt;
 Nginx 설정 오류
 &lt;a class="heading-anchor" href="#nginx-%ec%84%a4%ec%a0%95-%ec%98%a4%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;nginx: [emerg] invalid parameter&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;→ &lt;code&gt;sudo nginx -t&lt;/code&gt;로 설정 문법을 검사하고, 세미콜론·괄호 누락 여부를 확인합니다.&lt;/p&gt;
&lt;h3 id="주당-발급-한도-초과"&gt;
 주당 발급 한도 초과
 &lt;a class="heading-anchor" href="#%ec%a3%bc%eb%8b%b9-%eb%b0%9c%ea%b8%89-%ed%95%9c%eb%8f%84-%ec%b4%88%ea%b3%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Error: too many certificates already issued for exact set of domains&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;→ Let&amp;rsquo;s Encrypt는 동일 도메인에 대해 &lt;strong&gt;주당 5회 발급 제한&lt;/strong&gt;이 있습니다. &lt;code&gt;--staging&lt;/code&gt; 옵션으로 테스트 인증서를 발급하여 설정을 검증한 후 실제 발급합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 테스트 인증서 발급 (한도 미소모)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo certbot --nginx --staging -d example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-요약"&gt;
 ✅ 요약
 &lt;a class="heading-anchor" href="#-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;sudo apt install certbot python3-certbot-nginx&lt;/code&gt;로 Certbot을 설치합니다.&lt;/li&gt;
&lt;li&gt;Nginx에 &lt;code&gt;server_name&lt;/code&gt;을 설정한 뒤 &lt;code&gt;sudo certbot --nginx -d 도메인&lt;/code&gt;으로 인증서를 발급합니다.&lt;/li&gt;
&lt;li&gt;발급 후 &lt;code&gt;/etc/letsencrypt/live/도메인/&lt;/code&gt; 경로에 인증서가 저장됩니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo certbot renew --dry-run&lt;/code&gt;으로 자동 갱신을 테스트한 뒤 crontab 또는 systemd timer로 자동 갱신을 설정합니다.&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>[Kubernetes] kubectl edit command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-edit/</link><pubDate>Thu, 19 Oct 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-edit/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl edit &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름의 deployment 리소스의 YAML 구성 파일을 열고 직접 수정할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl edit deployment my-deployment&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;수정한 후에는 파일을 저장하고 종료하면, Kubernetes API 서버에 변경 내용이 자동으로 적용된다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--namespace&lt;/code&gt;: 리소스가 포함된 namespace를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-namespace namespace에 속한 my-deployment 이름의 deployment 리소스의 YAML 구성 파일을 열고 직접 수정할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl edit deployment my-deployment --namespace my-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--filename&lt;/code&gt;: 파일에서 YAML 구성을 읽어온다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment.yaml 파일에서 deployment 리소스의 YAML 구성을 읽어와 수정할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl edit --filename&lt;span class="o"&gt;=&lt;/span&gt;my-deployment.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--output&lt;/code&gt;: 출력 형식을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름의 deployment 리소스의 YAML 구성을 편집한 후, YAML 형식으로 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl edit deployment my-deployment --output&lt;span class="o"&gt;=&lt;/span&gt;yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Redis] Redis 설정 옵션 정리</title><link>https://kyungryeol-yoon.github.io/database/redis/redis-configuration/</link><pubDate>Sun, 01 Oct 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/redis/redis-configuration/</guid><description>&lt;h2 id="-설치-및-기본-서버-준비"&gt;
 🧰 설치 및 기본 서버 준비
 &lt;a class="heading-anchor" href="#-%ec%84%a4%ec%b9%98-%eb%b0%8f-%ea%b8%b0%eb%b3%b8-%ec%84%9c%eb%b2%84-%ec%a4%80%eb%b9%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;아래는 기본적인 설치 및 방화벽 포트 설정 예시입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 패키지 업데이트 및 Redis 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;dnf -y update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; dnf -y upgrade &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; dnf -y install firewalld redis yum-utils net-tools wget curl
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 방화벽 서비스 활성화 및 포트 오픈&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;systemctl start firewalld
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; firewalld
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;firewall-cmd --permanent --add-port&lt;span class="o"&gt;=&lt;/span&gt;6379/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;firewall-cmd --permanent --add-service&lt;span class="o"&gt;=&lt;/span&gt;redis
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;firewall-cmd --reload
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Redis 설정 적용 &amp;amp; 활성화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;bind 0.0.0.0&amp;#34;&lt;/span&gt; &amp;gt; /etc/redis.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;systemctl start redis
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; redis
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Redis 상태 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;systemctl status redis
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;netstat -lntp &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="m"&gt;6379&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;위 예시는 &lt;strong&gt;Firewalld 환경에서 Redis 포트(6379)을 열고 서비스로 등록&lt;/strong&gt;하는 방법입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-redisconf-구성-구조"&gt;
 🧾 redis.conf 구성 구조
 &lt;a class="heading-anchor" href="#-redisconf-%ea%b5%ac%ec%84%b1-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Redis 설정 파일(&lt;code&gt;/etc/redis.conf&lt;/code&gt;)은 대부분의 옵션이 다음 형식으로 되어 있습니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;keyword arg1 arg2 ... argN&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;예를 들어:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;requirepass &amp;#34;hello world&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이와 같이 &lt;code&gt;keyword + 값&lt;/code&gt; 형태로 옵션을 정의합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-일반-옵션-general"&gt;
 📌 일반 옵션 (General)
 &lt;a class="heading-anchor" href="#-%ec%9d%bc%eb%b0%98-%ec%98%b5%ec%85%98-general" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;옵션&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;requirepass&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Redis에 접속시 필요한 비밀번호 설정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;daemonize&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Redis를 데몬으로 실행할지 여부&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;supervised&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;systemd / upstart와 같은 서비스 관리 방식 지정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;loglevel&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;로그 레벨 (&lt;code&gt;debug&lt;/code&gt;, &lt;code&gt;verbose&lt;/code&gt;, &lt;code&gt;notice&lt;/code&gt;, &lt;code&gt;warning&lt;/code&gt;)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;logfile&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;로그 출력 파일 지정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;syslog-enabled&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Syslog 사용 여부&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;기본 값은 대부분 운영자 환경에 맞게 구성되어 있지 않으므로 상황에 따라 조정할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-메모리-관련-옵션"&gt;
 🧠 메모리 관련 옵션
 &lt;a class="heading-anchor" href="#-%eb%a9%94%eb%aa%a8%eb%a6%ac-%ea%b4%80%eb%a0%a8-%ec%98%b5%ec%85%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Redis는 메모리 관리가 중요합니다. 대표적인 메모리 옵션은 다음과 같습니다:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;옵션&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;maxmemory&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Redis 인스턴스가 사용할 최대 메모리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;maxmemory-policy&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;메모리 초과 시 처리 방식 (&lt;code&gt;noeviction&lt;/code&gt;, &lt;code&gt;allkeys-lru&lt;/code&gt;, 등)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;예:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;maxmemory-policy noeviction&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;는 메모리 한도를 넘어가면 에러를 반환합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-스냅샷--데이터-저장"&gt;
 🗄️ 스냅샷 &amp;amp; 데이터 저장
 &lt;a class="heading-anchor" href="#-%ec%8a%a4%eb%83%85%ec%83%b7--%eb%8d%b0%ec%9d%b4%ed%84%b0-%ec%a0%80%ec%9e%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Redis는 RDB 스냅샷 방식을 지원합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;옵션&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;dbfilename&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;덤프 파일 이름&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;dir&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;덤프 저장 디렉터리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;save&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;자동 백업 주기 설정&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;스냅샷은 Redis가 실행 중인 데이터를 지정 주기마다 디스크에 저장합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-네트워크-설정"&gt;
 📡 네트워크 설정
 &lt;a class="heading-anchor" href="#-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Redis 서버가 외부에서 접근 가능하게 설정하려면 다음 옵션들을 주의해야 합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;옵션&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;bind&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Redis가 수신할 IP 지정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;protected-mode&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;보호 모드 활성화 여부&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;port&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;수신 포트 지정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;tcp-keepalive&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;TCP keep-alive 설정&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;예:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;bind 192.168.0.150 10.0.0.5
port 6379
protected-mode yes&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Redis를 외부에서 안전하게 노출하기 위해서는 &lt;strong&gt;bind와 protected-mode 옵션을 함께 설정&lt;/strong&gt;하는 것이 좋습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-복제--보안-옵션"&gt;
 🔐 복제 &amp;amp; 보안 옵션
 &lt;a class="heading-anchor" href="#-%eb%b3%b5%ec%a0%9c--%eb%b3%b4%ec%95%88-%ec%98%b5%ec%85%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;옵션&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;replicaof&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Redis replication(복제) 설정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;masterauth&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;복제 시 마스터 인증 비밀번호&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Replica 서버가 Master와 연결을 유지하고 복제하기 위해 필요한 옵션입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-cli-연결-예시"&gt;
 📊 CLI 연결 예시
 &lt;a class="heading-anchor" href="#-cli-%ec%97%b0%ea%b2%b0-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Redis CLI를 통해 접속할 때는 다음 명령을 사용할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;redis-cli -h &lt;span class="o"&gt;[&lt;/span&gt;접속IP&lt;span class="o"&gt;]&lt;/span&gt; -p &lt;span class="o"&gt;[&lt;/span&gt;포트&lt;span class="o"&gt;]&lt;/span&gt; -a &lt;span class="o"&gt;[&lt;/span&gt;비밀번호&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;예:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;redis-cli -h 192.168.0.150 -p 6379 -a &amp;#34;yourpass&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;기본적인 키/값 조작도 아래와 같이 수행할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;redis-cli &lt;span class="nb"&gt;set&lt;/span&gt; mykey &lt;span class="s2"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;redis-cli get mykey
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;redis-cli del mykey
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;redis-cli flushall&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-핵심-정리"&gt;
 📌 핵심 정리
 &lt;a class="heading-anchor" href="#-%ed%95%b5%ec%8b%ac-%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Redis 설정은 크게 다음 영역으로 나눌 수 있습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;🔧 서비스 설치 및 방화벽 설정&lt;/li&gt;
&lt;li&gt;🛠 일반 옵션 (로그, 비밀번호)&lt;/li&gt;
&lt;li&gt;🧠 메모리 &amp;amp; eviction 정책&lt;/li&gt;
&lt;li&gt;💾 스냅샷 &amp;amp; 디스크 저장&lt;/li&gt;
&lt;li&gt;🌐 네트워크 접속 정책&lt;/li&gt;
&lt;li&gt;🔐 복제 &amp;amp; 보안&lt;/li&gt;
&lt;li&gt;📡 CLI로 직접 실습&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;</description></item><item><title>[Kubernetes] kubectl rollout command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-rollout/</link><pubDate>Sun, 17 Sep 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-rollout/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout &lt;span class="o"&gt;[&lt;/span&gt;하위 명령어&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt;/&lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# deployment rollout 상태를 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout status deployment/my-deploymentmy-deployment &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--revision&lt;/code&gt;: rollout 작업에서 사용할 revision 번호를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment deployment를 2번 revision으로 rollback&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout undo deployment/my-deployment --to-revision&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--dry-run&lt;/code&gt;: 실제로 명령어를 실행하지 않고, 실행 결과만 미리 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment deployment를 재시작할 때, 실제로는 실행하지 않고 결과만 미리 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout restart deployment/my-deployment --dry-run&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rollout-작업-상태-확인"&gt;
 rollout 작업 상태 확인
 &lt;a class="heading-anchor" href="#rollout-%ec%9e%91%ec%97%85-%ec%83%81%ed%83%9c-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="기본-구조-1"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout status &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt;/&lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment deployment의 rollout 상태를 확인할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout status deployment/my-deployment&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="option-1"&gt;
 Option
 &lt;a class="heading-anchor" href="#option-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--watch&lt;/code&gt;: 롤아웃 상태를 실시간으로 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment deployment의 rollout 상태를 실시간으로 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout status deployment/my-deployment --watch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--timeout&lt;/code&gt;: 대기 시간을 지정한다. 이 시간을 초과하면 명령어가 종료&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment deployment의 rollout이 60초 이내에 완료되지 않으면 명령어가 종료&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout status deployment/my-deployment --timeout&lt;span class="o"&gt;=&lt;/span&gt;60s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rollout-작업-취소하고-이전-버전으로-rollout"&gt;
 rollout 작업 취소하고 이전 버전으로 rollout
 &lt;a class="heading-anchor" href="#rollout-%ec%9e%91%ec%97%85-%ec%b7%a8%ec%86%8c%ed%95%98%ea%b3%a0-%ec%9d%b4%ec%a0%84-%eb%b2%84%ec%a0%84%ec%9c%bc%eb%a1%9c-rollout" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="기본-구조-2"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout undo &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름의 배포를 이전 버전으로 rollback할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout undo deployment/my-deployment&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="option-2"&gt;
 Option
 &lt;a class="heading-anchor" href="#option-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--to-revision&lt;/code&gt;: rollback할 배포의 revision 번호를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름의 배포를 2번 revision으로 rollback&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout undo deployment/my-deployment --to-revision&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--dry-run&lt;/code&gt;: 실제로 rollback하지 않고 실행 결과만 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름의 배포를 실제로 rollback하지 않고 실행 결과만 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout undo deployment/my-deployment --dry-run&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rollout-작업-이력을-확인"&gt;
 rollout 작업 이력을 확인
 &lt;a class="heading-anchor" href="#rollout-%ec%9e%91%ec%97%85-%ec%9d%b4%eb%a0%a5%ec%9d%84-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="기본-구조-3"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0-3" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout &lt;span class="nb"&gt;history&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 명령어를 실행하여 my-deployment 이름의 배포의 이전 rollout 기록을 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout &lt;span class="nb"&gt;history&lt;/span&gt; deployment/my-deployment&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="option-3"&gt;
 Option
 &lt;a class="heading-anchor" href="#option-3" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--revision&lt;/code&gt;: 특정 revision의 상세 정보를 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름의 배포의 2번 revision의 상세 정보를 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout &lt;span class="nb"&gt;history&lt;/span&gt; deployment/my-deployment --revision&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--namespace&lt;/code&gt;: 리소스가 포함된 namespace를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-namespace namespace에 속한 my-deployment 이름의 배포의 이전 rollout 기록을 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout &lt;span class="nb"&gt;history&lt;/span&gt; deployment/my-deployment --namespace my-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rollout-작업-재시작"&gt;
 rollout 작업 재시작
 &lt;a class="heading-anchor" href="#rollout-%ec%9e%91%ec%97%85-%ec%9e%ac%ec%8b%9c%ec%9e%91" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="기본-구조-4"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0-4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout restart &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt;/&lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment deployment를 다시 시작할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout restart deployment/my-deployment&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="option-4"&gt;
 Option
 &lt;a class="heading-anchor" href="#option-4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--selector&lt;/code&gt;: Label selector를 사용하여 리소스를 선택
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# app=nginx Label을 가진 모든 deployment를 다시 시작&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout restart deployment --selector&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rollout-작업-일시-중지"&gt;
 rollout 작업 일시 중지
 &lt;a class="heading-anchor" href="#rollout-%ec%9e%91%ec%97%85-%ec%9d%bc%ec%8b%9c-%ec%a4%91%ec%a7%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="기본-구조-5"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0-5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout pause &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt;/&lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment deployment의 rollout 작업을 일시 중지할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout pause deployment/my-deployment&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="option-5"&gt;
 Option
 &lt;a class="heading-anchor" href="#option-5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--selector&lt;/code&gt;: Label selector를 사용하여 리소스를 선택
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# app=nginx Label을 가진 모든 deployment의 rollout 작업을 일시 중지&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout pause deployment --selector&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;일시 중지된 rollout 작업은 kubectl rollout resume 명령어를 사용하여 다시 시작할 수 있다. 이 명령어를 사용하면, rollout 작업이 이전 상태에서 재개된다.
{: .prompt-danger }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="일시-중지된-rollout-작업-다시-시작"&gt;
 일시 중지된 rollout 작업 다시 시작
 &lt;a class="heading-anchor" href="#%ec%9d%bc%ec%8b%9c-%ec%a4%91%ec%a7%80%eb%90%9c-rollout-%ec%9e%91%ec%97%85-%eb%8b%a4%ec%8b%9c-%ec%8b%9c%ec%9e%91" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="기본-구조-6"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0-6" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout resume &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt;/&lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment deployment의 rollout 작업을 다시 시작할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout resume deployment/my-deployment&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="option-6"&gt;
 Option
 &lt;a class="heading-anchor" href="#option-6" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--selector&lt;/code&gt;: Label selector를 사용하여 리소스를 선택
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# app=nginx Label을 가진 모든 deployment의 rollout 작업을 다시 시작&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout resume deployment --selector&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubectl api-resources command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-api-resources/</link><pubDate>Tue, 12 Sep 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-api-resources/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes API에 정의된 모든 리소스 종류와 해당 리소스의 별칭, 리소스 유형 등의 정보를 출력
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl api-resources&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--namespaced&lt;/code&gt;: 네임스페이스를 사용하는 리소스만 출력&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# namespace를 사용하는 리소스 종류만 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl api-resources --namespaced&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--verbs&lt;/code&gt;: 지정한 액션을 수행할 수 있는 리소스만 출력&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# get과 delete 액션을 수행할 수 있는 리소스 종류만 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl api-resources --verbs&lt;span class="o"&gt;=&lt;/span&gt;get,delete&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--api-group&lt;/code&gt;: 지정한 API 그룹에 속한 리소스만 출력&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# apps API 그룹에 속한 리소스 종류만 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl api-resources --api-group&lt;span class="o"&gt;=&lt;/span&gt;apps&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Git] Git Bash Alias - Windows</title><link>https://kyungryeol-yoon.github.io/devops/git/gitbash-alias-windows/</link><pubDate>Wed, 23 Aug 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/git/gitbash-alias-windows/</guid><description>&lt;h2 id="windows-git-bash에서-alias-설정"&gt;
 Windows Git Bash에서 Alias 설정
 &lt;a class="heading-anchor" href="#windows-git-bash%ec%97%90%ec%84%9c-alias-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C:\Program Files\Git\etc\profile.d&lt;/code&gt; 경로의 &lt;code&gt;aliases.sh&lt;/code&gt; 파일에 아래와 같이 추가&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;mgmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;cp -f $HOME/.kube/config_mgmt $HOME/.kube/config; kubectl get node -o wide&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;prod&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;cp -f $HOME/.kube/config_prod $HOME/.kube/config; kubectl get node -o wide&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;stg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;cp -f $HOME/.kube/config_stg $HOME/.kube/config; kubectl get node -o wide&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;cp -f $HOME/.kube/config_dev $HOME/.kube/config; kubectl get node -o wide&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;beta&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;cp -f $HOME/.kube/config_beta $HOME/.kube/config; kubectl get node -o wide&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;ls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ls -F --color=auto --show-control-chars&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;ll&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ls -l&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;C:\Program Files\Git\etc&lt;/code&gt; 경로로 이동, &lt;code&gt;bash.bashrc&lt;/code&gt; 파일에 아래와 같이 추가&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;. /etc/profile.d/aliases.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Terminal에서 &lt;code&gt;/etc&lt;/code&gt; 경로로 이동, 아래 명령어로 적용&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;source&lt;/span&gt; bash.bashrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] kubectl auth can-i command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-auth/</link><pubDate>Fri, 11 Aug 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-auth/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl auth can-i &lt;span class="o"&gt;[&lt;/span&gt;액션&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;--namespace namespace&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;--subresource subresource&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;--list&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 현재 인증된 사용자가 파드를 가져올 수 있는지 여부를 확인할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl auth can-i get pods&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--namespace&lt;/code&gt;: 네임스페이스를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-namespace 네임스페이스 내 파드를 가져올 수 있는지 여부를 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl auth can-i get pods --namespace&lt;span class="o"&gt;=&lt;/span&gt;my-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--subresource&lt;/code&gt;: 서브리소스를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 이벤트의 watch 서브리소스를 가져올 수 있는지 여부를 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl auth can-i get events --subresource&lt;span class="o"&gt;=&lt;/span&gt;watch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--list&lt;/code&gt;: 리소스 목록을 출력&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 현재 사용자가 모든 파드를 가져올 수 있는지 여부와 함께 파드 목록을 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl auth can-i list pods --list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubectl cluster-info command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-cluster-info/</link><pubDate>Wed, 09 Aug 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-cluster-info/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;클러스터의 API 서버와 DNS 서비스의 IP 주소, 포트, 클러스터의 CA 인증서, API 서버의 버전 정보 등을 포함
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl cluster-info&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--context&lt;/code&gt;: 사용할 컨텍스트를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-context 컨텍스트를 사용하여 클러스터 정보를 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl cluster-info --context&lt;span class="o"&gt;=&lt;/span&gt;my-context&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--namespace&lt;/code&gt;: 리소스가 포함된 네임스페이스를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-namespace 네임스페이스에 대한 클러스터 정보를 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl cluster-info --namespace&lt;span class="o"&gt;=&lt;/span&gt;my-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubectl explain command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-explain/</link><pubDate>Mon, 07 Aug 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-explain/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl explain &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 리소스의 필드와 값을 확인할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl explain podPod&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--recursive&lt;/code&gt;, &lt;code&gt;-r&lt;/code&gt;: 모든 참조된 리소스의 필드와 값을 출력&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Pod 리소스와 관련된 모든 참조된 리소스의 필드와 값을 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl explain pod --recursive&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--api-version&lt;/code&gt;: API 버전을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# v1 버전의 Pod 리소스의 필드와 값을 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl explain pod --api-version&lt;span class="o"&gt;=&lt;/span&gt;v1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--show-defaults&lt;/code&gt;: 기본값을 포함하여 출력&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Pod 리소스의 필드와 값을 기본값과 함께 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl explain pod --show-defaults&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubectl drain command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-drain/</link><pubDate>Thu, 27 Jul 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-drain/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl drain &lt;span class="o"&gt;[&lt;/span&gt;노드 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-node 이름을 가진 노드에서 실행 중인 파드를 안전하게 다른 노드로 이동하고, 노드를 비활성화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl drain my-node&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--ignore-daemonsets&lt;/code&gt;: 데몬셋을 무시하고 파드를 다른 노드로 이동&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-node 이름을 가진 노드에서 실행 중인 파드를 안전하게 다른 노드로 이동하면서, 데몬셋을 무시&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl drain my-node --ignore-daemonsets&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--delete-local-data&lt;/code&gt;: 파드에서 사용하는 로컬 디스크 데이터를 삭제&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-node 이름을 가진 노드에서 실행 중인 파드를 안전하게 다른 노드로 이동하면서, 파드에서 사용하는 로컬 디스크 데이터를 삭제&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl drain my-node --delete-local-data&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--force&lt;/code&gt;: 파드가 정상적으로 종료되지 않더라도 파드를 강제로 이동&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-node 이름을 가진 노드에서 실행 중인 파드를 안전하게 다른 노드로 이동하면서, 파드가 정상적으로 종료되지 않더라도 강제로 이동&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl drain my-node --force&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--grace-period&lt;/code&gt;: 파드가 삭제되기 전 대기하는 시간(초)을 설정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-node 이름을 가진 노드에서 실행 중인 파드를 안전하게 다른 노드로 이동하면서, 파드가 삭제되기 전 30초간 대기&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl drain my-node --grace-period&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;30&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-n&lt;/code&gt;, &lt;code&gt;--namespace&lt;/code&gt;: 파드가 위치한 네임스페이스를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-node 이름을 가진 노드에서 실행 중인 파드를 안전하게 다른 노드로 이동하면서, my-namespace 네임스페이스에 위치한 파드를 이동&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl drain my-node -n my-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Git] Git Branch</title><link>https://kyungryeol-yoon.github.io/devops/git/git-branch/</link><pubDate>Tue, 25 Jul 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/git/git-branch/</guid><description>&lt;h2 id="git-pull"&gt;
 &lt;strong&gt;git pull&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#git-pull" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;branch를 생성하기 위해 git project의 master가 올린 repo를 pull하여 가져온다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;git pull &lt;span class="s2"&gt;&amp;#34;원격 repo 주소&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;git branch를 입력하여 원격 repo와 연결된 master branch가 생성되어 있는 것을 볼 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;git branch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="git-branch"&gt;
 &lt;strong&gt;git branch &amp;ldquo;branch 이름&amp;rdquo;&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#git-branch" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;새로운 branch를 생성한다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;git branch &lt;span class="s2"&gt;&amp;#34;branch 이름&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="git-checkout"&gt;
 &lt;strong&gt;git checkout &amp;ldquo;branch 이름&amp;rdquo;&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#git-checkout" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;git checkout 명령어를 사용하여 branch를 이동할 수 있다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;git checkout &lt;span class="s2"&gt;&amp;#34;branch 이름&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="branch에서-작업-후-add-commit"&gt;
 &lt;strong&gt;branch에서 작업 후 add, commit&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#branch%ec%97%90%ec%84%9c-%ec%9e%91%ec%97%85-%ed%9b%84-add-commit" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;생성한 branch에서 파일을 수정, 삭제, 추가하더라도 병합을 하기 전까지는 master branch에 아무런 영향을 주지 않는다.&lt;/li&gt;
&lt;li&gt;branch에서 작업한 내용을 master에 병합을 하기 위해서는 git에서 add, commit 한 것과 같이 branch의 변경 사항을 업데이트 해 주어야 한다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 파일 상태 체크&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;git status
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 특정 파일만 add 할 때&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;git add &lt;span class="s2"&gt;&amp;#34;파일명&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 모든 파일을 add 할 때&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;git add -A
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;git add .
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Commit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;git commit -m &lt;span class="s2"&gt;&amp;#34;commit 메세지&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="git-merge"&gt;
 &lt;strong&gt;git merge&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#git-merge" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;생성한 branch에서의 작업을 모두 commit 했다면 다시 master branch로 돌아와 작업을 진행했던 branch와 병합을 해 주어야 한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# master branch로 돌아가기&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;git checkout master
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 작업을 진행한 branch를 master에 병합하기&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;git merge &lt;span class="s2"&gt;&amp;#34;병합할 branch 이름&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 원격 repo에 push&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;git push origin &lt;span class="s2"&gt;&amp;#34;병합한 branch 이름&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;branch의 변경 사항을 master에서 병합을 했다면 원격 repo에 push, branch의 작업 내용이 반영된 채로 원격 repo에 commit이 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="gitlab-merge-request"&gt;
 &lt;strong&gt;gitlab Merge Request&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#gitlab-merge-request" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Local에서 생성하고 작업한 branch의 작업 내용만 commit하여 push한 것이기 때문에 프로젝트 master의 branch에는 전혀 영향을 주지 않는다.&lt;/li&gt;
&lt;li&gt;협업을 진행할 땐 팀원이 진행한 branch의 내용을 master에 병합을 할 필요가 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="특정-branch만-clone하고-싶을-때"&gt;
 &lt;strong&gt;특정 branch만 clone하고 싶을 때&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ed%8a%b9%ec%a0%95-branch%eb%a7%8c-clone%ed%95%98%ea%b3%a0-%ec%8b%b6%ec%9d%84-%eb%95%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;git clone -b &lt;span class="s2"&gt;&amp;#34;clone할 branch 이름&amp;#34;&lt;/span&gt; --single-branch &lt;span class="s2"&gt;&amp;#34;repo 주소&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="특정-branch만-pull-할-때"&gt;
 &lt;strong&gt;특정 branch만 pull 할 때&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ed%8a%b9%ec%a0%95-branch%eb%a7%8c-pull-%ed%95%a0-%eb%95%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;git pull origin &lt;span class="s2"&gt;&amp;#34;pull할 branch 이름&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] kubectl cordon command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-cordon/</link><pubDate>Fri, 07 Jul 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-cordon/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl cordon &lt;span class="o"&gt;[&lt;/span&gt;노드 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-node 이름을 가진 노드를 Scheduling 하지 않도록 설정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl cordon my-node&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--ignore-daemonsets&lt;/code&gt;: 데몬셋을 무시하고 노드를 cordon 처리&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-node 이름을 가진 노드를 Scheduling 하지 않도록 설정하면서, 데몬셋을 무시한다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl cordon my-node --ignore-daemonsets&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--dry-run&lt;/code&gt;: 노드를 cordon 처리하지 않고 처리 결과만 미리 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-node 이름을 가진 노드를 Scheduling 하지 않도록 설정하지 않고, 처리 결과만 미리 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl cordon my-node --dry-run&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--selector&lt;/code&gt;: cordon 처리할 노드를 선택한다. label selector를 지정하여 여러 노드를 선택할 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# region이 us-west인 노드를 모두 cordon 처리&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl cordon --selector&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;region=us-west&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--timeout&lt;/code&gt;: cordon 처리할 때, 타임아웃을 설정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-node 이름을 가진 노드를 Scheduling 하지 않도록 설정하면서, 타임아웃을 60초로 설정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl cordon my-node --timeout&lt;span class="o"&gt;=&lt;/span&gt;60s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Docker] FTP 서버</title><link>https://kyungryeol-yoon.github.io/docker/docker-ftp/</link><pubDate>Wed, 21 Jun 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/docker/docker-ftp/</guid><description>&lt;h2 id="docker-ftp"&gt;
 docker ftp
 &lt;a class="heading-anchor" href="#docker-ftp" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;공유할 폴더 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo mkdir /appdata/appuser/ftpdata&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;container 생성 및 백업&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker run --net&lt;span class="o"&gt;=&lt;/span&gt;host -d -v /appdata/appuser/ftpdata:/home/vstfpd -it --name data-ftp --restart&lt;span class="o"&gt;=&lt;/span&gt;always docker.io/ubuntu:20.04
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo docker commit -p data-ftp data-ftp-backup
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo docker stop data-ftp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;sudo docker remove data-ftp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;sudo docker run --net&lt;span class="o"&gt;=&lt;/span&gt;host -d -v /appdata/appuser/ftpdata:/home/vstfpd -it --name data-ftp --restart&lt;span class="o"&gt;=&lt;/span&gt;always data-ftp-backup&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;docker 목록 조회&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker ps -a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="vsftpd-설치"&gt;
 vsftpd 설치
 &lt;a class="heading-anchor" href="#vsftpd-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;container 접속&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker &lt;span class="nb"&gt;exec&lt;/span&gt; -it data-ftp bash&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;vsftpd 설치&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;apt-get install -y vsftpd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;apt-get install -y vim&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="vsftpd-설정-파일-수정"&gt;
 vsftpd 설정 파일 수정
 &lt;a class="heading-anchor" href="#vsftpd-%ec%84%a4%ec%a0%95-%ed%8c%8c%ec%9d%bc-%ec%88%98%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;vi /etc/vsftpd.conf&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-conf" data-lang="conf"&gt;# 패시브 모드 활성화
pasv_enable=YES

# Data 포트 범위설정
pasv_min_port=30001
pasv_max_port=30001

# 패시브모드로 연결될 ip(포트제외 서버ip만 적어주세요)
pasv_address=serverIp&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;vsftpd 재시작&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;service vsftpd restart&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;vsftpd 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo netstat -natp &lt;span class="p"&gt;|&lt;/span&gt; grep ftp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo vsftpd status
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;sudo netstat -natp &lt;span class="p"&gt;|&lt;/span&gt; grep LISTEN
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# vsftpd 멈춘다면&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;sudo vsftpd stop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;user 추가&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;adduser testuser&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ftp-접속"&gt;
 FTP 접속
 &lt;a class="heading-anchor" href="#ftp-%ec%a0%91%ec%86%8d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ftp 프로그램 또는 command로 접속&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="파일-업로드-또는-수정이-안된다면"&gt;
 파일 업로드 또는 수정이 안된다면?
 &lt;a class="heading-anchor" href="#%ed%8c%8c%ec%9d%bc-%ec%97%85%eb%a1%9c%eb%93%9c-%eb%98%90%eb%8a%94-%ec%88%98%ec%a0%95%ec%9d%b4-%ec%95%88%eb%90%9c%eb%8b%a4%eb%a9%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;3가지 설정을 주석처리 해서 권한수정
&lt;pre tabindex="0"&gt;&lt;code class="language-conf" data-lang="conf"&gt;#chroot_local_user=YES
#chroot_list_enable=YES
#chroot_list_file=/etc/vsftpd.chroot_list&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] kubectl copy command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-copy/</link><pubDate>Sun, 11 Jun 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-copy/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl cp &lt;span class="o"&gt;[&lt;/span&gt;소스&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;대상&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Local Machine의 /path/to/local/file 파일을 my-pod 파드의 /path/to/destination 경로로 복사할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl cp /path/to/local/file my-pod:/path/to/destination&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-c&lt;/code&gt;, &lt;code&gt;--container&lt;/code&gt;: 컨테이너 이름을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 파드의 my-container 컨테이너 내부의 /path/to/destination 경로에 로컬 머신의 /path/to/local/file 파일을 복사&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl cp /path/to/local/file my-pod:/path/to/destination -c my-container&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--no-preserve&lt;/code&gt;: 파일 속성을 유지하지 않는다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 파드의 /path/to/destination 경로에 로컬 머신의 /path/to/local/file 파일을 복사하되, 속성은 유지하지 않는다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl cp /path/to/local/file my-pod:/path/to/destination --no-preserve&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Mac OS] iTerm2 설치 및 꾸미기</title><link>https://kyungryeol-yoon.github.io/environment/macos/iterm2/</link><pubDate>Tue, 30 May 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/environment/macos/iterm2/</guid><description>&lt;h2 id="iterm2-설치"&gt;
 iTerm2 설치
 &lt;a class="heading-anchor" href="#iterm2-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew install iterm2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/homebrew-cask"&gt;Homebrew 설치 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="oh-my-zsh-설치"&gt;
 oh my zsh 설치
 &lt;a class="heading-anchor" href="#oh-my-zsh-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;iTerm2에 다음 명령어를 입력한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sh -c &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="theme-적용"&gt;
 Theme 적용
 &lt;a class="heading-anchor" href="#theme-%ec%a0%81%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;다음 명령어를 입력해 Theme를 다운받는다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;git clone https://github.com/romkatv/powerlevel10k.git &lt;span class="nv"&gt;$ZSH&lt;/span&gt;/themes/powerlevel10k&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;.zshrc&lt;/code&gt; 파일 열기&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;open ~/.zshrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ZSH_THEME&lt;/code&gt;를 수정한다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ZSH_THEME=&amp;#34;powerlevel10k/powerlevel10k&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;변경사항을 적용해준다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.zshrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Theme 설정을 변경하고 싶다면, 다음 명령어를 통해 수정이 가능하다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;p10k configure&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-tip }&lt;/p&gt;
&lt;h2 id="유용한-zsh-plugin"&gt;
 유용한 zsh Plugin
 &lt;a class="heading-anchor" href="#%ec%9c%a0%ec%9a%a9%ed%95%9c-zsh-plugin" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="syntax-highlighting-plugin-적용은-아래-참고"&gt;
 Syntax Highlighting (Plugin 적용은 아래 참고)
 &lt;a class="heading-anchor" href="#syntax-highlighting-plugin-%ec%a0%81%ec%9a%a9%ec%9d%80-%ec%95%84%eb%9e%98-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;명령어에 Highlight를 해주는 기능&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew install zsh-syntax-highlighting&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="auto-suggestions-plugin-적용은-아래-참고"&gt;
 Auto Suggestions (Plugin 적용은 아래 참고)
 &lt;a class="heading-anchor" href="#auto-suggestions-plugin-%ec%a0%81%ec%9a%a9%ec%9d%80-%ec%95%84%eb%9e%98-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;이전에 입력한 명령어를 보여주는 기능&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;오른쪽 방향키를 누르면 전체 명령어를 완성해준다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew install zsh-autosuggestions&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="autojump-plugin-적용은-아래-참고"&gt;
 Autojump (Plugin 적용은 아래 참고)
 &lt;a class="heading-anchor" href="#autojump-plugin-%ec%a0%81%ec%9a%a9%ec%9d%80-%ec%95%84%eb%9e%98-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;이전에 방문했던 위치를 알아서 찾아준다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;예를 들어 &lt;code&gt;/Downloads&lt;/code&gt;에서 &lt;code&gt;j dev&lt;/code&gt; 를 입력하면 &lt;code&gt;dev&lt;/code&gt; 라는 이름을 가진 Directory 중 가장 많이 방문한 곳으로 이동한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;j -s&lt;/code&gt;를 입력하면 방문한 Directory 기록 확인이 가능하다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew install autojump&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="plugin-적용"&gt;
 Plugin 적용
 &lt;a class="heading-anchor" href="#plugin-%ec%a0%81%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;.zshrc&lt;/code&gt; 파일 열기&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;open ~/.zshrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;다음 명령어 추가&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;source /opt/homebrew/share/zsh-autosuggestions/zsh-autosuggestions.zsh
source /opt/homebrew/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;plugins = (
 git
 autojump
 zsh-syntax-highlighting
 zsh-autosuggestions
)&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] kubectl delete command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-delete/</link><pubDate>Mon, 15 May 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-delete/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl delete &lt;span class="o"&gt;[&lt;/span&gt;리소스 유형&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Pod 삭제하려면 다음과 같이 입력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl delete pod &lt;span class="o"&gt;[&lt;/span&gt;파드 이름&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--all&lt;/code&gt;: 모든 리소스를 삭제&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--force&lt;/code&gt;: 강제 삭제&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--grace-period=&amp;lt;초&amp;gt;&lt;/code&gt;: 삭제될 때 대기할 시간을 초 단위로 설정&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--timeout=&amp;lt;초&amp;gt;&lt;/code&gt;: 명령이 실행될 때 대기할 최대 시간을 초 단위로 설정&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 모든 파드를 강제로 삭제&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl delete pod --all --force
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 모든 종류의 리소스와 파드를 삭제&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;kubectl delete all --all&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubectl run command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-run/</link><pubDate>Thu, 20 Apr 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-run/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl run &lt;span class="o"&gt;[&lt;/span&gt;파드 이름&lt;span class="o"&gt;]&lt;/span&gt; --image&lt;span class="o"&gt;=[&lt;/span&gt;이미지 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 명령어를 실행하여 nginx 이미지를 실행하는 nginx 파드를 생성할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl run nginx --image&lt;span class="o"&gt;=&lt;/span&gt;nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--image&lt;/code&gt;: 실행할 이미지 이름을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# nginx 이미지를 사용하여 파드를 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl run nginx --image&lt;span class="o"&gt;=&lt;/span&gt;nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--replicas&lt;/code&gt;: 생성할 파드나 작업의 개수를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# nginx 이미지를 사용하여 파드를 3개 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl run nginx --image&lt;span class="o"&gt;=&lt;/span&gt;nginx --replicas&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--port&lt;/code&gt;: 파드나 작업에서 노출할 포트 번호를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# nginx 이미지를 사용하여 파드를 생성하고, 80번 포트를 노출&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl run nginx --image&lt;span class="o"&gt;=&lt;/span&gt;nginx --port&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Linux] df, du란?</title><link>https://kyungryeol-yoon.github.io/linux/system/linux-df-du/</link><pubDate>Fri, 14 Apr 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/system/linux-df-du/</guid><description>&lt;h2 id="df--disk-free-"&gt;
 df ( Disk Free )
 &lt;a class="heading-anchor" href="#df--disk-free-" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Linux System 전체의(Mount 포함) Disk의 여유 공간 확인&lt;/li&gt;
&lt;li&gt;File System, Disk 크기, 사용량, 남아있는 용량, 사용률, Mount 지점 순으로 정보를 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="du--disk-usage-"&gt;
 du ( Disk Usage )
 &lt;a class="heading-anchor" href="#du--disk-usage-" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;해당 파일 및 Directory의 Disk 크기를 확인하는 명령어&lt;/li&gt;
&lt;li&gt;옵션이 없으면 현재 경로의 모든 파일 크기를 MB단위로 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="df와-du의-출력-크기가-다르게-보이는-이유"&gt;
 df와 du의 출력 크기가 다르게 보이는 이유
 &lt;a class="heading-anchor" href="#df%ec%99%80-du%ec%9d%98-%ec%b6%9c%eb%a0%a5-%ed%81%ac%ea%b8%b0%ea%b0%80-%eb%8b%a4%eb%a5%b4%ea%b2%8c-%eb%b3%b4%ec%9d%b4%eb%8a%94-%ec%9d%b4%ec%9c%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;df 명령어는 현재 Mount 된 File System의 상태를 기초로 하여 사용률을 보여주는 것이고, du명령어는 실제 Directory와 파일을 확인하고 그 크기를 조사하기 때문&lt;/li&gt;
&lt;li&gt;현재 실행 중인 프로세스가 열려 있는 파일에 대해서 삭제 처리를 한 후에 해당 프로세스(task)를 종료하지 않으면 그 파일은 deleted 상태로 남게 된다.
&lt;ul&gt;
&lt;li&gt;즉, 파일시스템에 deleted 상태 정보로 유지되고 있는 것이기 때문에 df 명령어로 확인하게 되면 deleted 파일이 차지하는 용량까지 더해져서 du 명령어와의 차이가 나타나는 것.&lt;/li&gt;
&lt;li&gt;특히, MySQL에서 큰 데이터베이스를 날렸을 경우에는 그 차이가 크게 느껴질 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="확인하는-방법"&gt;
 확인하는 방법
 &lt;a class="heading-anchor" href="#%ed%99%95%ec%9d%b8%ed%95%98%eb%8a%94-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;lsof라는 명령어를 통해서 &lt;code&gt;deleted&lt;/code&gt; 상태에 있는 파일을 확인할 수 있으니 각각의 파일 정보에서 해당 PID를 찾아서 그 프로세스를 Reset하거나 종료하면 df에서 잠식당한 공간을 확보할 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;lsof &lt;span class="p"&gt;|&lt;/span&gt; grep deleted&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Redis] Redis 백업 및 영속화 전략 (RDB &amp; AOF)</title><link>https://kyungryeol-yoon.github.io/database/redis/redis-backup-and-persistence-strategy/</link><pubDate>Mon, 03 Apr 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/redis/redis-backup-and-persistence-strategy/</guid><description>&lt;h2 id="redis-백업-및-영속화-전략"&gt;
 Redis 백업 및 영속화 전략
 &lt;a class="heading-anchor" href="#redis-%eb%b0%b1%ec%97%85-%eb%b0%8f-%ec%98%81%ec%86%8d%ed%99%94-%ec%a0%84%eb%9e%b5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Redis는 기본적으로 &lt;strong&gt;메모리 기반 데이터 저장소&lt;/strong&gt;입니다.
이는 빠른 속도의 장점이 있지만, 서버가 리부팅되거나 장애가 발생하면 메모리 데이터가 사라지는 특성이 있습니다. 이를 해결하기 위해 Redis는 &lt;strong&gt;디스크에 데이터를 저장하는 영속화(Persistence)&lt;/strong&gt; 기능을 제공합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-왜-redis-백업이-필요한가"&gt;
 📌 왜 Redis 백업이 필요한가?
 &lt;a class="heading-anchor" href="#-%ec%99%9c-redis-%eb%b0%b1%ec%97%85%ec%9d%b4-%ed%95%84%ec%9a%94%ed%95%9c%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Redis는 기본적으로 인메모리에 데이터를 저장합니다.&lt;br&gt;
즉, 프로세스가 종료되거나 서버가 재부팅될 경우 &lt;strong&gt;메모리 데이터가 사라집니다.&lt;/strong&gt;&lt;br&gt;
이를 방지하기 위해 디스크에 데이터를 백업해야 하며, Redis는 2가지 주요 백업 방식을 지원합니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;RDB (Snapshot) 방식&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AOF (Append Only File) 방식&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="-1-rdb-snapshot-방식"&gt;
 🧠 1. RDB (Snapshot) 방식
 &lt;a class="heading-anchor" href="#-1-rdb-snapshot-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="-개념"&gt;
 📌 개념
 &lt;a class="heading-anchor" href="#-%ea%b0%9c%eb%85%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;RDB는 &lt;strong&gt;특정 시점의 메모리 상태를 스냅샷 형태로 저장&lt;/strong&gt;하는 방식입니다.
이 스냅샷은 &lt;code&gt;.rdb&lt;/code&gt; 확장자의 파일(&lt;code&gt;dump.rdb&lt;/code&gt;)로 저장되며, Redis 부팅 시 해당 파일을 읽어 데이터를 복원합니다.&lt;/p&gt;
&lt;h3 id="-동작-원리"&gt;
 📌 동작 원리
 &lt;a class="heading-anchor" href="#-%eb%8f%99%ec%9e%91-%ec%9b%90%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;redis.conf 파일의 &lt;code&gt;save&lt;/code&gt; 옵션을 통해 주기적인 스냅샷 저장 조건을 정의합니다.
예를 들어:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;save 60 10&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;– 60초 동안 10개 이상의 키 변경이 발생하면 snapshot 저장합니다.
여러 조건이 있을 경우 &lt;strong&gt;조건 중 하나라도 만족하면 저장&lt;/strong&gt;됩니다.&lt;/p&gt;
&lt;h3 id="-예시-설정"&gt;
 📌 예시 설정
 &lt;a class="heading-anchor" href="#-%ec%98%88%ec%8b%9c-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;save 3600 1
save 300 100
save 60 10000&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이는 세 조건 중 하나라도 만족되면 스냅샷이 실행됩니다.&lt;/p&gt;
&lt;h3 id="-특징--장점--단점"&gt;
 📌 특징 – 장점 &amp;amp; 단점
 &lt;a class="heading-anchor" href="#-%ed%8a%b9%ec%a7%95--%ec%9e%a5%ec%a0%90--%eb%8b%a8%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;장점&lt;/th&gt;
					&lt;th&gt;단점&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;✨ 작은 파일로 관리가 쉬움&lt;/td&gt;
					&lt;td&gt;⚠ 스냅샷 사이 데이터 유실 가능&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;✨ 빠른 복구 가능&lt;/td&gt;
					&lt;td&gt;⚠ fork 기반이라 리소스 소모&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-2-aof-append-only-file-방식"&gt;
 🧠 2. AOF (Append Only File) 방식
 &lt;a class="heading-anchor" href="#-2-aof-append-only-file-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="-개념-1"&gt;
 📌 개념
 &lt;a class="heading-anchor" href="#-%ea%b0%9c%eb%85%90-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;AOF는 &lt;strong&gt;모든 쓰기 명령어(SET, DEL 등)를 로그 형태로 저장&lt;/strong&gt;하는 방식입니다.&lt;br&gt;
Redis 재부팅 시 이 로그를 순차적으로 재실행하여 데이터를 복원합니다.&lt;/p&gt;
&lt;h3 id="-동작-원리-1"&gt;
 📌 동작 원리
 &lt;a class="heading-anchor" href="#-%eb%8f%99%ec%9e%91-%ec%9b%90%eb%a6%ac-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Redis는 쓰기 명령 실행 시마다 로그 파일(&lt;code&gt;appendonly.aof&lt;/code&gt;)에 명령을 기록하며,&lt;br&gt;
로그 파일은 텍스트 형식이므로 사람이 직접 읽거나 수정할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-aof-rewrite-압축"&gt;
 📍 AOF Rewrite (압축)
 &lt;a class="heading-anchor" href="#-aof-rewrite-%ec%95%95%ec%b6%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;AOF 파일은 계속 기록되므로 파일 크기가 커지는 경향이 있습니다.&lt;br&gt;
이때 &lt;strong&gt;Rewrite&lt;/strong&gt; 기능을 사용하면 불필요한 명령을 제거하여 파일 크기를 줄일 수 있습니다.&lt;/p&gt;
&lt;p&gt;예를 들어 같은 키에 대해 &lt;code&gt;SET&lt;/code&gt; 명령이 100회 실행되었을 때, 마지막 값만 기록하면 충분하므로 Rewrite는 파일을 최적화합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-rdb-vs-aof--비교"&gt;
 📊 RDB vs AOF – 비교
 &lt;a class="heading-anchor" href="#-rdb-vs-aof--%eb%b9%84%ea%b5%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;RDB&lt;/th&gt;
					&lt;th&gt;AOF&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;저장 방식&lt;/td&gt;
					&lt;td&gt;스냅샷 시점 저장&lt;/td&gt;
					&lt;td&gt;모든 쓰기 명령 저장&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;복구 시점&lt;/td&gt;
					&lt;td&gt;가장 최근 스냅샷&lt;/td&gt;
					&lt;td&gt;전체 로그 재실행&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;파일 크기&lt;/td&gt;
					&lt;td&gt;작음&lt;/td&gt;
					&lt;td&gt;상대적으로 큼&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;복구 성능&lt;/td&gt;
					&lt;td&gt;빠름&lt;/td&gt;
					&lt;td&gt;느림 (로그 재실행)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;데이터 완전성&lt;/td&gt;
					&lt;td&gt;일부 유실 가능&lt;/td&gt;
					&lt;td&gt;대부분 보장&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-실습-예시-docker"&gt;
 🧩 실습 예시 (Docker)
 &lt;a class="heading-anchor" href="#-%ec%8b%a4%ec%8a%b5-%ec%98%88%ec%8b%9c-docker" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="rdb-기반-백업"&gt;
 RDB 기반 백업
 &lt;a class="heading-anchor" href="#rdb-%ea%b8%b0%eb%b0%98-%eb%b0%b1%ec%97%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker run &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; -v &lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;/redis.conf:/redis.conf &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; --name redis-rdb &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; redis redis-server /redis.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Redis에 데이터 입력 후 RDB 조건 만족 여부를 확인해 보세요.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="aof-기반-백업"&gt;
 AOF 기반 백업
 &lt;a class="heading-anchor" href="#aof-%ea%b8%b0%eb%b0%98-%eb%b0%b1%ec%97%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;redis.conf에서 다음 설정 활성화:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;appendonly yes&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이후 컨테이너를 실행하면 AOF 로그로 백업이 수행됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-참고--운영-환경-전략"&gt;
 🧠 참고 – 운영 환경 전략
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0--%ec%9a%b4%ec%98%81-%ed%99%98%ea%b2%bd-%ec%a0%84%eb%9e%b5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;운영 환경에서는 RDB와 AOF를 &lt;strong&gt;조합하여 사용&lt;/strong&gt;하는 것이 일반적입니다.
– RDB로 주기적인 전체 스냅샷 저장
– AOF로 세부 로그 저장 및 복원 안정성 확보&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-마무리"&gt;
 📌 마무리
 &lt;a class="heading-anchor" href="#-%eb%a7%88%eb%ac%b4%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Redis 백업은 단순히 데이터를 디스크에 저장하는 것이 아니라,
&lt;strong&gt;데이터 유실을 최소화하고 필요한 복구 전략을 갖추는 작업&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;✔ RDB: 빠른 백업 &amp;amp; 빠른 복구
✔ AOF: 높은 데이터 완전성&lt;/p&gt;
&lt;p&gt;필요하다면 두 방식을 &lt;strong&gt;동시 적용&lt;/strong&gt;하여 안정성과 성능 두 가지 모두 확보하는 것이 좋습니다.&lt;/p&gt;
&lt;hr&gt;</description></item><item><title>[Kubernetes] kubectl create command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-create/</link><pubDate>Thu, 30 Mar 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-create/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="자주-사용하는-command"&gt;
 자주 사용하는 Command
 &lt;a class="heading-anchor" href="#%ec%9e%90%ec%a3%bc-%ec%82%ac%ec%9a%a9%ed%95%98%eb%8a%94-command" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create pod
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Nginx 이미지를 사용하는 my-pod 이름을 가진 Pod 리소스를 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl create pod my-pod --image&lt;span class="o"&gt;=&lt;/span&gt;nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create deployment
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Nginx 이미지를 사용하는 my-deployment 이름을 가진 Deployment 리소스를 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl create deployment my-deployment --image&lt;span class="o"&gt;=&lt;/span&gt;nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 80 포트를 8080 포트로 매핑하는 my-service 이름을 가진 ClusterIP Service 리소스를 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl create service clusterip my-service --tcp&lt;span class="o"&gt;=&lt;/span&gt;80:8080&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create configmap
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# key1=value1, key2=value2 데이터를 가진 my-config 이름을 가진 ConfigMap 리소스를 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl create configmap my-config --from-literal&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;key1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;value1 --from-literal&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;key2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;value2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create secret
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# password=1234 데이터를 가진 my-secret 이름을 가진 Secret 리소스를 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl create secret generic my-secret --from-literal&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1234&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--dry-run&lt;/code&gt;: 리소스를 생성하지 않고 생성 결과만 미리 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create deployment my-deployment --image&lt;span class="o"&gt;=&lt;/span&gt;nginx --dry-run&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-o&lt;/code&gt;, &lt;code&gt;--output&lt;/code&gt;: 생성한 리소스의 정보를 출력 형식을 지정, json 또는 yaml 형식을 사용할 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create deployment my-deployment --image&lt;span class="o"&gt;=&lt;/span&gt;nginx -o json &lt;span class="o"&gt;(&lt;/span&gt;JSON 형식으로 생성한 deployment 정보를 출력&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--save-config&lt;/code&gt;: 리소스를 생성할 때, 생성한 리소스의 구성을 클러스터 상태 저장소에 저장&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Nginx 이미지를 사용하는 my-deployment 이름을 가진 Deployment 리소스를 생성하면서, 리소스의 구성을 클러스터 상태 저장소에 저장&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl create deployment my-deployment --image&lt;span class="o"&gt;=&lt;/span&gt;nginx --save-config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--image&lt;/code&gt;: Pod 또는 Deployment 리소스를 생성할 때, 사용할 컨테이너 이미지를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Nginx 이미지를 사용하는 my-pod 이름을 가진 Pod 리소스를 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl create pod my-pod --image&lt;span class="o"&gt;=&lt;/span&gt;nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-f&lt;/code&gt;, &lt;code&gt;--filename&lt;/code&gt;: YAML 또는 JSON 파일을 사용하여 리소스를 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pod.yaml 파일에 정의된 Pod 리소스를 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl create -f pod.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-n&lt;/code&gt;, &lt;code&gt;--namespace&lt;/code&gt;: 리소스가 생성될 네임스페이스를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름을 가진 Deployment 리소스를 my-namespace 네임스페이스에 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl create deployment my-deployment --image&lt;span class="o"&gt;=&lt;/span&gt;nginx -n my-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--restart-policy&lt;/code&gt;: 컨테이너의 재시작 정책을 지정, Always, OnFailure, Never 중 하나를 선택할 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Nginx 이미지를 사용하는 my-pod 이름을 가진 Pod 리소스를 생성하면서, 컨테이너의 재시작 정책을 OnFailure로 지정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl create pod my-pod --image&lt;span class="o"&gt;=&lt;/span&gt;nginx --restart-policy&lt;span class="o"&gt;=&lt;/span&gt;OnFailure&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubectl scale command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-scale/</link><pubDate>Tue, 21 Mar 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-scale/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl scale deployment &lt;span class="o"&gt;[&lt;/span&gt;deployment name&lt;span class="o"&gt;]&lt;/span&gt; --replicas&lt;span class="o"&gt;=[&lt;/span&gt;수정할 replica 수&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름을 가진 deployment의 replica 수를 3개로 조정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl scale deployment my-deployment --replicas&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--current-replicas&lt;/code&gt;: 현재 replica 수를 지정하며, 이 값을 지정하면 &amp;ndash;replicas 옵션으로 지정한 값과 함께 replica 수를 변경한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 현재 1개의 replica가 있는 my-deployment 이름을 가진 deployment의 replica 수를 3개로 조정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl scale deployment my-deployment --current-replicas&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; --replicas&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--resource-version&lt;/code&gt;: 리소스 버전을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름을 가진 deployment의 replica 수를 3개로 조정하면서, 리소스 버전을 4로 지정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl scale deployment my-deployment --replicas&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; --resource-version&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-n&lt;/code&gt;, &lt;code&gt;--namespace&lt;/code&gt;: 리소스가 위치한 namespace를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름을 가진 deployment의 replica 수를 3개로 조정하면서, my-namespace namespace에 위치한 리소스를 조정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl scale deployment my-deployment --replicas&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; -n my-namespace &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--timeout&lt;/code&gt;: replica 수를 조정할 때, 타임아웃을 설정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름을 가진 deployment의 replica 수를 3개로 조정하면서, 타임아웃을 60초로 설정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl scale deployment my-deployment --replicas&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; --timeout&lt;span class="o"&gt;=&lt;/span&gt;60s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--wait&lt;/code&gt;: replica 수를 조정한 후 변경이 완료될 때까지 대기&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름을 가진 deployment의 replica 수를 3개로 조정하면서, 변경이 완료될 때까지 대기&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl scale deployment my-deployment --replicas&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; --wait&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] Host Network</title><link>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-host-network/</link><pubDate>Thu, 02 Mar 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-host-network/</guid><description>&lt;h2 id="hostnetwork-false"&gt;
 hostNetwork: false
 &lt;a class="heading-anchor" href="#hostnetwork-false" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;test-pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx-port&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostIP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;Node IP]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;30123&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8888&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/etc/nginx/conf.d/default.conf&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx-conf&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx-conf&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/root/default.conf&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;File&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;해당 Pod가 배포된 Node의 IP + NodePort로 해당 서비스에 접근이 가능해진다.&lt;/li&gt;
&lt;li&gt;curl [hostIP]:[hostPort]로 nginx 웹서버의 정상적인 응답을 받을 수 있게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="hostnetwork-true"&gt;
 hostNetwork: true
 &lt;a class="heading-anchor" href="#hostnetwork-true" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;danger-pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostNetwork&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx-port&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8888&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8888&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/etc/nginx/conf.d/default.conf&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx-conf&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx-conf&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/root/default.conf&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;File&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;hostNetwork를 true로 설정하게되면 Pod가 자신이 배포된 node의 IP를 가지는 것을 확인할 수 있다.&lt;/li&gt;
&lt;li&gt;host의 Network를 사용하기 때문에 containerPort와 hostPort를 동일하게 설정해야한다. 그렇지않으면 에러가 발생할 것이다&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="해당-옵션을-사용할-시-고려할-점"&gt;
 해당 옵션을 사용할 시, 고려할 점
 &lt;a class="heading-anchor" href="#%ed%95%b4%eb%8b%b9-%ec%98%b5%ec%85%98%ec%9d%84-%ec%82%ac%ec%9a%a9%ed%95%a0-%ec%8b%9c-%ea%b3%a0%eb%a0%a4%ed%95%a0-%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="spechostnetwork"&gt;
 spec.hostNetwork
 &lt;a class="heading-anchor" href="#spechostnetwork" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;true와 false 두가지 옵션이 존재한다(미 설정시, Default: false).&lt;/li&gt;
&lt;li&gt;해당 값을 true로 설정 시, Pod의 IP가 Pod가 배포된 Node의 IP로 설정된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="speccontainersportscontainerport"&gt;
 spec.containers[].ports[].containerPort
 &lt;a class="heading-anchor" href="#speccontainersportscontainerport" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;해당 설정을 명시한다고해서 해당 container의 Port가 open되는 것은 아니다.&lt;/li&gt;
&lt;li&gt;해당 옵션을 원하는 Port로 사용하기 위해서는 반드시 해당 container에 원하는 Port를 사용하는 서비스 등이 동작중이여야 한다.&lt;/li&gt;
&lt;li&gt;즉, container가 자체적으로 Port를 사용하고 있어야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="speccontainersportshostip"&gt;
 spec.containers[].ports[].hostIP
 &lt;a class="heading-anchor" href="#speccontainersportshostip" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;아무 IP나 사용하면안되고 Node 중 하나의 IP를 사용하여야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="speccontainersportshostport"&gt;
 spec.containers[].ports[].hostPort
 &lt;a class="heading-anchor" href="#speccontainersportshostport" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;0 &amp;lt; port &amp;lt; 65536 중에서 Port를 사용하면 된다.&lt;/li&gt;
&lt;li&gt;만약 hostNetwork 값을 true로 사용할 시, containerPort와 같은 값을 지정해야한다.&lt;/li&gt;
&lt;li&gt;역시나 해당 설정을 한다고해서 해당 Pod가 배포된 Node의 Port가 Open 되는 것은 아니다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] kubectl patch command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-patch/</link><pubDate>Tue, 21 Feb 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-patch/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl patch &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;수정할 필드&lt;span class="o"&gt;]=[&lt;/span&gt;새 값&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름의 배포의 replica 수를 3으로 변경할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl patch deployment my-deployment -p &lt;span class="s1"&gt;&amp;#39;{&amp;#34;spec&amp;#34;:{&amp;#34;replicas&amp;#34;:3}}&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-p&lt;/code&gt;, &lt;code&gt;--patch&lt;/code&gt;: JSON 포맷으로 수정 내용을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름의 배포의 replica 수를 3으로 변경&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl patch deployment my-deployment -p &lt;span class="s1"&gt;&amp;#39;{&amp;#34;spec&amp;#34;:{&amp;#34;replicas&amp;#34;:3}}&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--type&lt;/code&gt;: 수정 내용의 포맷을 지정. json, merge, strategic 중 하나를 지정할 수 있다. 기본값은 strategic&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름의 배포의 replica 수를 3으로 변경합니다. --type=json 옵션을 사용하여 JSON 포맷으로 수정 내용을 지정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl patch deployment my-deployment --type&lt;span class="o"&gt;=&lt;/span&gt;json -p &lt;span class="s1"&gt;&amp;#39;[{&amp;#34;op&amp;#34;:&amp;#34;replace&amp;#34;,&amp;#34;path&amp;#34;:&amp;#34;/spec/replicas&amp;#34;,&amp;#34;value&amp;#34;:3}]&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Spring] Spring Context란?</title><link>https://kyungryeol-yoon.github.io/backend/spring/spring-context/</link><pubDate>Sun, 05 Feb 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/spring/spring-context/</guid><description>&lt;h2 id="spring-context-란"&gt;
 &lt;strong&gt;Spring Context 란?&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#spring-context-%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Bean의 확장 버전으로 Spring이 Bean을 다루기 좀 더 쉽도록 기능들이 추가된 공간이다.&lt;/li&gt;
&lt;li&gt;단순히 Bean을 다루는 것 이외에도 추가적인 기능을 수행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="root-context-공통-부분"&gt;
 &lt;strong&gt;ROOT-CONTEXT (공통 부분)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#root-context-%ea%b3%b5%ed%86%b5-%eb%b6%80%eb%b6%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;모든 서블릿이 공유할 수 있는 Bean들이 모인 공간.&lt;/li&gt;
&lt;li&gt;DB와 관련된 Repository, Service 등이 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="serlvet-context-개별-부분"&gt;
 &lt;strong&gt;SERLVET-CONTEXT (개별 부분)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#serlvet-context-%ea%b0%9c%eb%b3%84-%eb%b6%80%eb%b6%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;서블릿 각자의 Bean들이 모인 공간.&lt;/li&gt;
&lt;li&gt;웹, 앱 마다 한 개씩 존재하므로 웹 앱 그자체를 의미하기도 함&lt;/li&gt;
&lt;li&gt;이 Context 내에서의 Bean들은 서로 공유될 수 없음&lt;/li&gt;
&lt;li&gt;MVC의 Controller가 이에 해당된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="context의-구조"&gt;
 &lt;strong&gt;Context의 구조&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#context%ec%9d%98-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1-application-context"&gt;
 &lt;strong&gt;1. Application Context&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#1-application-context" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Spring Context 기능의 중심인 최상위 인터페이스&lt;/li&gt;
&lt;li&gt;거의 Spring Context는 얘를 구현하며, 기능에 따라 앞에 &amp;ldquo;~~ApplicationContext&amp;quot;라고 붙음&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-abstractapplication-contextapplication-context가-기능의-중심적인-역할을-수행한다면-이-context는-application-context를-구현한-추상-클래스로-내부에-정의된-특수한-bean들을-등록할-수-있음"&gt;
 &lt;strong&gt;2. AbstractApplication ContextApplication Context가 기능의 중심적인 역할을 수행한다면 이 Context는 Application Context를 구현한 추상 클래스로, 내부에 정의된 특수한 Bean들을 등록할 수 있음.&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#2-abstractapplication-contextapplication-context%ea%b0%80-%ea%b8%b0%eb%8a%a5%ec%9d%98-%ec%a4%91%ec%8b%ac%ec%a0%81%ec%9d%b8-%ec%97%ad%ed%95%a0%ec%9d%84-%ec%88%98%ed%96%89%ed%95%9c%eb%8b%a4%eb%a9%b4-%ec%9d%b4-context%eb%8a%94-application-context%eb%a5%bc-%ea%b5%ac%ed%98%84%ed%95%9c-%ec%b6%94%ec%83%81-%ed%81%b4%eb%9e%98%ec%8a%a4%eb%a1%9c-%eb%82%b4%eb%b6%80%ec%97%90-%ec%a0%95%ec%9d%98%eb%90%9c-%ed%8a%b9%ec%88%98%ed%95%9c-bean%eb%93%a4%ec%9d%84-%eb%93%b1%eb%a1%9d%ed%95%a0-%ec%88%98-%ec%9e%88%ec%9d%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h3 id="3-genericapplication-context"&gt;
 &lt;strong&gt;3. GenericApplication Context&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#3-genericapplication-context" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;이름부터 제너릭이듯, Context로서의 기능을 거의 다 갖고있다.&lt;/li&gt;
&lt;li&gt;주로 수동으로 직접 Bean을 등록할 때 사용한다.&lt;/li&gt;
&lt;li&gt;XmlBeanDefinitionReader를 사용하여 xml 파일을 읽어와야 한다.&lt;/li&gt;
&lt;li&gt;등록 과정이 좀 번거로움&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="4-genericxmlapplicationcontext"&gt;
 &lt;strong&gt;4. GenericXmlApplicationContext&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#4-genericxmlapplicationcontext" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Bean을 배울 때 보통 가장 먼저 사용하는 인터페이스.&lt;/li&gt;
&lt;li&gt;AbstractApplication Context 을 확장한 인터페이스로 Context등록 과정이 간편화되어 있음&lt;/li&gt;
&lt;li&gt;1번과 달리 xml 파일을 읽어오는 과정이 내부에 있으며, 다양한 루트로 설정 파일을 불러올 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="5-classpathxmlapplicationcontext"&gt;
 &lt;strong&gt;5. ClassPathXmlApplicationContext&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#5-classpathxmlapplicationcontext" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;GenericXmlApplicationContext과 비슷하지만, 클래스 경로로 Context를 불러오는 데 특화되어 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="6-filesystemxmlapplicationcontext"&gt;
 &lt;strong&gt;6. FileSystemXmlApplicationContext&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#6-filesystemxmlapplicationcontext" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;말 그대로 클래스 경로가 아닌 실제 파일 경로로 불러온다.&lt;/li&gt;
&lt;li&gt;쓸데없이 길기도 하고 그냥 classPath를 사용하는 것을 권장 (정신건강에 좋음)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="web-application용-context-종류"&gt;
 &lt;strong&gt;Web Application용 Context 종류&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#web-application%ec%9a%a9-context-%ec%a2%85%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1-serlvetcontext"&gt;
 &lt;strong&gt;1. SerlvetContext&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#1-serlvetcontext" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Java 자체의 Context를 말함&lt;/li&gt;
&lt;li&gt;Spring도 Java로 만들어졌으므로, 모든 Spring Context는 ServletContext라고 할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-webapplicationcontext"&gt;
 &lt;strong&gt;2. WebApplicationContext&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#2-webapplicationcontext" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;웹 애플리케이션에 특화된 Context&lt;/li&gt;
&lt;li&gt;앞서 설명한 ROOT, Serlvet Context로 사용됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-configurationwebapplicationcontext"&gt;
 &lt;strong&gt;3. ConfigurationWebApplicationContext&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#3-configurationwebapplicationcontext" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;WebApplicationContext를 설정하는 데 쓰이는 Context&lt;/li&gt;
&lt;li&gt;WebContext를 설정해야할 때엔 Configurable 클래스로 바꿔서 설정함&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] ⏱️ Chrony NTP 시간 동기화 완벽 가이드: 설정부터 iburst 에러 해결까지</title><link>https://kyungryeol-yoon.github.io/linux/system/linux-chrony-ntp-time-sync/</link><pubDate>Thu, 26 Jan 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/system/linux-chrony-ntp-time-sync/</guid><description>&lt;p&gt;&lt;strong&gt;Chrony&lt;/strong&gt;는 Linux에서 NTP(Network Time Protocol) 기반 시간 동기화를 담당하는 데몬입니다.
기존 &lt;code&gt;ntpd&lt;/code&gt;를 대체하는 최신 표준으로, RHEL 7 / CentOS 7 이상과 Ubuntu 18.04 이상에서 기본 탑재되어 있습니다.
이 글에서는 &lt;code&gt;chrony.conf&lt;/code&gt; 설정 방법, &lt;code&gt;iburst&lt;/code&gt; 옵션, 특정 NTP 서버로의 교체, &lt;code&gt;chronyc&lt;/code&gt; 진단 명령어, 그리고 흔히 발생하는 에러 해결 방법을 실무 기준으로 정리합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-chrony란"&gt;
 🧭 Chrony란?
 &lt;a class="heading-anchor" href="#-chrony%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Chrony는 불안정한 네트워크 환경(재부팅, 슬립 모드, 간헐적 연결)에서도 빠르고 정확하게 시스템 시간을 동기화하는 NTP 구현체입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;NTP 서버 (Stratum 1/2)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; ↓ UDP 123
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; chronyd 데몬
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; 시스템 클럭 조정
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; (rtcsync) 하드웨어 클럭(RTC) 반영&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;ntpd&lt;/th&gt;
					&lt;th&gt;chronyd (Chrony)&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;수렴 속도&lt;/td&gt;
					&lt;td&gt;느림&lt;/td&gt;
					&lt;td&gt;빠름 (iburst)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;불안정 네트워크 대응&lt;/td&gt;
					&lt;td&gt;취약&lt;/td&gt;
					&lt;td&gt;강함&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;기본 탑재&lt;/td&gt;
					&lt;td&gt;RHEL 6 이하&lt;/td&gt;
					&lt;td&gt;RHEL 7+ / Ubuntu 18.04+&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;설정 파일&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/etc/ntp.conf&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/etc/chrony.conf&lt;/code&gt; 또는 &lt;code&gt;/etc/chrony/chrony.conf&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-설치"&gt;
 📦 설치
 &lt;a class="heading-anchor" href="#-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="rhel--centos--rocky-linux"&gt;
 RHEL / CentOS / Rocky Linux
 &lt;a class="heading-anchor" href="#rhel--centos--rocky-linux" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo dnf install chrony -y &lt;span class="c1"&gt;# RHEL 8+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 또는&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo yum install chrony -y &lt;span class="c1"&gt;# CentOS 7&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="ubuntu--debian"&gt;
 Ubuntu / Debian
 &lt;a class="heading-anchor" href="#ubuntu--debian" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get install chrony -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="서비스-시작-및-자동-실행-등록"&gt;
 서비스 시작 및 자동 실행 등록
 &lt;a class="heading-anchor" href="#%ec%84%9c%eb%b9%84%ec%8a%a4-%ec%8b%9c%ec%9e%91-%eb%b0%8f-%ec%9e%90%eb%8f%99-%ec%8b%a4%ed%96%89-%eb%93%b1%eb%a1%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now chronyd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl status chronyd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-chronyconf-주요-설정"&gt;
 ⚙️ chrony.conf 주요 설정
 &lt;a class="heading-anchor" href="#-chronyconf-%ec%a3%bc%ec%9a%94-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;설정 파일 경로:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ubuntu&lt;/strong&gt;: &lt;code&gt;/etc/chrony/chrony.conf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CentOS / RHEL / Rocky&lt;/strong&gt;: &lt;code&gt;/etc/chrony.conf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="pool-vs-server"&gt;
 pool vs server
 &lt;a class="heading-anchor" href="#pool-vs-server" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pool: NTP Pool 프로젝트에서 여러 서버를 자동 선택&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;pool 2.rocky.pool.ntp.org iburst
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# server: 특정 서버 한 대를 직접 지정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;server time.google.com iburst&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: &lt;code&gt;pool&lt;/code&gt;은 여러 서버를 자동으로 활용해 안정성이 높습니다. 사내 전용 NTP 서버가 있다면 &lt;code&gt;server&lt;/code&gt;로 직접 지정하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="주요-옵션-설명"&gt;
 주요 옵션 설명
 &lt;a class="heading-anchor" href="#%ec%a3%bc%ec%9a%94-%ec%98%b5%ec%85%98-%ec%84%a4%eb%aa%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;옵션&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;iburst&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;초기 동기화 시 패킷을 집중 전송하여 수렴 속도를 높임&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;prefer&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;해당 서버를 우선 참조 소스로 지정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;maxsources N&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;pool에서 사용할 최대 서버 수 (기본값: 4)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;minpoll N&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;최소 폴링 간격 (2^N 초, 기본 6 = 64초)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;maxpoll N&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;최대 폴링 간격 (2^N 초, 기본 10 = 1024초)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;makestep T S&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;T초 이상 오차 발생 시 처음 S번은 즉시 시간 점프&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;rtcsync&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;시스템 클럭을 하드웨어 RTC와 주기적으로 동기화&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;driftfile&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;클럭 드리프트 값 저장 경로&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;logdir&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;로그 저장 디렉토리&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="권장-기본-설정-예시"&gt;
 권장 기본 설정 예시
 &lt;a class="heading-anchor" href="#%ea%b6%8c%ec%9e%a5-%ea%b8%b0%eb%b3%b8-%ec%84%a4%ec%a0%95-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# /etc/chrony.conf (CentOS/RHEL 기준)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 기본 pool 대신 특정 서버로 교체 시 아래처럼 pool 줄을 주석 처리&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pool 2.centos.pool.ntp.org iburst&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;server 0.asia.pool.ntp.org iburst&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;server 1.asia.pool.ntp.org iburst&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;server 2.asia.pool.ntp.org iburst&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;server 3.asia.pool.ntp.org iburst&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 한국 공개 NTP 서버&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# server time.bora.net iburst&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# server time.kornet.net iburst&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 시간 오차 1.0초 초과 시 처음 3번은 즉시 점프 조정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;makestep 1.0 3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 하드웨어 RTC와 동기화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;rtcsync&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 클럭 드리프트 저장&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;driftfile /var/lib/chrony/drift&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 로그 디렉토리&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;logdir /var/log/chrony&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-특정-ntp-서버로-교체하기"&gt;
 🔄 특정 NTP 서버로 교체하기
 &lt;a class="heading-anchor" href="#-%ed%8a%b9%ec%a0%95-ntp-%ec%84%9c%eb%b2%84%eb%a1%9c-%ea%b5%90%ec%b2%b4%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;사내 NTP 서버 또는 클라우드 내부 NTP 서버로 교체하는 실무 절차입니다.&lt;/p&gt;
&lt;h3 id="1단계-설정-파일-편집"&gt;
 1단계: 설정 파일 편집
 &lt;a class="heading-anchor" href="#1%eb%8b%a8%ea%b3%84-%ec%84%a4%ec%a0%95-%ed%8c%8c%ec%9d%bc-%ed%8e%b8%ec%a7%91" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo vi /etc/chrony.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 또는 Ubuntu&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo vi /etc/chrony/chrony.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;기존 &lt;code&gt;pool&lt;/code&gt; 또는 &lt;code&gt;server&lt;/code&gt; 라인을 주석 처리하고 새 서버를 추가합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 기존 pool 비활성화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pool 2.centos.pool.ntp.org iburst&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 사내 NTP 서버로 교체&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;server 192.168.1.10 iburst&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;server 192.168.1.11 iburst&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="2단계-서비스-재시작"&gt;
 2단계: 서비스 재시작
 &lt;a class="heading-anchor" href="#2%eb%8b%a8%ea%b3%84-%ec%84%9c%eb%b9%84%ec%8a%a4-%ec%9e%ac%ec%8b%9c%ec%9e%91" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl restart chronyd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="3단계-동기화-상태-확인"&gt;
 3단계: 동기화 상태 확인
 &lt;a class="heading-anchor" href="#3%eb%8b%a8%ea%b3%84-%eb%8f%99%ea%b8%b0%ed%99%94-%ec%83%81%ed%83%9c-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chronyc sources -v&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;출력 예시:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;MS Name/IP address Stratum Poll Reach LastRx Last sample
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;===============================================================================
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;^* 192.168.1.10 2 6 377 23 +12us[ +8us] +/- 220us
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;^+ 192.168.1.11 2 6 377 24 -15us[ -10us] +/- 180us&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-클라우드-환경별-ntp-설정"&gt;
 ☁️ 클라우드 환경별 NTP 설정
 &lt;a class="heading-anchor" href="#-%ed%81%b4%eb%9d%bc%ec%9a%b0%eb%93%9c-%ed%99%98%ea%b2%bd%eb%b3%84-ntp-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;클라우드 인스턴스는 해당 클라우드 내부 NTP 서버를 사용하는 것이 정확도·안정성 측면에서 유리합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;클라우드&lt;/th&gt;
					&lt;th&gt;내부 NTP 서버&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;AWS&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;169.254.169.123&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;GCP&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;metadata.google.internal&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Azure&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;time.windows.com&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Naver Cloud&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;내부 NTP 서버 (VPC 설정 참고)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;AWS 환경 예시:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;server 169.254.169.123 prefer iburst minpoll 4 maxpoll 4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: &lt;code&gt;prefer&lt;/code&gt; 옵션으로 내부 서버를 우선 참조 소스로 지정하고, &lt;code&gt;minpoll&lt;/code&gt;/&lt;code&gt;maxpoll 4&lt;/code&gt;로 폴링 간격을 16초로 고정해 빠른 동기화를 유지할 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-chronyc-진단-명령어"&gt;
 🛠️ chronyc 진단 명령어
 &lt;a class="heading-anchor" href="#-chronyc-%ec%a7%84%eb%8b%a8-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="sources--ntp-소스-상태-확인"&gt;
 sources — NTP 소스 상태 확인
 &lt;a class="heading-anchor" href="#sources--ntp-%ec%86%8c%ec%8a%a4-%ec%83%81%ed%83%9c-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chronyc sources -v&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;소스 상태 기호&lt;/th&gt;
					&lt;th&gt;의미&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;현재 동기화 중인 기준 서버&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;+&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;신뢰할 수 있는 후보 서버&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;알고리즘에 의해 제외된 서버&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;?&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;연결 불가 / 응답 없음&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;x&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;거짓 서버(falseticker)로 판정됨&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="tracking--시스템-시간-동기화-세부-정보"&gt;
 tracking — 시스템 시간 동기화 세부 정보
 &lt;a class="heading-anchor" href="#tracking--%ec%8b%9c%ec%8a%a4%ed%85%9c-%ec%8b%9c%ea%b0%84-%eb%8f%99%ea%b8%b0%ed%99%94-%ec%84%b8%eb%b6%80-%ec%a0%95%eb%b3%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chronyc tracking&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;Reference ID : C0A8010A (192.168.1.10)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;Stratum : 3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;Ref time (UTC) : Sat Apr 26 12:00:00 2026
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;System time : 0.000012345 seconds fast of NTP time
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;Last offset : +0.000012345 seconds
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;RMS offset : 0.000015678 seconds
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;Frequency : 2.341 ppm fast
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;Residual freq : +0.001 ppm
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;Skew : 0.012 ppm
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;Root delay : 0.002345678 seconds
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;Root dispersion : 0.001234567 seconds&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="makestep--즉시-시간-강제-동기화"&gt;
 makestep — 즉시 시간 강제 동기화
 &lt;a class="heading-anchor" href="#makestep--%ec%a6%89%ec%8b%9c-%ec%8b%9c%ea%b0%84-%ea%b0%95%ec%a0%9c-%eb%8f%99%ea%b8%b0%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;시스템 시간이 크게 틀어졌을 때 즉시 보정합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo chronyc makestep
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 또는 -a 옵션으로 인증 우회&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo chronyc -a makestep&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="기타-유용한-명령어"&gt;
 기타 유용한 명령어
 &lt;a class="heading-anchor" href="#%ea%b8%b0%ed%83%80-%ec%9c%a0%ec%9a%a9%ed%95%9c-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chronyc sourcestats -v &lt;span class="c1"&gt;# 소스별 통계 (오프셋 히스토리, 지터 등)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;chronyc activity &lt;span class="c1"&gt;# 온라인/오프라인 서버 수 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;timedatectl status &lt;span class="c1"&gt;# 시스템 시간·타임존·NTP 상태 종합 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;timedatectl set-timezone Asia/Seoul &lt;span class="c1"&gt;# 타임존 변경&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-타임존-설정"&gt;
 🌏 타임존 설정
 &lt;a class="heading-anchor" href="#-%ed%83%80%ec%9e%84%ec%a1%b4-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;시간 동기화와 함께 타임존도 올바르게 설정해야 합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 현재 타임존 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;timedatectl status
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 한국 표준시로 변경&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;timedatectl set-timezone Asia/Seoul
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 변경 결과 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;date&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-방화벽-설정-udp-123"&gt;
 🔒 방화벽 설정 (UDP 123)
 &lt;a class="heading-anchor" href="#-%eb%b0%a9%ed%99%94%eb%b2%bd-%ec%84%a4%ec%a0%95-udp-123" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;NTP는 &lt;strong&gt;UDP 123번 포트&lt;/strong&gt;를 사용합니다. 클라이언트가 외부 NTP 서버에 접근하려면 아웃바운드 규칙이 열려 있어야 합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# firewalld (RHEL/CentOS)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo firewall-cmd --add-service&lt;span class="o"&gt;=&lt;/span&gt;ntp --permanent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo firewall-cmd --reload
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# UFW (Ubuntu)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;sudo ufw allow 123/udp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# iptables 직접 설정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;sudo iptables -A OUTPUT -p udp --dport &lt;span class="m"&gt;123&lt;/span&gt; -j ACCEPT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;클라우드 환경이라면 &lt;strong&gt;보안 그룹(Security Group)&lt;/strong&gt; 의 아웃바운드 규칙에서도 UDP 123번을 허용해야 합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문-및-트러블슈팅"&gt;
 ❓ 자주 묻는 질문 및 트러블슈팅
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8-%eb%b0%8f-%ed%8a%b8%eb%9f%ac%eb%b8%94%ec%8a%88%ed%8c%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-chronyc-sources에서-모든-서버가--로-표시됩니다"&gt;
 Q. chronyc sources에서 모든 서버가 &lt;code&gt;?&lt;/code&gt; 로 표시됩니다
 &lt;a class="heading-anchor" href="#q-chronyc-sources%ec%97%90%ec%84%9c-%eb%aa%a8%eb%93%a0-%ec%84%9c%eb%b2%84%ea%b0%80--%eb%a1%9c-%ed%91%9c%ec%8b%9c%eb%90%a9%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;→ NTP 서버에 연결이 안 되는 상태입니다. 다음 순서로 확인합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 방화벽 UDP 123 허용 여부 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;sudo firewall-cmd --list-all
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. NTP 서버 IP 도달 가능 여부 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;ping -c &lt;span class="m"&gt;3&lt;/span&gt; time.google.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. UDP 123 연결 테스트&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;sudo nc -uzv time.google.com &lt;span class="m"&gt;123&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 4. 서비스 재시작&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl restart chronyd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="q-iburst-옵션을-추가했는데-시간이-빨리-맞지-않습니다"&gt;
 Q. iburst 옵션을 추가했는데 시간이 빨리 맞지 않습니다
 &lt;a class="heading-anchor" href="#q-iburst-%ec%98%b5%ec%85%98%ec%9d%84-%ec%b6%94%ea%b0%80%ed%96%88%eb%8a%94%eb%8d%b0-%ec%8b%9c%ea%b0%84%ec%9d%b4-%eb%b9%a8%eb%a6%ac-%eb%a7%9e%ec%a7%80-%ec%95%8a%ec%8a%b5%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;→ &lt;code&gt;iburst&lt;/code&gt;는 초기 동기화 속도를 높이지만, 시간 오차가 크면 &lt;code&gt;makestep&lt;/code&gt;으로 즉시 강제 보정해야 합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo chronyc makestep
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;chronyc tracking &lt;span class="c1"&gt;# System time 값이 줄어드는지 확인&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="q-iburst를-설정-파일에-단독-라인으로-넣으면-에러가-납니다"&gt;
 Q. &lt;code&gt;iburst&lt;/code&gt;를 설정 파일에 단독 라인으로 넣으면 에러가 납니다
 &lt;a class="heading-anchor" href="#q-iburst%eb%a5%bc-%ec%84%a4%ec%a0%95-%ed%8c%8c%ec%9d%bc%ec%97%90-%eb%8b%a8%eb%8f%85-%eb%9d%bc%ec%9d%b8%ec%9c%bc%eb%a1%9c-%eb%84%a3%ec%9c%bc%eb%a9%b4-%ec%97%90%eb%9f%ac%ea%b0%80-%eb%82%a9%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;→ &lt;code&gt;iburst&lt;/code&gt;는 독립 지시어가 아니라 &lt;code&gt;server&lt;/code&gt; 또는 &lt;code&gt;pool&lt;/code&gt; 명령어의 &lt;strong&gt;옵션&lt;/strong&gt;입니다. 반드시 서버 주소 뒤에 붙여야 합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 잘못된 예&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pool 2.centos.pool.ntp.org&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;iburst # ❌ 단독 라인 — 문법 오류&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 올바른 예&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;server time.google.com iburst # ✅ server 뒤에 옵션으로 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;pool 2.centos.pool.ntp.org iburst # ✅ pool 뒤에도 동일하게&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="q-시간이-동기화되었는지-한-번에-확인하는-방법은"&gt;
 Q. 시간이 동기화되었는지 한 번에 확인하는 방법은?
 &lt;a class="heading-anchor" href="#q-%ec%8b%9c%ea%b0%84%ec%9d%b4-%eb%8f%99%ea%b8%b0%ed%99%94%eb%90%98%ec%97%88%eb%8a%94%ec%a7%80-%ed%95%9c-%eb%b2%88%ec%97%90-%ed%99%95%ec%9d%b8%ed%95%98%eb%8a%94-%eb%b0%a9%eb%b2%95%ec%9d%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;timedatectl status &lt;span class="p"&gt;|&lt;/span&gt; grep -E &lt;span class="s2"&gt;&amp;#34;synchronized|NTP&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# System clock synchronized: yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# NTP service: active&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-요약"&gt;
 ✅ 요약
 &lt;a class="heading-anchor" href="#-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;단계&lt;/th&gt;
					&lt;th&gt;명령어&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;설치&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;dnf install chrony&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;설정 파일 편집&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;vi /etc/chrony.conf&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;기존 pool 주석, 새 server 추가&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;server [IP] iburst&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;서비스 재시작&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;systemctl restart chronyd&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;동기화 상태 확인&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;chronyc sources -v&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;즉시 강제 동기화&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;chronyc makestep&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;타임존 설정&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;timedatectl set-timezone Asia/Seoul&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;</description></item><item><title>[Kubernetes] kubectl apply command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-apply/</link><pubDate>Tue, 10 Jan 2023 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-apply/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f &lt;span class="o"&gt;[&lt;/span&gt;파일 경로&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# deployment.yaml 파일에 정의된 deployment 리소스를 Cluster에 배포&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f deployment.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-f&lt;/code&gt;, &lt;code&gt;--filename&lt;/code&gt;: 배포할 YAML 또는 JSON 파일의 경로를 지정할 수 있으며, 파일 이름이나 directory 이름을 지정할 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# deployment.yaml 파일에 정의된 리소스를 배포&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f deployment.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--prune&lt;/code&gt;: 새로운 YAML 또는 JSON 파일에 정의되지 않은 기존 리소스를 삭제&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# deployment.yaml 파일에 정의된 리소스를 배포하면서, 새로운 파일에 정의되지 않은 기존 리소스를 삭제&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply --prune -f deployment.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--selector&lt;/code&gt;: 리소스를 선택하는 Label selector를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# deployment.yaml 파일에 정의된 리소스를 배포하면서, app=nginx Label을 가진 기존 리소스를 선택&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply --selector &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nginx -f deployment.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-R&lt;/code&gt;, &lt;code&gt;--recursive&lt;/code&gt;: directory 내부의 모든 YAML 또는 JSON 파일을 배포&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# deployments directory 내부의 모든 YAML 또는 JSON 파일을 배포&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -R -f ./deployments&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--validate&lt;/code&gt;: 배포하기 전 YAML 또는 JSON 파일을 검증&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# YAML 또는 JSON 파일을 검증하지 않고 배포&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply --validate&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; -f deployment.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--overwrite&lt;/code&gt;: 기존 리소스를 덮어쓰기 한다. &lt;code&gt;--force&lt;/code&gt;와 유사하지만, 롤링 업데이트 중에 리소스를 강제로 교체할 때 사용&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# nginx-deployment.yaml 파일을 사용하여 Deployment 오브젝트를 생성하거나 수정하되, 이미 존재하는 경우 덮어쓰기(overwrite)를 하라는 옵션&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply --overwrite -f nginx-deployment.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--force&lt;/code&gt;: 기존 리소스를 덮어쓰기&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# deployment.yaml 파일에 정의된 리소스를 Cluster에 배포하면서, 기존 리소스를 덮어쓴다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply --force -f deployment.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--force-conflicts&lt;/code&gt;: 리소스 간의 충돌을 해결하기 위해 강제로 덮어쓰기 한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# deployment.yaml 파일에 정의된 리소스를 Cluster에 배포하면서, 리소스 간의 충돌이 발생하면 강제로 덮어쓴다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply --force-conflicts -f deployment.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--prune-whitelist&lt;/code&gt;: &lt;code&gt;--prune&lt;/code&gt; 옵션과 함께 사용되며, 삭제하지 않을 리소스를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# deployment.yaml 파일에 정의된 리소스를 배포하면서, configmap 리소스는 삭제하지 않도록 지정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply --prune --prune-whitelist&lt;span class="o"&gt;=&lt;/span&gt;configmap -f deployment.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--dry-run&lt;/code&gt;: 배포하지 않고 배포 결과만 미리 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# deployment.yaml 파일에 정의된 리소스를 배포하지 않고, 배포 결과만 미리 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply --dry-run -f deployment.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] Affinity</title><link>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-affinity/</link><pubDate>Fri, 09 Dec 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-affinity/</guid><description>&lt;h2 id="affinity"&gt;
 Affinity?
 &lt;a class="heading-anchor" href="#affinity" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Affinity란 선호도란 뜻이다. Pod는 항상 Node에서 띄워져야 하는데, 이러한 배치를 함에 있어 선호하는 Node나 Pod를 설정할 수 있는 리소스이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="affinity-종류"&gt;
 Affinity 종류
 &lt;a class="heading-anchor" href="#affinity-%ec%a2%85%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;nodeAffinity는 어떤 Node를 선호할 것인가? 에 관련한 리소스이다. 즉, Pod를 배치할 때 어떤 Node에 스케쥴링할지 설정을 해준다.&lt;/li&gt;
&lt;li&gt;podAffinity는 Pod가 배치될 때, 실행 중인 Pod들 중에 선호하는 Pod를 찾아 해당 Pod와 동일한 Node로 배치하는 걸 설정해준다.&lt;/li&gt;
&lt;li&gt;podAnitAffinity는 실행 중인 Pod들 중에, 선호하지 않은 Pod가 실행 중인 Node는 피해서 배치를 하겠다는 걸 설정해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="nodeaffinity"&gt;
 nodeAffinity?
 &lt;a class="heading-anchor" href="#nodeaffinity" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;선호하는 노드를 설정하는 방법으로, nodeSelector 보다 확장된 Label Selector 기능을 지원한다. 그래서 좀 더 실무환경에 적합한 Pod 배치 전략이다.&lt;/li&gt;
&lt;li&gt;matchExpressions 사용 가능하다. (In, NotIn, Exists, DoesNotExist, Gt, Lt 등의 옵션이 있다.)&lt;/li&gt;
&lt;li&gt;여러 유즈케이스에 활용 가능한 2가지 옵션이 있는데. Hard, Soft로 나뉜다. 매우 조건이 길기 때문에 2등분해서 의미를 이해하면 좋다.
&lt;ul&gt;
&lt;li&gt;반드시 충족해야 하는 조건 (Hard)
&lt;ul&gt;
&lt;li&gt;requiredDuringSchedulingIgnoredDuringExecution : &lt;code&gt;스케쥴링하는 동안 꼭 필요한&lt;/code&gt; 조건
&lt;ul&gt;
&lt;li&gt;즉, 스케쥴링되는 워크로드에는 필수 조건이고, 실행 중인 워크로드는 조건을 무시한다는 의미이다.&lt;/li&gt;
&lt;li&gt;requiredDuringSchedulingIgnoredDuringExecution를 구성하는 매니페스트 파일&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;...✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;affinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeAffinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeSelectorTerms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;matchExpressions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;disktype&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;In&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ssd&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;선호하는 조건 (Soft)
&lt;ul&gt;
&lt;li&gt;preferredDuringSchedulingIgnoredDuringExecution : &lt;code&gt;스케쥴링하는 동안 만족하면 좋은&lt;/code&gt; 조건입니다. 꼭 이 조건을 만족해야하는 것은 아니라는 의미입니다.
&lt;ul&gt;
&lt;li&gt;즉, 스케쥴링되는 워크로드에는 선호 조건이고, 실행 중인 워크로드는 조건을 무시한다는 의미이다.&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;...✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;affinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeAffinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;preferredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;preference&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;matchExpressions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;disktype&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;In&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;hdd&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;용어 설명:
&lt;ul&gt;
&lt;li&gt;IgnoredDuringExecution: 실행 중인 워크로드에 대해서는 해당 규칙을 무시한다.&lt;/li&gt;
&lt;li&gt;RequiredDuringExecution: 위와 반대개념으로 실행 중인 워크로드에 대해서 해당 규칙을 반드시 필요로 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;key 필드 값&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;In&lt;/td&gt;
					&lt;td&gt;values[] 필드에 설정한 값 중 레이블에 있는 값과 일치하는 것이 하나라도 있는지 확인합니다.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Notln&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;In&lt;/code&gt;과 반대로 values[]에 있는 값 모두와 맞지 않는 지 확인합니다.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Exists&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;key&lt;/code&gt; 필드에 설정한 값이 레이블에 있는지만 확인합니다. (values[] 필드가 필요 없습니다.)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;DoseNotExist&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Exists&lt;/code&gt;와 반대로 노드의 레이블에 &lt;code&gt;key&lt;/code&gt; 필드 값이 없는지만 확인합니다.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Gt&lt;/td&gt;
					&lt;td&gt;Greater than의 약자로 values[] 필드에 설정된 값이 설정된 값 보다 더 큰 숫자형 데이터 인지 확인합니다. 이 때 values[] 필드에는 값이 하나만 있어야 합니다.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Lt&lt;/td&gt;
					&lt;td&gt;Lower than의 약자로 values[] 필드에 설정된 값이 설정된 값 보다 더 작은 숫자형 데이터 인지 확인합니다. 이 때 values[] 필드에는 값이 하나만 있어야 합니다.&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="nodeaffinity-세팅"&gt;
 nodeAffinity 세팅
 &lt;a class="heading-anchor" href="#nodeaffinity-%ec%84%b8%ed%8c%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;node-affinity-required&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginxdemos/hello:plain-text&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;affinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeAffinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeSelectorTerms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;matchExpressions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;team&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;In&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;blue&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;red&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;operator In은 or 연산자라고 이해하면 된다. 즉, key가 team이고, value가 blue 혹은 red인 조건을 필수로 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;node-affinity-preferred&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginxdemos/hello:plain-text&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;affinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeAffinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;preferredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;40&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;preference&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchExpressions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;team&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;In&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;green&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;operator In은 or 연산자라고 이해하면 된다. 즉, key가 team이고, value가 green인 조건을 선호 한다.&lt;/li&gt;
&lt;li&gt;preferred는 weight가 있고, 각각에 matchExpressions을 넣는 구조로 되어 있다.
&lt;ul&gt;
&lt;li&gt;weight는 0~100 사이의 값을 가질 수 있다. 각각의 rule을 기반으로 weight를 설정해서 점수를 줌으로써 Pod가 어떤 Node에 최종 배치될지 우선순위를 설정하는 것으로 이해하면 된다.&lt;/li&gt;
&lt;li&gt;즉, weight는 여러개 설정할 수 있고, 점수를 매겨 우선순위를 결정하는 데 쓰이는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl label node kube-01 --overwrite &lt;span class="nv"&gt;team&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;green
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl label node kube-02 --overwrite &lt;span class="nv"&gt;team&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;red
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;kubectl label node kube-03 --overwrite &lt;span class="nv"&gt;team&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;blue&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;특정 node 각각에 label(key-valu)를 지정하는 set-node-labels.sh 스크립트이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;kubectl get nodes --show-labels
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;kubectl get nodes --label-columns team
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="podaffinity"&gt;
 podAffinity?
 &lt;a class="heading-anchor" href="#podaffinity" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;선호하는 파드를 설정하는 방법으로, 사용법은 nodeAffinity와 거의 동일하다.&lt;/li&gt;
&lt;li&gt;역시 여러 유즈케이스에 활용 가능한 2가지 옵션을 제공하며, Hard, Soft로 나뉜다. nodeAffinity와 동일하여 자세한 설명은 생략한다.
&lt;ul&gt;
&lt;li&gt;반드시 충족해야 하는 조건 (Hard)
&lt;ul&gt;
&lt;li&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;선호하는 조건 (Soft)
&lt;ul&gt;
&lt;li&gt;preferredDuringSchedulingIgnoredDuringExecution&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;podAffinity의 가장 중요한 부분은 다음의 개념이다.&lt;/li&gt;
&lt;li&gt;토폴로지 키 (Topology Key)
&lt;ul&gt;
&lt;li&gt;쿠버네티스 Node에 설정된 Label에 대해서, Label Selector를 수행할 노드의 범위를 결정한다.&lt;/li&gt;
&lt;li&gt;Topology Key는 노드의 레이블 key를 설정하는 것이며, 어떠한 값을 key name으로 넣어도 상관없지만 다음과 같은 3가지 key를 주로 쓴다.
&lt;ul&gt;
&lt;li&gt;Node 단위: kubernetes.io/hostname&lt;/li&gt;
&lt;li&gt;zone 단위: topology.kubernetes.io/zone
&lt;ul&gt;
&lt;li&gt;AZ(Availablity Zone: 가용영역)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;region 단위: topology.kubernetes.io/region
&lt;ul&gt;
&lt;li&gt;지역 (서울, 도쿄 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="podaffinity-세팅"&gt;
 podAffinity 세팅
 &lt;a class="heading-anchor" href="#podaffinity-%ec%84%b8%ed%8c%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mariadb:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;setting_password&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;MYSQL_DATABASE&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3306&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod-affinity-required&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginxdemos/hello:plain-text&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;affinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podAffinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;labelSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchExpressions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;In&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;topologyKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes.io/hostname&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# topologyKey: topology.kubernetes.io/zone&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# topologyKey: topology.kubernetes.io/region&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod-affinity-preferred&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginxdemos/hello:plain-text&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;affinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podAffinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;preferredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podAffinityTerm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labelSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchExpressions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;In&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;topologyKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes.io/hostname&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# topologyKey: topology.kubernetes.io/zone&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# topologyKey: topology.kubernetes.io/region&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="podantiaffinity"&gt;
 podAntiAffinity?
 &lt;a class="heading-anchor" href="#podantiaffinity" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;선호하지 않는 파드를 설정하는 방법으로, podAffinity를 podAntiAffinity로만 변경하면 사용법 동일하다.&lt;/li&gt;
&lt;li&gt;역시 여러 유즈케이스에 활용 가능한 2가지 옵션을 제공하며, Hard, Soft로 나뉜다. podAffinity와 동일하여 자세한 설명은 생략한다.
&lt;ul&gt;
&lt;li&gt;반드시 충족해야 하는 조건 (Hard)
&lt;ul&gt;
&lt;li&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;선호하는 조건 (Soft)
&lt;ul&gt;
&lt;li&gt;preferredDuringSchedulingIgnoredDuringExecution&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;토폴로지 키 (Topology Key)도 podAffinity와 같은 방식이다. 자세한 건 3번 챕터(podAffinity)를 참고하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="podantiaffinity-세팅"&gt;
 podAntiAffinity 세팅
 &lt;a class="heading-anchor" href="#podantiaffinity-%ec%84%b8%ed%8c%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod-anti-affinity-required&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginxdemos/hello:plain-text&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;affinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podAntiAffinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;labelSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchExpressions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;In&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;topologyKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes.io/hostname&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# topologyKey: topology.kubernetes.io/zone&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# topologyKey: topology.kubernetes.io/region&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod-anti-affinity-preferred&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginxdemos/hello:plain-text&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;affinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podAntiAffinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;preferredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podAffinityTerm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labelSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchExpressions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;In&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;topologyKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes.io/hostname&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# topologyKey: topology.kubernetes.io/zone&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# topologyKey: topology.kubernetes.io/region&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[PostgreSQL] VACUUM</title><link>https://kyungryeol-yoon.github.io/database/postgresql/postgresql-vacuum/</link><pubDate>Fri, 02 Dec 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/postgresql/postgresql-vacuum/</guid><description>&lt;div class="alert alert-warning"&gt;
 &lt;span class="alert-label"&gt;주의&lt;/span&gt;
 full 옵션으로 실행 시 데이터베이스가 잠김(Lock)처리가 되므로 운영중인 데이터베이스에서는 해당 옵션으로 사용하지 마세요.
&lt;/div&gt;

&lt;h2 id="db-전체-풀-실행"&gt;
 DB 전체 풀 실행
 &lt;a class="heading-anchor" href="#db-%ec%a0%84%ec%b2%b4-%ed%92%80-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vacuum full analyze&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="db-전체-간단하게-실행"&gt;
 DB 전체 간단하게 실행
 &lt;a class="heading-anchor" href="#db-%ec%a0%84%ec%b2%b4-%ea%b0%84%eb%8b%a8%ed%95%98%ea%b2%8c-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vacuum verbose analyze&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="해당-테이블만-간단하게-실행"&gt;
 해당 테이블만 간단하게 실행
 &lt;a class="heading-anchor" href="#%ed%95%b4%eb%8b%b9-%ed%85%8c%ec%9d%b4%eb%b8%94%eb%a7%8c-%ea%b0%84%eb%8b%a8%ed%95%98%ea%b2%8c-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vacuum analyse &lt;span class="o"&gt;[&lt;/span&gt;테이블 명&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="특정-테이블만-풀-실행"&gt;
 특정 테이블만 풀 실행
 &lt;a class="heading-anchor" href="#%ed%8a%b9%ec%a0%95-%ed%85%8c%ec%9d%b4%eb%b8%94%eb%a7%8c-%ed%92%80-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vacuum full &lt;span class="o"&gt;[&lt;/span&gt;테이블명&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Virtual Box] Ubuntu Terminal Not Open</title><link>https://kyungryeol-yoon.github.io/environment/virtualization/virtual-box-ubuntu-terminal-not-open/</link><pubDate>Thu, 01 Dec 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/environment/virtualization/virtual-box-ubuntu-terminal-not-open/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Ubuntu Desktop 이라면 &amp;lsquo;Ctrl + Alt + F3&amp;rsquo; 으로 TTY Terminal 접속
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo locale-gen --purge&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;재부팅 후 Termianl 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Ctrl+Alt+F1: Returns you to the graphical desktop environment log in screen
Ctrl+Alt+F2: Returns you to the graphical desktop environment
Ctrl+Alt+F3: Opens TTY 3
Ctrl+Alt+F4: Opens TTY 4
Ctrl+Alt+F5: Opens TTY 5
Ctrl+Alt+F6: Opens TTY 6&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Linux] Directory와 파일 용량 확인 명령어</title><link>https://kyungryeol-yoon.github.io/linux/system/linux-disk-usage/</link><pubDate>Thu, 24 Nov 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/system/linux-disk-usage/</guid><description>&lt;h2 id="du-directory명"&gt;
 du Directory명
 &lt;a class="heading-anchor" href="#du-directory%eb%aa%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Directory와 모든 하위 Directory의 용량을 표시해준다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;다음과 같이 명령하면 etc Directory와 그 하위 Directory의 사용량이 출력된다. 단위는 &lt;code&gt;kbyte&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;du /etc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="du--s-directory명"&gt;
 du -s Directory명
 &lt;a class="heading-anchor" href="#du--s-directory%eb%aa%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;선택한 Directory만의 용량을 알고 싶으면 s 옵션을 붙인다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;du -s /etc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="du--sh-directory명"&gt;
 du -sh Directory명
 &lt;a class="heading-anchor" href="#du--sh-directory%eb%aa%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;용량이 읽기 편한 단위로 나오게 하려면 h 옵션을 붙인다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;du -sh /etc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="du--sh-directory명-1"&gt;
 du -sh Directory명/*
 &lt;a class="heading-anchor" href="#du--sh-directory%eb%aa%85-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;예를 들어 etc Directory 바로 아래 Directory들의 용량을 알고 싶으면 다음과 같이 한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;du -sh /etc/*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="du--d-n-directory명"&gt;
 du -d N Directory명
 &lt;a class="heading-anchor" href="#du--d-n-directory%eb%aa%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;d 옵션으로 몇 단계 하위 Directory까지 출력할지 정할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;다음과 같이 명령하면 etc Directory의 2단계 하위 Directory까지의 용량을 출력한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;du -d &lt;span class="m"&gt;2&lt;/span&gt; /etc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="du--a-directory명"&gt;
 du -a Directory명
 &lt;a class="heading-anchor" href="#du--a-directory%eb%aa%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;a 옵션을 붙이면 Directory에 속한 파일의 용량도 같이 출력한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;du -a /etc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="디스크-사용량-확인"&gt;
 디스크 사용량 확인
 &lt;a class="heading-anchor" href="#%eb%94%94%ec%8a%a4%ed%81%ac-%ec%82%ac%ec%9a%a9%eb%9f%89-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;참고로 디스크 사용량은 df 명령어로 확인할 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;df -h&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] kubectl Connection Refused 문제 분석 및 해결</title><link>https://kyungryeol-yoon.github.io/kubernetes/troubleshooting/kubectl-connection-refused/</link><pubDate>Mon, 21 Nov 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/troubleshooting/kubectl-connection-refused/</guid><description>&lt;h2 id="-문제-발생-환경"&gt;
 🧪 문제 발생 환경
 &lt;a class="heading-anchor" href="#-%eb%ac%b8%ec%a0%9c-%eb%b0%9c%ec%83%9d-%ed%99%98%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntu 22.04 (VirtualBox VM)&lt;/li&gt;
&lt;li&gt;Kubernetes: kubeadm 기반 설치&lt;/li&gt;
&lt;li&gt;Kubernetes v1.25.x&lt;/li&gt;
&lt;li&gt;containerd v1.6.x&lt;/li&gt;
&lt;li&gt;CNI: Weave Net&lt;/li&gt;
&lt;li&gt;Swap off, Firewall off&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Master / Worker 노드 join은 정상적으로 완료된 상태였습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-문제-증상-분석"&gt;
 🔍 문제 증상 분석
 &lt;a class="heading-anchor" href="#-%eb%ac%b8%ec%a0%9c-%ec%a6%9d%ec%83%81-%eb%b6%84%ec%84%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1-kube-system-컴포넌트-crashloopbackoff"&gt;
 1️⃣ kube-system 컴포넌트 CrashLoopBackOff
 &lt;a class="heading-anchor" href="#1-kube-system-%ec%bb%b4%ed%8f%ac%eb%84%8c%ed%8a%b8-crashloopbackoff" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;kube-system&lt;/code&gt; 네임스페이스의 일부 컴포넌트가 반복적으로 재시작되었습니다.&lt;/p&gt;
&lt;p&gt;kube-proxy 로그에서 다음과 같은 메시지가 확인되었습니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;dial tcp &amp;lt;IP&amp;gt;:6443: connect: connection refused&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이는 kube-proxy가 API Server에 연결하지 못하고 있다는 의미입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="2-노드-ip-감지-오류-의심"&gt;
 2️⃣ 노드 IP 감지 오류 의심
 &lt;a class="heading-anchor" href="#2-%eb%85%b8%eb%93%9c-ip-%ea%b0%90%ec%a7%80-%ec%98%a4%eb%a5%98-%ec%9d%98%ec%8b%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;로그 중 다음 메시지도 확인되었습니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Can&amp;#39;t determine this node&amp;#39;s IP, assuming 127.0.0.1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;IP 인식 문제를 의심했으나, admin.conf 및 API Server 설정을 점검해도 해결되지 않았습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="3-proxy-mode--dual-stack-이슈-검토"&gt;
 3️⃣ Proxy Mode / Dual Stack 이슈 검토
 &lt;a class="heading-anchor" href="#3-proxy-mode--dual-stack-%ec%9d%b4%ec%8a%88-%ea%b2%80%ed%86%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Unknown proxy mode, assuming iptables proxy
kube-proxy running in dual-stack mode&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;IPv6 또는 proxy-mode 설정 문제도 의심했지만 직접적인 원인은 아니었습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="4-oom-여부-확인"&gt;
 4️⃣ OOM 여부 확인
 &lt;a class="heading-anchor" href="#4-oom-%ec%97%ac%eb%b6%80-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Memory 부족으로 프로세스가 종료되는지 확인했으나 OOM 로그는 발견되지 않았습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-최종-원인"&gt;
 🧠 최종 원인
 &lt;a class="heading-anchor" href="#-%ec%b5%9c%ec%a2%85-%ec%9b%90%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;문제의 핵심은 &lt;strong&gt;containerd와 kubelet 간 cgroup driver 불일치&lt;/strong&gt;였습니다.&lt;/p&gt;
&lt;p&gt;Ubuntu 22.04 기본 containerd 설정은 다음과 같습니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SystemdCgroup = false&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;하지만 kubelet은 systemd cgroup을 사용하는 경우가 많습니다.&lt;br&gt;
이 설정 불일치로 인해 kubelet ↔ container runtime 간 충돌이 발생하면서 API Server 연결이 불안정해진 것으로 보입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-해결-방법"&gt;
 ✅ 해결 방법
 &lt;a class="heading-anchor" href="#-%ed%95%b4%ea%b2%b0-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1-containerd-설정-수정"&gt;
 1️⃣ containerd 설정 수정
 &lt;a class="heading-anchor" href="#1-containerd-%ec%84%a4%ec%a0%95-%ec%88%98%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo sed -i &lt;span class="s1"&gt;&amp;#39;s/SystemdCgroup = false/SystemdCgroup = true/&amp;#39;&lt;/span&gt; /etc/containerd/config.toml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl restart containerd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;수정 후 kubelet도 재시작합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl restart kubelet&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="2-네트워크-브리지-설정-필요-시"&gt;
 2️⃣ 네트워크 브리지 설정 (필요 시)
 &lt;a class="heading-anchor" href="#2-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac-%eb%b8%8c%eb%a6%ac%ec%a7%80-%ec%84%a4%ec%a0%95-%ed%95%84%ec%9a%94-%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo modprobe br_netfilter
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /proc/sys/net/bridge/bridge-nf-call-iptables
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /proc/sys/net/ipv4/ip_forward&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-해결-후-확인"&gt;
 📊 해결 후 확인
 &lt;a class="heading-anchor" href="#-%ed%95%b4%ea%b2%b0-%ed%9b%84-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get nodes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;정상 출력:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;NAME STATUS ROLES VERSION
master Ready control-plane v1.25.x
worker1 Ready &amp;lt;none&amp;gt; v1.25.x&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이후 &lt;code&gt;kubectl&lt;/code&gt; connection refused 오류는 더 이상 발생하지 않았습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-개발자-관점-정리"&gt;
 🧠 개발자 관점 정리
 &lt;a class="heading-anchor" href="#-%ea%b0%9c%eb%b0%9c%ec%9e%90-%ea%b4%80%ec%a0%90-%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;구분&lt;/th&gt;
					&lt;th&gt;원인&lt;/th&gt;
					&lt;th&gt;해결&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;API Server 연결 실패&lt;/td&gt;
					&lt;td&gt;containerd cgroup 설정 불일치&lt;/td&gt;
					&lt;td&gt;SystemdCgroup = true&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CrashLoopBackOff&lt;/td&gt;
					&lt;td&gt;Runtime 충돌&lt;/td&gt;
					&lt;td&gt;containerd 재설정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Ubuntu 22.04 기본 설정&lt;/td&gt;
					&lt;td&gt;Kubernetes와 비호환 가능성&lt;/td&gt;
					&lt;td&gt;설정 수정 또는 버전 조정&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-마무리"&gt;
 🏁 마무리
 &lt;a class="heading-anchor" href="#-%eb%a7%88%eb%ac%b4%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Ubuntu 22.04 + containerd + kubeadm 조합에서는
&lt;strong&gt;cgroup driver 설정을 반드시 확인해야 합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Kubernetes 트러블슈팅 시에는:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;kube-system 로그 확인&lt;/li&gt;
&lt;li&gt;container runtime 설정 점검&lt;/li&gt;
&lt;li&gt;cgroup driver 일치 여부 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이 3가지를 우선 체크하는 것이 좋습니다.&lt;/p&gt;
&lt;hr&gt;</description></item><item><title>[Kubernetes] kubectl port-forward command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-port-forward/</link><pubDate>Sat, 19 Nov 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-port-forward/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;kubectl port-forward &lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;로컬 포트&lt;span class="o"&gt;]&lt;/span&gt;:&lt;span class="o"&gt;[&lt;/span&gt;원격 포트&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 파드 내부의 80번 포트를 로컬 시스템의 8080번 포트와 연결할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;kubectl port-forward my-pod 8080:80
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Pod 연결&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;kubectl port-forward pods/mongo-75f59d57f4-4nd6q 28015:27017
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Deployment 연결&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;kubectl port-forward deployment/mongo 28015:27017
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Replicaset 연결&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;kubectl port-forward replicaset/mongo-75f59d57f4 28015:27017
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Service 연결&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;kubectl port-forward service/mongo 28015:27017&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--namespace&lt;/code&gt;: 리소스가 포함된 Namespace를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# (my-namespace Namespace에 속한 my-service 이름의 서비스 내부의 80번 포트를 로컬 시스템의 8080번 포트와 연결&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl port-forward my-service --namespace my-namespace 8080:80&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--address&lt;/code&gt;: 로컬 주소를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 Pod 내부의 80번 포트를 로컬 시스템의 127.0.0.1 주소의 8080번 포트와 연결&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl port-forward my-pod 127.0.0.1:8080:80&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] PostgreSQL initdb 설정</title><link>https://kyungryeol-yoon.github.io/database/postgresql/kubernetes-postgresql-init/</link><pubDate>Sat, 19 Nov 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/postgresql/kubernetes-postgresql-init/</guid><description>&lt;ul&gt;
&lt;li&gt;PV 또는 PVC 설정이 되어 있지 않았을 때&lt;/li&gt;
&lt;li&gt;PV 또는 PVC 실수로 지웠을 때&lt;/li&gt;
&lt;li&gt;환경이 동일하고 같은 테이블을 사용하는 db를 재사용할 때&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;postgresql pod가 생성될 때 최초로 아래와 같은 기본 테이블 세팅 설정&lt;/p&gt;
&lt;h2 id="configmap-yaml"&gt;
 ConfigMap yaml
 &lt;a class="heading-anchor" href="#configmap-yaml" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ConfigMap&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-initdb-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;init.sql&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; CREATE TABLE IF NOT EXISTS customers (
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; customer_id bpchar NOT NULL,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; company_name character varying(40) NOT NULL,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; contact_name character varying(30),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; contact_title character varying(30),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; address character varying(60),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; city character varying(15),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; region character varying(15),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; postal_code character varying(10),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; country character varying(15),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; phone character varying(24),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; fax character varying(24)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; );&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;INSERT INTO customers VALUES (&amp;#39;Chris&amp;#39;, &amp;#39;company_name&amp;#39;, &amp;#39;contact_name&amp;#39;, &amp;#39;contact_title&amp;#39;, &amp;#39;address&amp;#39;, &amp;#39;city_name&amp;#39;, region_name, &amp;#39;postal_code&amp;#39;, &amp;#39;Korea&amp;#39;, &amp;#39;phone-number&amp;#39;, &amp;#39;fax-number&amp;#39;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="pv-yaml"&gt;
 PV yaml
 &lt;a class="heading-anchor" href="#pv-yaml" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PersistentVolume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-claim0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;local&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storageClassName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;manual&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteOnce&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/Users/docker/postgres/docker-pg-vol/data&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="pvc-yaml"&gt;
 PVC yaml
 &lt;a class="heading-anchor" href="#pvc-yaml" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PersistentVolumeClaim&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-claim0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;database&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteOnce&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;100Mi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="deployment-yaml"&gt;
 Deployment yaml
 &lt;a class="heading-anchor" href="#deployment-yaml" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;database&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Recreate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;database&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgres:12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;imagePullPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;IfNotPresent&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;db_name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;setting_password&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5432&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-claim0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/lib/postgresql/data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/docker-entrypoint-initdb.d&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-initdb&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-claim0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persistentVolumeClaim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;claimName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-claim0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-initdb&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;postgresql-initdb-config&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] kubectl auth reconcile command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-auth-reconcile/</link><pubDate>Thu, 10 Nov 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-auth-reconcile/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl auth reconcile -f &lt;span class="o"&gt;[&lt;/span&gt;파일 경로&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 현재 클러스터에 적용된 ./rbac.yaml 파일의 권한 부여를 재조정할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl auth reconcile -f ./rbac.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-f&lt;/code&gt;, &lt;code&gt;--filename&lt;/code&gt;: 대상 파일을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ./rbac.yaml 파일의 권한 부여를 재조정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl auth reconcile -f ./rbac.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--dry-run&lt;/code&gt;: 실제 작업을 수행하지 않고 결과만 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 실제 작업을 수행하지 않고 ./rbac.yaml 파일의 재조정 결과만 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl auth reconcile -f ./rbac.yaml --dry-run&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubeadm join command</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubeadm-command-join/</link><pubDate>Sat, 22 Oct 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubeadm-command-join/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubeadm join &lt;span class="o"&gt;[&lt;/span&gt;Master Node IP&lt;span class="o"&gt;]&lt;/span&gt;:&lt;span class="o"&gt;[&lt;/span&gt;Port&lt;span class="o"&gt;]&lt;/span&gt; --token &lt;span class="o"&gt;[&lt;/span&gt;Token&lt;span class="o"&gt;]&lt;/span&gt; --discovery-token-ca-cert-hash &lt;span class="o"&gt;[&lt;/span&gt;디스커버리 Token CA 인증서 해시&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Master Node IP가 192.168.0.1이고, Token이 abcdef.1234567890abcdef이며, 디스커버리 Token CA 인증서 해시가 sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef인 Worker Node를 추가할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubeadm join 192.168.0.1:6443 --token abcdef.1234567890abcdef --discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--token&lt;/code&gt;: Cluster에 대한 액세스를 허용하는 Token을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 액세스를 허용하는 Token이 abcdef.1234567890abcdef인 Worker Node를 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm join 192.168.0.1:6443 --token abcdef.1234567890abcdef&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--discovery-token-ca-cert-hash&lt;/code&gt;: 디스커버리 Token CA 인증서 해시를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 디스커버리 Token CA 인증서 해시가 sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef인 Worker Node를 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm join 192.168.0.1:6443 --discovery-token-ca-certhash&lt;span class="se"&gt;\ &lt;/span&gt;sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;\&lt;/code&gt; 는 아랫줄까지 한줄로 쓰겠다는 의미
{: .prompt-tip }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--control-plane&lt;/code&gt;: Master Node에서 실행되는 Kubernetes 컨트롤 플레인 구성 요소를 설치&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubeadm join 192.168.0.1:6443 --token abcdef.1234567890abcdef --discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--certificate-key&lt;/code&gt;: Master Node에서 생성된 인증서 키를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 인증서 키가 abcdef1234567890인 Worker Node를 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm join 192.168.0.1:6443 --token abcdef.1234567890abcdef --discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef --certificate-key abcdef1234567890&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--cri-socket&lt;/code&gt;: 사용할 CRI 소켓 경로를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Docker CRI를 사용하고, /var/run/dockershim.sock CRI 소켓을 사용하는 Worker Node를 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm join 192.168.0.1:6443 --token abcdef.1234567890abcdef --discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef --cri-socket /var/run/dockershim.sock&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--discovery-file&lt;/code&gt;: 디스커버리 Token 파일의 경로를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# /etc/kubernetes/discovery-token-ca-cert-hash.txt 파일에서 디스커버리 Token CA 인증서 해시를 읽어들여 Worker Node를 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm join 192.168.0.1:6443 --discovery-file&lt;span class="o"&gt;=&lt;/span&gt;/etc/kubernetes/discovery-token-ca-cert-hash.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--skip-preflight-checks&lt;/code&gt;: 사전 검사를 건너뛴다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 사전 검사를 건너뛰고 Worker Node를 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm join 192.168.0.1:6443 --token abcdef.1234567890abcdef --discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef --skip-preflight-checks&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Python] 원하는 개수만큼 자르기</title><link>https://kyungryeol-yoon.github.io/backend/python/python-divide-str-to-list/</link><pubDate>Sat, 22 Oct 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/python/python-divide-str-to-list/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;str_eng&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ABCDEFGHIJKLMNOPQRSTUVWXYZ&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;str_eng&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str_eng&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# [&amp;#39;ABC&amp;#39;, &amp;#39;DEF&amp;#39;, &amp;#39;GHI&amp;#39;, &amp;#39;JKL&amp;#39;, &amp;#39;MNO&amp;#39;, &amp;#39;PQR&amp;#39;, &amp;#39;STU&amp;#39;, &amp;#39;VWX&amp;#39;, &amp;#39;YZ&amp;#39;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;str_eng&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ABCDEFGHIJKLMNOPQRSTUVWXYZ&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str_eng&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)])]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# [&amp;#39;ABC&amp;#39;, &amp;#39;DEF&amp;#39;, &amp;#39;GHI&amp;#39;, &amp;#39;JKL&amp;#39;, &amp;#39;MNO&amp;#39;, &amp;#39;PQR&amp;#39;, &amp;#39;STU&amp;#39;, &amp;#39;VWX&amp;#39;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;str_eng&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ABCDEFGHIJKLMNOPQRSTUVWXYZ&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str_eng&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# [&amp;#39;ABC&amp;#39;, &amp;#39;DEF&amp;#39;, &amp;#39;GHI&amp;#39;, &amp;#39;JKL&amp;#39;, &amp;#39;MNO&amp;#39;, &amp;#39;PQR&amp;#39;, &amp;#39;STU&amp;#39;, &amp;#39;VWX&amp;#39;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Istioctl 다운로드 및 설치</title><link>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-install-istioctl/</link><pubDate>Mon, 17 Oct 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-install-istioctl/</guid><description>&lt;h2 id="다운로드-및-설치"&gt;
 다운로드 및 설치
 &lt;a class="heading-anchor" href="#%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c-%eb%b0%8f-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -sL https://istio.io/downloadIstioctl &lt;span class="p"&gt;|&lt;/span&gt; sh -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:&lt;span class="nv"&gt;$HOME&lt;/span&gt;/.istioctl/bin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;istioctl 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/istio/istio/releases"&gt;https://github.com/istio/istio/releases&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="istio-관련-배포-확인"&gt;
 istio 관련 배포 확인
 &lt;a class="heading-anchor" href="#istio-%ea%b4%80%eb%a0%a8-%eb%b0%b0%ed%8f%ac-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl -n istio-system get deploy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="특정-namespace에-istio-설정"&gt;
 특정 Namespace에 Istio 설정
 &lt;a class="heading-anchor" href="#%ed%8a%b9%ec%a0%95-namespace%ec%97%90-istio-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl label namespace &amp;lt;namespace&amp;gt; istio-injection&lt;span class="o"&gt;=&lt;/span&gt;enabled&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] kubeadm token command</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubeadm-command-token/</link><pubDate>Sun, 02 Oct 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubeadm-command-token/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Token 생성 - kubeadm join 명령어를 사용하여 Woker Node를 Cluster에 추가할 때 사용&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm token create
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Token 조회 - 현재 사용 가능한 Token 목록을 조회&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;kubeadm token list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Token 삭제 - 특정 Token을 삭제&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;kubeadm token delete &lt;span class="o"&gt;[&lt;/span&gt;Token&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="alert alert-info"&gt;
 &lt;span class="alert-label"&gt;참고&lt;/span&gt;
 [명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
&lt;/div&gt;

&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;create&lt;/code&gt;: 새로운 Token을 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 24시간 동안 유효한 Token을 생성하고, kubeadm join 명령어를 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm token create --ttl 24h --print-join-command&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;delete&lt;/code&gt;: Token을 삭제&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# abcdef.1234567890abcdef Token을 삭제&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm token delete abcdef.1234567890abcdef&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;list&lt;/code&gt;: 사용 가능한 Token 목록을 조회&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 사용 가능한 Token 목록을 조회&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm token list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="alert alert-info"&gt;
 &lt;span class="alert-label"&gt;참고&lt;/span&gt;
 자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
&lt;/div&gt;
</description></item><item><title>[Kubernetes] kubeadm init command</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubeadm-command-init/</link><pubDate>Sun, 25 Sep 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubeadm-command-init/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubeadm init &lt;span class="o"&gt;[&lt;/span&gt;옵션&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 10.244.0.0/16 CIDR 범위의 Pod 네트워크를 생성하면서 Kubernetes Cluster를 초기화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubeadm init --pod-network-cidr&lt;span class="o"&gt;=&lt;/span&gt;10.244.0.0/16&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--config&lt;/code&gt;: 초기화에 사용할 구성 파일을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-config.yaml 파일에 지정된 구성 파일을 사용하여 Kubernetes Cluster를 초기화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm init --config&lt;span class="o"&gt;=&lt;/span&gt;my-config.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--token&lt;/code&gt;: Cluster에 대한 액세스를 허용하는 토큰을 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 액세스를 허용하는 토큰이 abcdef.1234567890abcdef인 Kubernetes Cluster를 초기화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm init --token abcdef.1234567890abcdef&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--pod-network-cidr&lt;/code&gt;: Cluster에 대한 Pod 네트워크 CIDR 범위를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 10.244.0.0/16 CIDR 범위의 Pod 네트워크를 생성하면서 Kubernetes Cluster를 초기화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm init --pod-network-cidr&lt;span class="o"&gt;=&lt;/span&gt;10.244.0.0/16&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--apiserver-cert-extra-sans&lt;/code&gt;: Master Node 인증서에 추가할 DNS 이름을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Master Node 인증서에 www.example.com DNS 이름을 추가하면서 Kubernetes Cluster를 초기화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm init --apiserver-cert-extra-sans&lt;span class="o"&gt;=&lt;/span&gt;www.example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--skip-phases&lt;/code&gt;: 특정 초기화 단계를 건너뛴다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# kube-proxy 애드온 초기화를 건너뛴다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm init --skip-phases&lt;span class="o"&gt;=&lt;/span&gt;addon/kube-proxy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubeadm list command</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubeadm-command-list/</link><pubDate>Thu, 22 Sep 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubeadm-command-list/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# component는 확인하려는 구성 요소를 지정. 지정하지 않으면, 모든 구성 요소를 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubeadm list &lt;span class="o"&gt;[&lt;/span&gt;component&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;kube-apiserver&lt;/li&gt;
&lt;li&gt;kube-controller-manager&lt;/li&gt;
&lt;li&gt;kube-scheduler&lt;/li&gt;
&lt;li&gt;etcd&lt;/li&gt;
&lt;li&gt;kube-proxy&lt;/li&gt;
&lt;li&gt;kubelet&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--kubeconfig&lt;/code&gt;: kubeconfig 파일을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm list --kubeconfig&lt;span class="o"&gt;=&lt;/span&gt;/path/to/kubeconfig&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--output&lt;/code&gt;: 출력 형식을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# JSON 형식으로 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm list --output&lt;span class="o"&gt;=&lt;/span&gt;json&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Redis] Redis Persistence: RDB &amp; AOF Explained</title><link>https://kyungryeol-yoon.github.io/database/redis/redis-persistence-rdb-aof/</link><pubDate>Sat, 03 Sep 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/redis/redis-persistence-rdb-aof/</guid><description>&lt;h2 id="redis-persistence-영속성--데이터-저장"&gt;
 Redis Persistence (영속성 &amp;amp; 데이터 저장)
 &lt;a class="heading-anchor" href="#redis-persistence-%ec%98%81%ec%86%8d%ec%84%b1--%eb%8d%b0%ec%9d%b4%ed%84%b0-%ec%a0%80%ec%9e%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Redis는 인메모리 데이터 저장소로 매우 빠르지만, 메모리 기반이기 때문에 서버 재시작 시 데이터가 사라질 수 있습니다.&lt;br&gt;
이를 보완하기 위해 Redis는 &lt;strong&gt;디스크에 데이터를 저장하는 영속성(Persistence)&lt;/strong&gt; 기능을 제공합니다. Redis는 두 가지 영속성 방식을 지원합니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;RDB (Snapshotting)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AOF (Append Only File)&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="-persistence-개념"&gt;
 🔎 Persistence 개념
 &lt;a class="heading-anchor" href="#-persistence-%ea%b0%9c%eb%85%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Redis Persistence는 Redis 데이터를 &lt;strong&gt;메모리뿐 아니라 디스크에도 저장&lt;/strong&gt;해 장애 시 데이터를 복원할 수 있도록 해줍니다.&lt;br&gt;
이 두 방식은 목적은 같지만 저장 방식과 복구 방식, 성능 특성이 다릅니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-rdb-snapshotting"&gt;
 1️⃣ RDB (Snapshotting)
 &lt;a class="heading-anchor" href="#1-rdb-snapshotting" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="-개념"&gt;
 🧠 개념
 &lt;a class="heading-anchor" href="#-%ea%b0%9c%eb%85%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;RDB는 특정 시점의 Redis 메모리 데이터를 &lt;strong&gt;스냅샷 형태로 디스크에 저장&lt;/strong&gt;하는 방식입니다.&lt;br&gt;
dump 파일(&lt;code&gt;dump.rdb&lt;/code&gt;)로 저장되며 Redis 재시작 시 이 파일을 다시 읽어 데이터 복구를 수행합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="-rdb-저장-시점-save-vs-bgsave"&gt;
 🧩 RDB 저장 시점: SAVE vs BGSAVE
 &lt;a class="heading-anchor" href="#-rdb-%ec%a0%80%ec%9e%a5-%ec%8b%9c%ec%a0%90-save-vs-bgsave" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Redis는 두 가지 스냅샷 저장 방법을 제공합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;명령&lt;/th&gt;
					&lt;th&gt;영향&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;SAVE&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Redis 프로세스를 잠시 멈추고 즉시 스냅샷을 생성 (blocking)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;BGSAVE&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;자식 프로세스를 fork하여 백그라운드에서 저장 (non‑blocking)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SAVE&lt;/code&gt;: 동기식으로 데이터 저장 → 서비스 중단 위험&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BGSAVE&lt;/code&gt;: fork 기반 비동기 저장 → 서비스 중단 없이 백업 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;RDB는 기본적으로 &lt;strong&gt;BGSAVE 방식&lt;/strong&gt;을 사용합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="-설정-예시"&gt;
 🧠 설정 예시
 &lt;a class="heading-anchor" href="#-%ec%84%a4%ec%a0%95-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;redis.conf&lt;/code&gt; 파일 예:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;save 900 1 # 900초 동안 1회 이상 변경되면 저장
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;save 300 10 # 300초 동안 10회 이상 변경되면 저장
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;save 60 10000 # 60초 동안 10000회 이상 변경되면 저장&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;추가 설정:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;dbfilename dump.rdb
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;dir /var/lib/redis
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;stop-writes-on-bgsave-error yes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;rdbcompression yes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;rdbchecksum yes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="-장단점"&gt;
 📊 장단점
 &lt;a class="heading-anchor" href="#-%ec%9e%a5%eb%8b%a8%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;장점&lt;/th&gt;
					&lt;th&gt;단점&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;파일 크기&lt;/td&gt;
					&lt;td&gt;작음&lt;/td&gt;
					&lt;td&gt;중간 주기 사이 데이터 손실 가능&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;복구 속도&lt;/td&gt;
					&lt;td&gt;빠름&lt;/td&gt;
					&lt;td&gt;fork 비용 발생&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;운영 특성&lt;/td&gt;
					&lt;td&gt;빠른 백업&lt;/td&gt;
					&lt;td&gt;빈번 저장시 성능 영향&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="2-aof-append-only-file"&gt;
 2️⃣ AOF (Append Only File)
 &lt;a class="heading-anchor" href="#2-aof-append-only-file" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="-개념-1"&gt;
 🧠 개념
 &lt;a class="heading-anchor" href="#-%ea%b0%9c%eb%85%90-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;AOF는 모든 쓰기(write) 명령을 &lt;strong&gt;순차적으로 기록&lt;/strong&gt;하는 방식입니다.
Redis는 저장된 로그를 재실행하여 데이터를 복구합니다.&lt;/p&gt;
&lt;h3 id="-설정-예시-1"&gt;
 📌 설정 예시
 &lt;a class="heading-anchor" href="#-%ec%84%a4%ec%a0%95-%ec%98%88%ec%8b%9c-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;redis.conf&lt;/code&gt; 예:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;appendonly yes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;appendfilename &amp;#34;appendonly.aof&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;appendfsync everysec
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;auto-aof-rewrite-percentage 100
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;auto-aof-rewrite-min-size 64mb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-aof-세부-옵션"&gt;
 📌 AOF 세부 옵션
 &lt;a class="heading-anchor" href="#-aof-%ec%84%b8%eb%b6%80-%ec%98%b5%ec%85%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;옵션&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;appendfsync&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;로그 동기화 타이밍 (&lt;code&gt;always&lt;/code&gt;, &lt;code&gt;everysec&lt;/code&gt;, &lt;code&gt;no&lt;/code&gt;)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;no-appendfsync-on-rewrite&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;rewrite중 fsync 중단 여부&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;auto-aof-rewrite-percentage&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;자동 rewrite 비율&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;auto-aof-rewrite-min-size&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;자동 rewrite 최소 파일 크기&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;aof-load-truncated&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;손상시 기록 잘라쓰기 옵션&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;aof-use-rdb-preamble&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;RDB 프리앰블 포함 여부&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;aof-timestamp-enabled&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;타임스탬프 기록 여부&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;이런 옵션들은 &lt;strong&gt;AOF 동작 및 성능/안정성 균형&lt;/strong&gt;을 조정하는 데 유용합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="-aof-특징"&gt;
 📊 AOF 특징
 &lt;a class="heading-anchor" href="#-aof-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;내용&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;파일 크기&lt;/td&gt;
					&lt;td&gt;큼&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;복구 속도&lt;/td&gt;
					&lt;td&gt;느림&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;데이터 무결성&lt;/td&gt;
					&lt;td&gt;높음&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="rdb-vs-aof-비교"&gt;
 RDB vs AOF 비교
 &lt;a class="heading-anchor" href="#rdb-vs-aof-%eb%b9%84%ea%b5%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;RDB&lt;/th&gt;
					&lt;th&gt;AOF&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;저장 방식&lt;/td&gt;
					&lt;td&gt;Snapshot&lt;/td&gt;
					&lt;td&gt;모든 쓰기 로그&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;데이터 안전&lt;/td&gt;
					&lt;td&gt;보통&lt;/td&gt;
					&lt;td&gt;매우 높음&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;파일 크기&lt;/td&gt;
					&lt;td&gt;작음&lt;/td&gt;
					&lt;td&gt;큼&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;복구 속도&lt;/td&gt;
					&lt;td&gt;빠름&lt;/td&gt;
					&lt;td&gt;느림&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;운영 상황&lt;/td&gt;
					&lt;td&gt;주기 백업&lt;/td&gt;
					&lt;td&gt;데이터 무결성 우선&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="실무-운영-전략"&gt;
 실무 운영 전략
 &lt;a class="heading-anchor" href="#%ec%8b%a4%eb%ac%b4-%ec%9a%b4%ec%98%81-%ec%a0%84%eb%9e%b5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cache 용도&lt;/strong&gt;: 영속성 비활성화 가능&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;주기 백업&lt;/strong&gt;: RDB 설정을 통해 스냅샷 저장&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;데이터 무결성 우선&lt;/strong&gt;: AOF 기록 활성화&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;균형 전략&lt;/strong&gt;: RDB + AOF 동시 활성화&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;RDB는 빠른 복구를, AOF는 적은 데이터 유실을 보장합니다. 두 방식을 병행하면 운영 안정성을 높일 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="정리"&gt;
 정리
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Redis Persistence는 데이터 안정성과 운영 목적에 따라 선택합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🧠 &lt;strong&gt;RDB&lt;/strong&gt;: Snapshot 기반으로 빠른 복구, 작은 파일&lt;/li&gt;
&lt;li&gt;📜 &lt;strong&gt;AOF&lt;/strong&gt;: 모든 쓰기 로그 기록, 데이터 무결성 우수&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;혼합&lt;/strong&gt;: 두 방식 장점을 조합한 운영 전략&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;</description></item><item><title>[Error] kubeadm join - pending</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubeadm-join-pending/</link><pubDate>Sat, 27 Aug 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubeadm-join-pending/</guid><description>&lt;ul&gt;
&lt;li&gt;kubeadm join시 아래와 같은 에러가 발생하며 pending되는 현상 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="error"&gt;
 Error
 &lt;a class="heading-anchor" href="#error" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;아래와 같이 무한 pending&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;preflight&lt;span class="o"&gt;]&lt;/span&gt; Running pre-flight checks&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;원인은 node join을 위한 token이 expired 되었기 때문&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;token을 새로 생성해 해결 가능&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="해결-방법"&gt;
 해결 방법
 &lt;a class="heading-anchor" href="#%ed%95%b4%ea%b2%b0-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;아래 명령어로 token 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubeadm token create&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="확인"&gt;
 확인
 &lt;a class="heading-anchor" href="#%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;아래 명령어로 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubeadm token list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--discovery-token-ca-cert-hash&lt;/code&gt;는 변경되지 않기 때문에 kubeadm join시 token을 새로 생성된 token 값으로 변경 후 join&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] kubectl version command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-version/</link><pubDate>Fri, 12 Aug 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-version/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Cluster의 버전 정보와 kubectl 명령어의 버전 정보가 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--short&lt;/code&gt;: 간략한 버전 정보를 출력&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# kubectl 명령어와 Cluster의 버전 정보를 간략하게 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl version --short&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--client&lt;/code&gt;: 클라이언트의 버전 정보만 출력&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# kubectl 명령어의 버전 정보만 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl version --client&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--server&lt;/code&gt;: 서버의 버전 정보만 출력&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Cluster의 API 서버 버전 정보만 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl version --server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] Release 상태의 PV를 Available 상태로 변경</title><link>https://kyungryeol-yoon.github.io/kubernetes/storage/kubernetes-pv-release/</link><pubDate>Sun, 07 Aug 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/storage/kubernetes-pv-release/</guid><description>&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;helm으로 설치된 경우 동적 프로비저닝을 통해 PV/PVC 가 동적으로 사용되었을 경우, helm으로 uninstall을 하게 되면 사용되었던 PV 자원의 상태는 release 상태가 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이 경우 PV는 이전에 매핑된 PVC의 ref 요소가 남아 있어 다음에 다시 helm 으로 설치하게 되면 이전에 사용했던 PV 를 다시 사용하는 것이 아니라 새로운 PV 를 생성하여 사용하게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이전에 사용했던 PV는 그대로 release 상태로 남아 있게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이 경우 helm 삭제시 삭제 후 PV의 spec.claimRef를 null로 지정하게 되면 다음에 다시 helm 으로 설치하는 경우, 이전에 사용했던 PV 를 다시 사용할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl patch pv &lt;span class="o"&gt;[&lt;/span&gt;pvname&lt;span class="o"&gt;]&lt;/span&gt; --patch &lt;span class="s1"&gt;&amp;#39;{&amp;#34;spec&amp;#34;:{claimRef&amp;#34;: null}}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;kubectl patch pv &lt;span class="o"&gt;[&lt;/span&gt;pvname&lt;span class="o"&gt;]&lt;/span&gt; -p &lt;span class="s1"&gt;&amp;#39;{&amp;#34;spec&amp;#34;:{&amp;#34;claimRef&amp;#34;: null}}&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Mac OS] Homebrew and Cask</title><link>https://kyungryeol-yoon.github.io/environment/macos/homebrew-cask/</link><pubDate>Sat, 30 Jul 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/environment/macos/homebrew-cask/</guid><description>&lt;h2 id="homebrew와-cask에-대한-설명"&gt;
 Homebrew와 Cask에 대한 설명
 &lt;a class="heading-anchor" href="#homebrew%ec%99%80-cask%ec%97%90-%eb%8c%80%ed%95%9c-%ec%84%a4%eb%aa%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Homebrew와 Cask는 macOS 및 Linux에서 소프트웨어를 설치하고 관리하는 데 사용되는 패키지 관리 도구이다.&lt;/li&gt;
&lt;li&gt;Homebrew는 주로 명령어 기반으로 소프트웨어를 설치하는 데 사용되며, Cask는 그래픽 인터페이스가 필요한 앱들을 설치하는 데 특화되어 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="homebrew"&gt;
 Homebrew
 &lt;a class="heading-anchor" href="#homebrew" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Homebrew는 macOS에서 소프트웨어를 설치, 관리, 업데이트하는 데 널리 사용되는 패키지 관리 시스템이다.&lt;/li&gt;
&lt;li&gt;Linux에서도 사용할 수 있으며, 주로 &lt;strong&gt;명령줄 도구&lt;/strong&gt;나 &lt;strong&gt;Library&lt;/strong&gt;를 설치하는 데 사용된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="특징"&gt;
 특징
 &lt;a class="heading-anchor" href="#%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;명령줄 도구&lt;/strong&gt;를 설치하는 데 주로 사용된다.
&lt;ul&gt;
&lt;li&gt;예: &lt;code&gt;git&lt;/code&gt;, &lt;code&gt;node.js&lt;/code&gt;, &lt;code&gt;python&lt;/code&gt;, &lt;code&gt;htop&lt;/code&gt; 등.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;macOS 시스템에 &lt;strong&gt;특화된&lt;/strong&gt; 설치 관리 도구이다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;스크립트&lt;/strong&gt;나 명령어로 설치를 자동화할 수 있다.&lt;/li&gt;
&lt;li&gt;의존성 관리가 뛰어나며, 필요한 Library나 도구를 함께 설치해준다.&lt;/li&gt;
&lt;li&gt;설치된 패키지를 손쉽게 업그레이드하거나 삭제할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="homebrew-사용-예시"&gt;
 Homebrew 사용 예시
 &lt;a class="heading-anchor" href="#homebrew-%ec%82%ac%ec%9a%a9-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Homebrew 설치 (macOS)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;bin/bash -c &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 패키지 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;brew install wget
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 설치된 패키지 업데이트&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;brew update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;brew upgrade
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 설치된 패키지 목록 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;brew list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 패키지 삭제&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;brew uninstall wget&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="homebrew-cask"&gt;
 Homebrew Cask
 &lt;a class="heading-anchor" href="#homebrew-cask" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Homebrew Cask는 Homebrew의 확장 기능으로, **그래픽 사용자 인터페이스(GUI)**를 가진 애플리케이션을 설치하는 데 사용된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cask는 일반적으로 macOS 앱스토어에 있는 것과 같은 &lt;strong&gt;GUI 애플리케이션&lt;/strong&gt;을 설치할 때 유용하다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;예를 들어, 브라우저나, 이미지 편집기, 텍스트 편집기와 같은 애플리케이션들이 여기에 해당한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cask를 사용하면 &lt;code&gt;.dmg&lt;/code&gt;, &lt;code&gt;.pkg&lt;/code&gt;, &lt;code&gt;.app&lt;/code&gt; 파일을 자동으로 다운로드하고 설치해 주며, 앱의 최신 버전도 쉽게 관리할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="특징-1"&gt;
 특징
 &lt;a class="heading-anchor" href="#%ed%8a%b9%ec%a7%95-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GUI 애플리케이션&lt;/strong&gt;을 설치하는 데 사용된다.
&lt;ul&gt;
&lt;li&gt;예: &lt;code&gt;Google Chrome&lt;/code&gt;, &lt;code&gt;Visual Studio Code&lt;/code&gt;, &lt;code&gt;Slack&lt;/code&gt;, &lt;code&gt;Spotify&lt;/code&gt; 등.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;brew install&lt;/code&gt; 명령어와 비슷하지만, &lt;code&gt;cask&lt;/code&gt;를 명시적으로 사용해야 한다.&lt;/li&gt;
&lt;li&gt;사용자가 직접 다운로드하여 설치하는 것보다 훨씬 더 빠르고 쉽게 앱을 설치할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="homebrew-cask-사용-예시"&gt;
 Homebrew Cask 사용 예시
 &lt;a class="heading-anchor" href="#homebrew-cask-%ec%82%ac%ec%9a%a9-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Homebrew Cask 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;brew install cask
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# GUI 애플리케이션 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;brew install --cask google-chrome
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 설치된 GUI 애플리케이션 목록 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;brew list --cask
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 앱 삭제&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;brew uninstall --cask google-chrome&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="homebrew와-cask의-차이점"&gt;
 Homebrew와 Cask의 차이점
 &lt;a class="heading-anchor" href="#homebrew%ec%99%80-cask%ec%9d%98-%ec%b0%a8%ec%9d%b4%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Homebrew&lt;/strong&gt;는 주로 명령줄 도구, 라이브러리, 서버 프로그램 등 &lt;strong&gt;CLI 도구&lt;/strong&gt;를 설치하는 데 사용된다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cask&lt;/strong&gt;는 GUI 애플리케이션을 설치하는 데 사용된다.&lt;/li&gt;
&lt;li&gt;예를 들어, &lt;code&gt;Google Chrome&lt;/code&gt;, &lt;code&gt;Slack&lt;/code&gt;, &lt;code&gt;Visual Studio Code&lt;/code&gt; 같은 애플리케이션을 설치할 때 사용된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="만약-zsh-command-not-found-brew-오류가-발생한다면"&gt;
 만약 &lt;code&gt;zsh: command not found: brew&lt;/code&gt; 오류가 발생한다면
 &lt;a class="heading-anchor" href="#%eb%a7%8c%ec%95%bd-zsh-command-not-found-brew-%ec%98%a4%eb%a5%98%ea%b0%80-%eb%b0%9c%ec%83%9d%ed%95%9c%eb%8b%a4%eb%a9%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew --version
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;zsh: &lt;span class="nb"&gt;command&lt;/span&gt; not found: brew&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# zshrc에 homebrew path 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;export PATH=/opt/homebrew/bin:$PATH&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; ~/.zshrc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# zshrc 반영&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.zshrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] kubectl top command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-top/</link><pubDate>Sat, 09 Jul 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-top/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl top &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Cluster 내 모든 Pod의 리소스 사용량을 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl top pods
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Cluster 내 모든 Node의 리소스 사용량을 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;kubectl top nodes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--containers&lt;/code&gt;: Container 단위의 리소스 사용량을 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 모든 파드의 Container 단위의 리소스 사용량을 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl top pods --containers&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--kryoon-namespace&lt;/code&gt;: kryoon의 Namespace를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# kryoon가 설치된 kube-system Namespace에 대한 Pod의 리소스 사용량을 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl top pods --kryoon-namespace&lt;span class="o"&gt;=&lt;/span&gt;kube-system&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubeadm reset command</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubeadm-command-reset/</link><pubDate>Sun, 03 Jul 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubeadm-command-reset/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubeadm reset&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;모든 Kubernetes 구성 요소와 컨테이너를 제거합니다.&lt;/li&gt;
&lt;li&gt;모든 네트워크 설정을 제거합니다.&lt;/li&gt;
&lt;li&gt;모든 Kubernetes 설정 파일을 삭제합니다.&lt;/li&gt;
&lt;li&gt;모든 데이터를 삭제합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--cri-socket&lt;/code&gt;: CRI 소켓 경로를 지정. 이 옵션을 사용하여 kubelet이나 kubeadm에 등록된 CRI 구현체의 소켓을 사용&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# dockershim을 사용하여 초기화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm reset --cri-socket&lt;span class="o"&gt;=&lt;/span&gt;/var/run/dockershim.sock&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--force&lt;/code&gt;: 초기화 작업을 강제로 수행&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 강제 초기화를 수행&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm reset --force&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--skip-phases&lt;/code&gt;: 특정 초기화 단계를 건너뛴다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 모든 초기화 단계를 건너뛴다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm reset --skip-phases&lt;span class="o"&gt;=&lt;/span&gt;all&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--dry-run&lt;/code&gt;: 실제로 초기화 작업을 수행하지 않고, 초기화 작업을 출력&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 초기화 작업을 수행하지 않고, 초기화 작업을 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm reset --dry-run&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubectl proxy command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-proxy/</link><pubDate>Sat, 25 Jun 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-proxy/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# URL을 통해 API 서버와 통신할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl proxy http://localhost:8001&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--port&lt;/code&gt;: proxy 서버가 사용할 포트 번호를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# proxy 서버를 8080 포트에서 실행&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl proxy --port&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--address&lt;/code&gt;: proxy 서버가 사용할 IP 주소를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# proxy 서버를 모든 IP 주소에서 실행&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl proxy --address&lt;span class="o"&gt;=&lt;/span&gt;0.0.0.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Spring] Spring Security, JWT, 인증, 인가</title><link>https://kyungryeol-yoon.github.io/backend/spring/spring-security-jwt/</link><pubDate>Sun, 05 Jun 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/spring/spring-security-jwt/</guid><description>&lt;h2 id="spring-security-jwt-인증-인가"&gt;
 &lt;strong&gt;Spring Security, JWT, 인증, 인가&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#spring-security-jwt-%ec%9d%b8%ec%a6%9d-%ec%9d%b8%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Spring Security를 베이스로 JWT를 사용해서 해당 프로젝트의 인증과 인가를 구현한다.&lt;/li&gt;
&lt;li&gt;이와 관련돼서 생성된 Class는 다음과 같다.
&lt;ul&gt;
&lt;li&gt;SecurityConfig : Spring Security관련 설정&lt;/li&gt;
&lt;li&gt;UserAccount : Spring Security에서 인증 요소(principal)로 사용되는 객체. Userdetails를 상속받고 Account의 정보를 갖는다.&lt;/li&gt;
&lt;li&gt;PrincipalDetailService : 인증 시, DB에서 Account를 찾고 UserAccount로 반환하는 loadUserByUsername Method를 갖는다.&lt;/li&gt;
&lt;li&gt;JwtAutienticationFilter : jwt를 사용해서 인증 처리&lt;/li&gt;
&lt;li&gt;JwtAutiorizationFilter : jwt를 사용해서 인가 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="securityconfig"&gt;
 &lt;strong&gt;SecurityConfig&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#securityconfig" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Spring Security가 사용할 정책, 필터, 인가 권한 등을 설정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Configuration&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@EnableWebSecurity&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RequiredArgsConstructor&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SecurityConfig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;WebSecurityConfigurerAdapter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AccountRepository&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;accountRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JwtProcessor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtProcessor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;protected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpSecurity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;csrf&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;disable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;formLogin&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;disable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;httpBasic&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;disable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sessionManagement&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;sessionCreationPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SessionCreationPolicy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;STATELESS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;corsFilter&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JwtAuthenticationFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authenticationManager&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtProcessor&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JwtAuthorizationFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authenticationManager&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;accountRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtProcessor&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authorizeRequests&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mvcMatchers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/home&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/login&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;permitAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//** 홈페이지, login&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;anyRequest&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;hasAuthority&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ROLE_USER&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WebSecurity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ignoring&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requestMatchers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PathRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toStaticResources&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;atCommonLocations&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Bean&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CorsFilter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;corsFilter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UrlBasedCorsConfigurationSource&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UrlBasedCorsConfigurationSource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CorsConfiguration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CorsConfiguration&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAllowCredentials&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAllowedOriginPattern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAllowedHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAllowedMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerCorsConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/**&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CorsFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Bean&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AuthenticationManager&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;authenticationManagerBean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authenticationManagerBean&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="기본-설정"&gt;
 &lt;strong&gt;기본 설정&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;csrf&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;disable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;formLogin&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;disable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;httpBasic&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;disable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sessionManagement&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;sessionCreationPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SessionCreationPolicy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;STATELESS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;csrf.disable()&lt;/strong&gt; : API를 작성하는데 프런트가 정해져있지 않기 때문에 csrf설정은 우선 꺼놓는다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;formLogin.disable()&lt;/strong&gt; : formLogin 대신 Jwt를 사용하기 때문에 disable로 설정&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;httpBasic.disable()&lt;/strong&gt; : httpBasic 방식 대신 Jwt를 사용하기 때문에 disable로 설정&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SessionCreationPolicy.STATELESS&lt;/strong&gt; : Jwt를 사용하기 때문에 session을 stateless로 설정한다. stateless로 설정 시 Spring Security는 세션을 사용하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="추가-필터"&gt;
 &lt;strong&gt;추가 필터&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%b6%94%ea%b0%80-%ed%95%84%ed%84%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;corsFilter&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JwtAuthenticationFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authenticationManager&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtProcessor&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JwtAuthorizationFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authenticationManager&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;accountRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtProcessor&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="corsfilter"&gt;
 &lt;strong&gt;corsFilter&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#corsfilter" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Bean&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CorsFilter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;corsFilter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UrlBasedCorsConfigurationSource&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UrlBasedCorsConfigurationSource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CorsConfiguration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CorsConfiguration&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAllowCredentials&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAllowedOriginPattern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAllowedHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAllowedMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerCorsConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/**&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CorsFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;cors관련 설정을 포함한 필터.&lt;/li&gt;
&lt;li&gt;기본적으로 서버 또는 지정된 특정 도메인의 요청만 허용하지만 프런트가 정해져있지 않기 때문에 모든 도메인을 허용하는 방식으로 설정.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;setAllowCredentials&lt;/strong&gt; : 내 서버가 응답을 할 때 json을 자바스크립트에서 처리할수 있게 할지를 설정&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;addAllowedOriginPattern&lt;/strong&gt; : 허용할 도메인 목록&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;addAllowedHeader&lt;/strong&gt; : 허용할 헤더 목록&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;addAllowedMethod&lt;/strong&gt; : 허용할 Method(GET, PUT, 등) 목록&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;source.registerCorsConfiguration&lt;/strong&gt; : 지정한 url에 config 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="jwtauthenticationfilter"&gt;
 &lt;strong&gt;JwtAuthenticationFilter&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#jwtauthenticationfilter" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Jwt를 사용한 인증을 구현한 필터&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="jwtauthorizationfilter"&gt;
 &lt;strong&gt;JwtAuthorizationFilter&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#jwtauthorizationfilter" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Jwt를 사용한 인가를 구현한 필터&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="인가"&gt;
 &lt;strong&gt;인가&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%9d%b8%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authorizeRequests&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mvcMatchers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/home&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/login&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;permitAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//** 홈페이지, 로그인&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;anyRequest&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;hasAuthority&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ROLE_USER&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;authorizationRequest&lt;/strong&gt; : 요청에 따른 인가 설정
&lt;ul&gt;
&lt;li&gt;기본적으로 모든 uri은 ROLE_USER의 권한만 허용&lt;/li&gt;
&lt;li&gt;홈페이지와 로그인, 스웨거 관련 uri은 모두 허용&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;configure(WebSecurity web)&lt;/strong&gt; : HttpSecurity에서 설정하지 않은 정적리소스와 HTML 등에 관한 권한을 설정한다.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;web.ignoring().requestMathers(PathRequest.toStaticResources().atCommonLocations())&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;static 리소스의 자원을 Security에서 제외(Security에서 걸러지지 않고 접근 가능)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="authenticationmanagerbean"&gt;
 &lt;strong&gt;authenticationManagerBean&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#authenticationmanagerbean" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WebSecurity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ignoring&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requestMatchers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PathRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toStaticResources&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;atCommonLocations&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;WebSecurityConfigurerAdepter를 상속받은 SecurityConfigure 외에서 AuthenticationManager를 사용하려면 authenticationManagerBean()을 오버라이드 해서 @Bean으로 직접 등록해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="userdetails-userdetailsservice"&gt;
 &lt;strong&gt;UserDetails, UserDetailsService&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#userdetails-userdetailsservice" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Spring Security에서 인증, 인가를 할 때 사용되는 Principal과 관련 서비스 Class를 만든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="useraccount"&gt;
 &lt;strong&gt;UserAccount&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#useraccount" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Principal은 인증, 인가시 검증되는 객체이기 때문에 본 프로젝트에서 사용되는 회원의 정보인 Account를 갖고 있어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Getter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserAccount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;implements&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserDetails&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;UserAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GrantedAuthority&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getAuthorities&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GrantedAuthority&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authorities&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;roleName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRole&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getRoleName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authorities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;roleName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authorities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getPassword&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPassword&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getUsername&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUsername&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;isAccountNonExpired&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;isAccountNonLocked&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;isCredentialsNonExpired&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;isEnabled&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;UserDetails를 상속받는다.&lt;/li&gt;
&lt;li&gt;회원 계정 엔티티인 Account를 필드로 갖는다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;getAuthorities()&lt;/strong&gt; : account의 Role에 저장된 권한 정보를 authorities에 담고 반환한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;isAccountNonExpired()&lt;/strong&gt; : 계정이 만료되지 않았는지를 리턴(true =&amp;gt; 만료되지 않음을 의미)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;isAccountNonLocked()&lt;/strong&gt; : 계정이 잠겨있는지를 리턴(true =&amp;gt; 잠겨있지 않음을 의미)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;isCredentialNonExpired()&lt;/strong&gt; : 계정의 패스워드가 만료되어있는지 를 리턴(true =&amp;gt; 만료되지 않음을 의미)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;isEnabled()&lt;/strong&gt; : 계정이 사용 가능한지를 리턴&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="principaldetailservice"&gt;
 &lt;strong&gt;PrincipalDetailService&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#principaldetailservice" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RequiredArgsConstructor&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PrincipalDetailService&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;implements&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserDetailsService&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AccountRepository&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;accountRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserDetails&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;loadUserByUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UsernameNotFoundException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;accountRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NonExistResourceException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;해당 username을 갖는 Account를 찾을 수 없습니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;UserDetailsService를 상속받는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="loaduserbyusernamestring-username"&gt;
 &lt;strong&gt;loadUserByUsername(String username)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#loaduserbyusernamestring-username" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserDetails&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;loadUserByUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UsernameNotFoundException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;accountRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NonExistResourceException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;해당 username을 갖는 Account를 찾을 수 없습니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Spring Security에서 AutenticationManager가 authenticate()를 통해서 인증을 할 때, 지정된 repository에서 인증 대상 객체를 찾아서 Principal 형태로 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="accountrepository"&gt;
 &lt;strong&gt;AccountRepository&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#accountrepository" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;AccountRepository&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JpaRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;findByUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Spring 데이터 JPA를 사용해서 Repository를 생성한다.&lt;/li&gt;
&lt;li&gt;findByUsername : username(= id)으로 Account를 찾아서 반환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="jwt"&gt;
 &lt;strong&gt;Jwt&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#jwt" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Jwt를 생성하고 디코딩하는 클래스와 Jwt를 사용한 인증, 인가 필터를 구현한 클래스를 만든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="jwtprocessor"&gt;
 &lt;strong&gt;JwtProcessor&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#jwtprocessor" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JwtProcessor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;createAuthJwtToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserAccount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JWT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withSubject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUsername&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withExpiresAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JwtProperties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EXPIRATION_TIME&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withClaim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAccount&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withClaim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;username&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAccount&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getUsername&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Algorithm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HMAC512&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JwtProperties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SECRET&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;decodeJwtToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;secretKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;claim&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JWT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Algorithm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HMAC512&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secretKey&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwtToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClaim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;claim&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;extractBearer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtHeader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lastIndexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="creatauthjwttoken"&gt;
 &lt;strong&gt;creatAuthJwtToken&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#creatauthjwttoken" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;createAuthJwtToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserAccount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JWT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withSubject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUsername&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withExpiresAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JwtProperties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EXPIRATION_TIME&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withClaim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAccount&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withClaim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;username&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAccount&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getUsername&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Algorithm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HMAC512&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JwtProperties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SECRET&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;userAccount를 받아서 JwtToken을 생성하고 반환.&lt;/li&gt;
&lt;li&gt;Account의 id(엔티티의 id)와 username(로그인 시 id로 사용됨)을 HMAC512 알고리즘으로 암호화한다.&lt;/li&gt;
&lt;li&gt;만료시간은 현재 시간으로부터 JwtProperties(Jwt관련 설정 정보를 모아놓은 클래스)에 정의된 EXPIRATION_TIME까지로 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;만료시간은 밀리 세컨드로 설정됨
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="decodejwttoken"&gt;
 &lt;strong&gt;decodeJwtToken&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#decodejwttoken" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;decodeJwtToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;secretKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;claim&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JWT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Algorithm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HMAC512&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secretKey&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwtToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClaim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;claim&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;JwtToken을 받으면 secretKey를 사용해서 지정된 claim을 반환한다&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="extractbearer"&gt;
 &lt;strong&gt;extractBearer&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#extractbearer" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;extractBearer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtHeader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lastIndexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Authentication 해더의 Jwt Token은 앞에 &amp;ldquo;Bearer &amp;ldquo;가 붙기 때문에 &amp;ldquo;Bearer &amp;ldquo;를 제거하고 뒤의 순수한 Jwt Token만을 추출한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="jwtproperties"&gt;
 &lt;strong&gt;JwtProperties&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#jwtproperties" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;JwtProperties&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SECRET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JWT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;암호화시&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;사용할&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SecretKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;EXPIRATION_TIME&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;60000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;60&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TOKEN_PREFIX&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Bearer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HEADER_STRING&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Authorization&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;JWT와 관련된 설정 수치들을 지정한 인터페이스&lt;/li&gt;
&lt;li&gt;JWT 암호화 시 사용되는 SecretKey의 값이 있기 때문에 gitIgnore 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="jwtauthenticationfilter-1"&gt;
 &lt;strong&gt;JwtAuthenticationFilter&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#jwtauthenticationfilter-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RequiredArgsConstructor&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JwtAuthenticationFilter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UsernamePasswordAuthenticationFilter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AuthenticationManager&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authenticationManager&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JwtProcessor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtProcessor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@SneakyThrows&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;attemptAuthentication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpServletRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HttpServletResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AuthenticationException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ObjectMapper&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;objectMapper&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ObjectMapper&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;objectMapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInputStream&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UsernamePasswordAuthenticationToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authenticationToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UsernamePasswordAuthenticationToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUsername&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPassword&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authenticationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authenticationToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authentication&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;protected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;successfulAuthentication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpServletRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HttpServletResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FilterChain&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IOException&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ServletException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserAccount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserAccount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPrincipal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtProcessor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createAuthJwtToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JwtProperties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HEADER_STRING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JwtProperties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TOKEN_PREFIX&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;JWT로 인증을 하기 위한 클래스&lt;/li&gt;
&lt;li&gt;Spring Security 로그인 시 인증을 담당하는 UsernamePasswordAuthenticationFilter를 상속받는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Spring Bean으로 등록하지 않는 이유는 해당 클래스가 AuthenticationManager를 의존성 주입받는데 해당 클래스를 사용하는 SecurityConfig에서 AuthenticationManager를 빈으로 등록하기 때문에 순환 참조가 발생하기 때문이다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="attemptauthentication"&gt;
 &lt;strong&gt;attemptAuthentication&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#attemptauthentication" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@SneakyThrows&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;attemptAuthentication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpServletRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HttpServletResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AuthenticationException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ObjectMapper&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;objectMapper&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ObjectMapper&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;objectMapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInputStream&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UsernamePasswordAuthenticationToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authenticationToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UsernamePasswordAuthenticationToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUsername&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPassword&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authenticationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authenticationToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authentication&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;로그인 시 인증을 위해 실행되는 Method&lt;/li&gt;
&lt;li&gt;오버라이드 해서 Json으로 들어오는 id와 password로 인증을 하도록 변경한다.&lt;/li&gt;
&lt;li&gt;반환 값은 인증된 Authentication 객체이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="successfulauthentication"&gt;
 &lt;strong&gt;successfulAuthentication&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#successfulauthentication" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;protected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;successfulAuthentication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpServletRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HttpServletResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FilterChain&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IOException&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ServletException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserAccount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserAccount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPrincipal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtProcessor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createAuthJwtToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JwtProperties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HEADER_STRING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JwtProperties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TOKEN_PREFIX&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;인증에 성공할 시 실행되는 Method&lt;/li&gt;
&lt;li&gt;인증에 성공할 시 인증된 Account의 정보를 통해 JWT Token을 만들고 헤더(Authentication 헤더)에 포함시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="jwtauthorizationfilter-1"&gt;
 &lt;strong&gt;JwtAuthorizationFilter&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#jwtauthorizationfilter-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JwtAuthorizationFilter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BasicAuthenticationFilter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AccountRepository&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;accountRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JwtProcessor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtProcessor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;JwtAuthorizationFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthenticationManager&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authenticationManager&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AccountRepository&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;accountRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JwtProcessor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtProcessor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authenticationManager&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accountRepository&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;accountRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jwtProcessor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtProcessor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;protected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;doFilterInternal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpServletRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HttpServletResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FilterChain&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IOException&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ServletException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtHeader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JwtProperties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HEADER_STRING&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwtHeader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;jwtHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JwtProperties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TOKEN_PREFIX&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;doFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtProcessor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;extractBearer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwtHeader&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtProcessor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;decodeJwtToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwtToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JwtProperties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;username&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;accountRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NonExistResourceException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;해당 username을 갖는 Account를 찾을 수 없습니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserAccount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UsernamePasswordAuthenticationToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAuthorities&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SecurityContextHolder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;setAuthentication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authentication&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;doFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;JWT로 인가를 하기 위한 클래스&lt;/li&gt;
&lt;li&gt;헤더를 통한 인증 시 적용되는 BasicAuthenticationFilter를 상속받는다.&lt;/li&gt;
&lt;li&gt;BasicAuthenticationFilter는 AuthenticationManager를 사용하기 때문에 super를 사용해서 주입해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="dofilterinternal"&gt;
 &lt;strong&gt;doFilterInternal&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#dofilterinternal" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;protected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;doFilterInternal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpServletRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HttpServletResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FilterChain&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IOException&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ServletException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtHeader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JwtProperties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HEADER_STRING&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwtHeader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;jwtHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JwtProperties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TOKEN_PREFIX&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;doFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtProcessor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;extractBearer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwtHeader&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jwtProcessor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;decodeJwtToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwtToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JwtProperties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;username&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;accountRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NonExistResourceException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;해당 username을 갖는 Account를 찾을 수 없습니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserAccount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UsernamePasswordAuthenticationToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAuthorities&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SecurityContextHolder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;setAuthentication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authentication&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;doFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;필터 적용 시 실행되는 Method.&lt;/li&gt;
&lt;li&gt;헤더에 담겨있는 JWT Token을 디코딩해서 얻은 username값이 올바른지 판단하고 username으로 DB에서 Account를 찾아온다.&lt;/li&gt;
&lt;li&gt;찾아진 Account로 만든 Authentication 객체를 SecurityContextHolder에 넣어서 인가를 처리한다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Docker-Compose] Docker-Compose Command</title><link>https://kyungryeol-yoon.github.io/docker/docker-compose-command/</link><pubDate>Wed, 25 May 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/docker/docker-compose-command/</guid><description>&lt;h2 id="version-확인"&gt;
 Version 확인
 &lt;a class="heading-anchor" href="#version-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker-compose --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="container-생성-및-실행"&gt;
 Container 생성 및 실행
 &lt;a class="heading-anchor" href="#container-%ec%83%9d%ec%84%b1-%eb%b0%8f-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-d&lt;/code&gt; : 백그라운드 실행&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--no-deps&lt;/code&gt; : 링크 서비스 실행하지 않음&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--build&lt;/code&gt; : Image 빌드&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-t&lt;/code&gt; : Timeout을 지정(기본 10초)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker-compose up &lt;span class="o"&gt;[&lt;/span&gt;옵션&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;서비스명&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;특정 서비스들의 경우, 백그라운드로 실행하지 않으면 Container가 생성 및 실행되며, 바로 종료될 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="현재-동작중인-container-상태를-확인"&gt;
 현재 동작중인 Container 상태를 확인
 &lt;a class="heading-anchor" href="#%ed%98%84%ec%9e%ac-%eb%8f%99%ec%9e%91%ec%a4%91%ec%9d%b8-container-%ec%83%81%ed%83%9c%eb%a5%bc-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker-compose ps&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="container-log-출력"&gt;
 Container Log 출력
 &lt;a class="heading-anchor" href="#container-log-%ec%b6%9c%eb%a0%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker-compose logs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="docker-compose-up-명령어를-이용해-생성-및-실행된-container에서-임의의-명령을-실행하기-위해-사용"&gt;
 &lt;code&gt;docker-compose up&lt;/code&gt; 명령어를 이용해 생성 및 실행된 Container에서 임의의 명령을 실행하기 위해 사용
 &lt;a class="heading-anchor" href="#docker-compose-up-%eb%aa%85%eb%a0%b9%ec%96%b4%eb%a5%bc-%ec%9d%b4%ec%9a%a9%ed%95%b4-%ec%83%9d%ec%84%b1-%eb%b0%8f-%ec%8b%a4%ed%96%89%eb%90%9c-container%ec%97%90%ec%84%9c-%ec%9e%84%ec%9d%98%ec%9d%98-%eb%aa%85%eb%a0%b9%ec%9d%84-%ec%8b%a4%ed%96%89%ed%95%98%ea%b8%b0-%ec%9c%84%ed%95%b4-%ec%82%ac%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Container들을 모두 삭제할 경우 &lt;code&gt;docker-compose start&lt;/code&gt;가 아닌, &lt;code&gt;docker-compose up&lt;/code&gt;으로 다시 Container들을 생성 해주어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker-compose run&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;만약 특정 서비스에서 &lt;code&gt;/bin/bash&lt;/code&gt;를 실행시켜 Shell 환경으로 진입하고 싶다면 아래와 같은 명령어를 이용하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;참고로 서비스명과 Container명은 다르다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;서비스명은 &lt;code&gt;docker-compose.yml&lt;/code&gt;의 &lt;code&gt;services:&lt;/code&gt; 밑에 작성한 서비스 이름이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# docker-compose run [서비스명] [명령]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;docker-compose run redis /bin/bash&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="서비스-제어"&gt;
 서비스 제어
 &lt;a class="heading-anchor" href="#%ec%84%9c%eb%b9%84%ec%8a%a4-%ec%a0%9c%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 서비스 시작&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;docker-compose start
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 서비스 정지&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;docker-compose stop
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 서비스 일시 정지&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;docker-compose pause
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 서비스 일시 정지 해제&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;docker-compose unpause
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 서비스 재시작&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;docker-compose restart&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;각각의 설정 뒤에 서비스명을 붙이면 특정 서비스만 제어할 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker-compose restart &lt;span class="o"&gt;[&lt;/span&gt;서비스명&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;{: .prompt-tip }&lt;/p&gt;
&lt;h2 id="docker-compose로-생성한-container들을-일괄-삭제"&gt;
 docker-compose로 생성한 Container들을 일괄 삭제
 &lt;a class="heading-anchor" href="#docker-compose%eb%a1%9c-%ec%83%9d%ec%84%b1%ed%95%9c-container%eb%93%a4%ec%9d%84-%ec%9d%bc%ea%b4%84-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker-compose rm&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;삭제 전, 관련 Container들을 종료 시켜두어야 한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="실행중인-container를-강제로-정지"&gt;
 실행중인 Container를 강제로 정지
 &lt;a class="heading-anchor" href="#%ec%8b%a4%ed%96%89%ec%a4%91%ec%9d%b8-container%eb%a5%bc-%ea%b0%95%ec%a0%9c%eb%a1%9c-%ec%a0%95%ec%a7%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-s&lt;/code&gt; 옵션을 사용하여 시그널을 지정해줄 수 있는데, 아래 코드에서는 SIGINT를 사용하였다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-s&lt;/code&gt; 옵션을 사용하지 않고 &lt;code&gt;docker-compose kill&lt;/code&gt;만 사용할 경우 SIGKILL이 전송된다.&lt;/li&gt;
&lt;li&gt;kill 뒤에 서비스를 지정하여 특정 서비스만 kill할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# docker-compose kill [옵션]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;docker-compose &lt;span class="nb"&gt;kill&lt;/span&gt; -s SIGINT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="네트워크-정보-볼륨-container들을-일괄-정지-및-삭제-처리"&gt;
 네트워크 정보, 볼륨, Container들을 일괄 정지 및 삭제 처리
 &lt;a class="heading-anchor" href="#%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac-%ec%a0%95%eb%b3%b4-%eb%b3%bc%eb%a5%a8-container%eb%93%a4%ec%9d%84-%ec%9d%bc%ea%b4%84-%ec%a0%95%ec%a7%80-%eb%b0%8f-%ec%82%ad%ec%a0%9c-%ec%b2%98%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker-compose down&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;docker-compose down --rmi all&lt;/code&gt; 명령을 사용한다면 모든 Image까지 삭제한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="서비스-포트-번호의-설정-확인"&gt;
 서비스 포트 번호의 설정 확인
 &lt;a class="heading-anchor" href="#%ec%84%9c%eb%b9%84%ec%8a%a4-%ed%8f%ac%ed%8a%b8-%eb%b2%88%ed%98%b8%ec%9d%98-%ec%84%a4%ec%a0%95-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# docker-compose port [서비스명] [포트 번호]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;docker-compose port nginx &lt;span class="m"&gt;80&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="docker-compose-구성-파일의-내용을-확인"&gt;
 docker-compose 구성 파일의 내용을 확인
 &lt;a class="heading-anchor" href="#docker-compose-%ea%b5%ac%ec%84%b1-%ed%8c%8c%ec%9d%bc%ec%9d%98-%eb%82%b4%ec%9a%a9%ec%9d%84-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker-compose config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;docker-compose.yml&lt;/code&gt;의 내용을 출력 해주므로 많이 쓸 일은 없다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubeadm으로 쿠버네티스 클러스터 설치하기 (Ubuntu/Debian)</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubernetes-install-kubeadm-ubuntu/</link><pubDate>Fri, 06 May 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubernetes-install-kubeadm-ubuntu/</guid><description>&lt;h2 id="-1-클러스터-구성-환경"&gt;
 🏗️ 1. 클러스터 구성 환경
 &lt;a class="heading-anchor" href="#-1-%ed%81%b4%eb%9f%ac%ec%8a%a4%ed%84%b0-%ea%b5%ac%ec%84%b1-%ed%99%98%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;본 가이드는 &lt;strong&gt;Ubuntu 20.04 LTS&lt;/strong&gt; 이상 환경을 기준으로 작성되었습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Master Node (1대)&lt;/strong&gt;: 클러스터 관리 및 제어 (최소 2 vCPU, 2GB RAM)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Worker Node (N대)&lt;/strong&gt;: 실제 컨테이너(Pod)가 실행되는 노드&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OS&lt;/strong&gt;: Ubuntu 20.04 / 22.04 LTS&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-2-사전-준비-작업-모든-노드-공통"&gt;
 ⚙️ 2. 사전 준비 작업 (모든 노드 공통)
 &lt;a class="heading-anchor" href="#-2-%ec%82%ac%ec%a0%84-%ec%a4%80%eb%b9%84-%ec%9e%91%ec%97%85-%eb%aa%a8%eb%93%a0-%eb%85%b8%eb%93%9c-%ea%b3%b5%ed%86%b5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;쿠버네티스가 안정적으로 돌아가기 위해 시스템의 기초를 다지는 단계입니다. &lt;strong&gt;모든 노드&lt;/strong&gt;에서 실행해 주세요.&lt;/p&gt;
&lt;h3 id="21-swap-메모리-비활성화-"&gt;
 2.1 Swap 메모리 비활성화 🛑
 &lt;a class="heading-anchor" href="#21-swap-%eb%a9%94%eb%aa%a8%eb%a6%ac-%eb%b9%84%ed%99%9c%ec%84%b1%ed%99%94-" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;쿠버네티스는 성능과 안정성을 위해 스왑 메모리를 사용하지 않습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 즉시 비활성화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo swapoff -a
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 재부팅 시에도 적용되도록 설정 (fstab에서 swap 라인 주석 처리)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;sudo sed -i &lt;span class="s1"&gt;&amp;#39;/swap/s/^/#/&amp;#39;&lt;/span&gt; /etc/fstab
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 확인 (Swap 항목이 0B여야 함)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;free -h&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="22-네트워크-브리지-및-커널-모듈-설정-"&gt;
 2.2 네트워크 브리지 및 커널 모듈 설정 🌐
 &lt;a class="heading-anchor" href="#22-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac-%eb%b8%8c%eb%a6%ac%ec%a7%80-%eb%b0%8f-%ec%bb%a4%eb%84%90-%eb%aa%a8%eb%93%88-%ec%84%a4%ec%a0%95-" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;노드 간 통신과 iptables가 브리지 트래픽을 올바르게 처리하도록 설정합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF | sudo tee /etc/modules-load.d/k8s.conf
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;br_netfilter
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF | sudo tee /etc/sysctl.d/k8s.conf
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;net.bridge.bridge-nf-call-ip6tables = 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;net.bridge.bridge-nf-call-iptables = 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;net.ipv4.ip_forward = 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 설정 적용&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;sudo sysctl --system&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-3-컨테이너-런타임docker-설치"&gt;
 📦 3. 컨테이너 런타임(Docker) 설치
 &lt;a class="heading-anchor" href="#-3-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%eb%9f%b0%ed%83%80%ec%9e%84docker-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;요즘은 &lt;code&gt;Containerd&lt;/code&gt;를 많이 쓰지만, 기본 학습을 위해 가장 친숙한 &lt;code&gt;Docker&lt;/code&gt;를 설치하는 과정입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 패키지 업데이트 및 필수 도구 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Docker 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get install -y docker.io
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Docker 서비스 활성화 및 시작&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Docker cgroup driver를 systemd로 변경 (K8s 권장사항)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF | sudo tee /etc/docker/daemon.json
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;exec-opts&amp;#34;: [&amp;#34;native.cgroupdriver=systemd&amp;#34;],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;log-driver&amp;#34;: &amp;#34;json-file&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;log-opts&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;max-size&amp;#34;: &amp;#34;100m&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;storage-driver&amp;#34;: &amp;#34;overlay2&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl restart docker&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-4-kubernetes-컴포넌트-설치"&gt;
 🛠️ 4. Kubernetes 컴포넌트 설치
 &lt;a class="heading-anchor" href="#-4-kubernetes-%ec%bb%b4%ed%8f%ac%eb%84%8c%ed%8a%b8-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;클러스터 운영의 핵심 도구인 &lt;code&gt;kubeadm&lt;/code&gt;, &lt;code&gt;kubelet&lt;/code&gt;, &lt;code&gt;kubectl&lt;/code&gt;을 설치합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 구글 클라우드 퍼블릭 키 다운로드&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg &lt;span class="o"&gt;[&lt;/span&gt;https://packages.cloud.google.com/apt/doc/apt-key.gpg&lt;span class="o"&gt;](&lt;/span&gt;https://packages.cloud.google.com/apt/doc/apt-key.gpg&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 쿠버네티스 리포지토리 추가&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] [https://apt.kubernetes.io/](https://apt.kubernetes.io/) kubernetes-xenial main&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/apt/sources.list.d/kubernetes.list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 패키지 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get install -y kubelet kubeadm kubectl
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 버전 업데이트로 인한 혼란 방지를 위해 버전 고정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-mark hold kubelet kubeadm kubectl&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-5-마스터-노드-초기화-master-node-only"&gt;
 🚩 5. 마스터 노드 초기화 (Master Node Only)
 &lt;a class="heading-anchor" href="#-5-%eb%a7%88%ec%8a%a4%ed%84%b0-%eb%85%b8%eb%93%9c-%ec%b4%88%ea%b8%b0%ed%99%94-master-node-only" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;이제 실제로 클러스터를 시작합니다. &lt;strong&gt;마스터 노드에서만&lt;/strong&gt; 실행하세요.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pod-network-cidr은 이후 설치할 CNI(예: Flannel)에 맞춰 설정합니다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm init --pod-network-cidr&lt;span class="o"&gt;=&lt;/span&gt;10.244.0.0/16&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-초기화-완료-후-설정-일반-사용자용"&gt;
 💡 초기화 완료 후 설정 (일반 사용자용)
 &lt;a class="heading-anchor" href="#-%ec%b4%88%ea%b8%b0%ed%99%94-%ec%99%84%eb%a3%8c-%ed%9b%84-%ec%84%a4%ec%a0%95-%ec%9d%bc%eb%b0%98-%ec%82%ac%ec%9a%a9%ec%9e%90%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;초기화가 끝나면 화면에 나오는 명령어를 복사해서 실행해 주세요.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mkdir -p &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo cp -i /etc/kubernetes/admin.conf &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo chown &lt;span class="k"&gt;$(&lt;/span&gt;id -u&lt;span class="k"&gt;)&lt;/span&gt;:&lt;span class="k"&gt;$(&lt;/span&gt;id -g&lt;span class="k"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;주의!&lt;/strong&gt; 마지막에 출력되는 &lt;code&gt;kubeadm join ...&lt;/code&gt; 명령어를 별도로 메모장 등에 꼭 저장해 두세요. 워커 노드를 연결할 때 필요합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-6-네트워크-플러그인cni-설치"&gt;
 🤝 6. 네트워크 플러그인(CNI) 설치
 &lt;a class="heading-anchor" href="#-6-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac-%ed%94%8c%eb%9f%ac%ea%b7%b8%ec%9d%b8cni-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;파드(Pod)끼리 통신할 수 있도록 &lt;strong&gt;Flannel&lt;/strong&gt; 네트워크를 설치합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f &lt;span class="o"&gt;[&lt;/span&gt;https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml&lt;span class="o"&gt;](&lt;/span&gt;https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-7-워커-노드-연결-및-상태-확인"&gt;
 ✅ 7. 워커 노드 연결 및 상태 확인
 &lt;a class="heading-anchor" href="#-7-%ec%9b%8c%ec%bb%a4-%eb%85%b8%eb%93%9c-%ec%97%b0%ea%b2%b0-%eb%b0%8f-%ec%83%81%ed%83%9c-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;이제 &lt;strong&gt;워커 노드&lt;/strong&gt;로 가서 아까 저장해둔 &lt;code&gt;join&lt;/code&gt; 명령어를 입력합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm join &amp;lt;MASTER_IP&amp;gt;:6443 --token &amp;lt;TOKEN&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; --discovery-token-ca-cert-hash sha256:&amp;lt;HASH&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;마지막으로 마스터 노드에서 상태를 확인합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get nodes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] kubectl logs command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-logs/</link><pubDate>Tue, 12 Apr 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-logs/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl logs &lt;span class="o"&gt;[&lt;/span&gt;Pod 이름&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;Container 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 Pod 내부에서 my-container 이름의 Container의 로그를 출력할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl logs my-pod my-container&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--namespace&lt;/code&gt;: Pod가 포함된 Namespace를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-namespace Namespace에 속한 my-pod 이름의 Pod 내부에서 my-container 이름의 Container의 로그를 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl logs my-pod -n my-namespace my-container&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--follow&lt;/code&gt;, &lt;code&gt;-f&lt;/code&gt;: 로그를 실시간으로 출력&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 Pod 내부에서 my-container 이름의 Container의 로그를 실시간으로 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl logs my-pod my-container -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--tail&lt;/code&gt;: 출력할 로그 라인 수를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 Pod 내부에서 my-container 이름의 Container의 로그를 최근 50개 라인만 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl logs my-pod my-container --tail&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;50&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--since&lt;/code&gt;: 출력할 로그의 시작 시간을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 Pod 내부에서 my-container 이름의 Container에서 1시간 이전부터 출력할 로그를 선택&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl logs my-pod my-container --since&lt;span class="o"&gt;=&lt;/span&gt;1h&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Ubuntu] Install containerd on Ubuntu 22.04</title><link>https://kyungryeol-yoon.github.io/linux/package/install-containerd-on-ubuntu-22-04/</link><pubDate>Wed, 23 Mar 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/package/install-containerd-on-ubuntu-22-04/</guid><description>&lt;h2 id="containerd-설치--ubuntu-2204"&gt;
 containerd 설치 – Ubuntu 22.04
 &lt;a class="heading-anchor" href="#containerd-%ec%84%a4%ec%b9%98--ubuntu-2204" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;containerd는 컨테이너의 라이프사이클(이미지 다운로드, 네트워크, 컨테이너 실행 등)을 관리하는 런타임입니다. Kubernetes에서는 기본 컨테이너 런타임으로 containerd를 사용합니다.&lt;/p&gt;
&lt;p&gt;아래 절차는 Ubuntu 22.04 기준이며 Kubernetes 등 컨테이너 오케스트레이션 환경에서 흔히 사용하는 설치 방법입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="사전-요구사항"&gt;
 사전 요구사항
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%a0%84-%ec%9a%94%ea%b5%ac%ec%82%ac%ed%95%ad" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntu 22.04 LTS&lt;/li&gt;
&lt;li&gt;sudo 권한 사용자&lt;/li&gt;
&lt;li&gt;인터넷 연결&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="1-패키지-준비--docker-저장소-추가"&gt;
 1) 패키지 준비 &amp;amp; Docker 저장소 추가
 &lt;a class="heading-anchor" href="#1-%ed%8c%a8%ed%82%a4%ec%a7%80-%ec%a4%80%eb%b9%84--docker-%ec%a0%80%ec%9e%a5%ec%86%8c-%ec%b6%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;APT로 containerd를 설치하기 위해 Docker 저장소를 추가합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo apt install -y ca-certificates curl gnupg lsb-release&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;그 다음 Docker 공식 GPG 키를 추가하고 저장소를 등록합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo mkdir -p /etc/apt/keyrings
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;curl -fsSL https://download.docker.com/linux/ubuntu/gpg &lt;span class="p"&gt;|&lt;/span&gt; sudo gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;deb [arch=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;dpkg --print-architecture&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; https://download.docker.com/linux/ubuntu &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;lsb_release -cs&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; stable&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="2-containerd-설치"&gt;
 2) containerd 설치
 &lt;a class="heading-anchor" href="#2-containerd-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Docker 저장소를 추가한 후, &lt;code&gt;containerd.io&lt;/code&gt; 패키지를 설치합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo apt install -y containerd.io&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;설치 후 서비스 상태를 확인합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl status containerd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;서비스가 &lt;strong&gt;active (running)&lt;/strong&gt; 상태면 정상입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="3-containerd-기본-설정-파일-생성"&gt;
 3) containerd 기본 설정 파일 생성
 &lt;a class="heading-anchor" href="#3-containerd-%ea%b8%b0%eb%b3%b8-%ec%84%a4%ec%a0%95-%ed%8c%8c%ec%9d%bc-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Kubernetes와 호환되도록 기본 설정 파일을 생성합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo mkdir -p /etc/containerd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo containerd config default &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/containerd/config.toml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;생성된 &lt;code&gt;/etc/containerd/config.toml&lt;/code&gt;에서 &lt;code&gt;SystemdCgroup&lt;/code&gt; 값을 &lt;strong&gt;true&lt;/strong&gt;로 설정합니다. 이는 cgroup 드라이버를 systemd로 맞추기 위함입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo sed -i &lt;span class="s1"&gt;&amp;#39;s/SystemdCgroup = false/SystemdCgroup = true/&amp;#39;&lt;/span&gt; /etc/containerd/config.toml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;설정 완료 후 containerd를 재시작합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl restart containerd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="4-설치-확인"&gt;
 4) 설치 확인
 &lt;a class="heading-anchor" href="#4-%ec%84%a4%ec%b9%98-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;containerd 소켓과 상태를 확인합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ls -l /var/run/containerd/containerd.sock
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl status containerd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;정상적으로 실행 중이라면 해당 런타임을 Kubernetes에서 사용할 준비가 된 것입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="장점-및-고려사항"&gt;
 장점 및 고려사항
 &lt;a class="heading-anchor" href="#%ec%9e%a5%ec%a0%90-%eb%b0%8f-%ea%b3%a0%eb%a0%a4%ec%82%ac%ed%95%ad" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;containerd는 Docker보다 &lt;strong&gt;가볍고 Kubernetes 친화적&lt;/strong&gt;입니다.&lt;/li&gt;
&lt;li&gt;Ubuntu 22.04 기본 패키지 버전이 Kubernetes 요구 버전보다 낮은 경우가 있어, Docker 저장소에서 설치하는 것이 안정적이라는 경험이 있습니다 (예: containerd 1.6 이상)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="요약"&gt;
 요약
 &lt;a class="heading-anchor" href="#%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Ubuntu 22.04에 containerd를 설치하고 Kubernetes 환경에 맞게 설정하는 과정은 다음과 같습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Docker 저장소 추가&lt;/li&gt;
&lt;li&gt;containerd 설치&lt;/li&gt;
&lt;li&gt;config.toml 생성 및 SystemdCgroup 활성화&lt;/li&gt;
&lt;li&gt;서비스 재시작 및 상태 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이제 이 노드에서 컨테이너를 실행하거나 Kubernetes 클러스터 환경을 구성할 준비가 되었습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id="정리-체크포인트"&gt;
 정리 체크포인트
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a6%ac-%ec%b2%b4%ed%81%ac%ed%8f%ac%ec%9d%b8%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;✔ Docker 저장소 추가를 통해 최신 &lt;code&gt;containerd.io&lt;/code&gt; 설치&lt;br&gt;
✔ &lt;code&gt;SystemdCgroup=true&lt;/code&gt; 설정으로 Kubernetes 호환성 확보&lt;br&gt;
✔ Ubuntu 22.04 환경에 맞춘 기본 설치 가이드&lt;/p&gt;</description></item><item><title>[Kubernetes] k3s로 손쉬운 Kubernetes 클러스터 만들기 (Windows + Multipass + Ubuntu)</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-k3s-on-multipasswindows/</link><pubDate>Mon, 21 Mar 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-k3s-on-multipasswindows/</guid><description>&lt;h2 id="k3s로-손쉬운-kubernetes-클러스터-만들기-windows--multipass--ubuntu"&gt;
 k3s로 손쉬운 Kubernetes 클러스터 만들기 (Windows + Multipass + Ubuntu)
 &lt;a class="heading-anchor" href="#k3s%eb%a1%9c-%ec%86%90%ec%89%ac%ec%9a%b4-kubernetes-%ed%81%b4%eb%9f%ac%ec%8a%a4%ed%84%b0-%eb%a7%8c%eb%93%a4%ea%b8%b0-windows--multipass--ubuntu" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Windows 환경에서 &lt;strong&gt;Multipass + Ubuntu VM&lt;/strong&gt;을 활용해 &lt;strong&gt;k3s 기반 Kubernetes 클러스터&lt;/strong&gt;를 만드는 실습 가이드입니다.&lt;br&gt;
가볍고 빠르게 Kubernetes 클러스터를 실험해보고 싶을 때, k3s는 매우 적합합니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;k3s는 Rancher Labs에서 만든 경량 Kubernetes 배포판입니다. 프로덕션보다는 테스트/개발/엣지 환경에서 많이 활용됩니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-목표"&gt;
 🎯 목표
 &lt;a class="heading-anchor" href="#-%eb%aa%a9%ed%91%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Windows에서 Ubuntu VM 여러 대를 띄우기&lt;/li&gt;
&lt;li&gt;Master 노드 1대 + Worker 노드 3대를 구성&lt;/li&gt;
&lt;li&gt;Ubuntu 간 통신 및 고정 IP 설정&lt;/li&gt;
&lt;li&gt;k3s 설치 및 노드 조인&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-사용-도구"&gt;
 🛠️ 사용 도구
 &lt;a class="heading-anchor" href="#-%ec%82%ac%ec%9a%a9-%eb%8f%84%ea%b5%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;도구&lt;/th&gt;
					&lt;th&gt;역할&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Windows + Hyper-V&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;하이퍼바이저&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Multipass&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Ubuntu VM 생성&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;k3s&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Lightweight Kubernetes 배포&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-1-ubuntu-vm-생성-multipass"&gt;
 🐧 1. Ubuntu VM 생성 (Multipass)
 &lt;a class="heading-anchor" href="#-1-ubuntu-vm-%ec%83%9d%ec%84%b1-multipass" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Windows에서 다음과 같이 Ubuntu 인스턴스 4대를 띄웁니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;multipass&lt;/span&gt; &lt;span class="n"&gt;launch&lt;/span&gt; &lt;span class="n"&gt;-n&lt;/span&gt; &lt;span class="nb"&gt;k3s-master&lt;/span&gt; &lt;span class="n"&gt;-c&lt;/span&gt; &lt;span class="mf"&gt;2&lt;/span&gt; &lt;span class="n"&gt;-m&lt;/span&gt; &lt;span class="n"&gt;2G&lt;/span&gt; &lt;span class="n"&gt;-d&lt;/span&gt; &lt;span class="n"&gt;20G&lt;/span&gt; &lt;span class="n"&gt;impish&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;multipass&lt;/span&gt; &lt;span class="n"&gt;launch&lt;/span&gt; &lt;span class="n"&gt;-n&lt;/span&gt; &lt;span class="nb"&gt;k3s-node1&lt;/span&gt; &lt;span class="n"&gt;-c&lt;/span&gt; &lt;span class="mf"&gt;2&lt;/span&gt; &lt;span class="n"&gt;-m&lt;/span&gt; &lt;span class="n"&gt;2G&lt;/span&gt; &lt;span class="n"&gt;-d&lt;/span&gt; &lt;span class="n"&gt;20G&lt;/span&gt; &lt;span class="n"&gt;impish&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;multipass&lt;/span&gt; &lt;span class="n"&gt;launch&lt;/span&gt; &lt;span class="n"&gt;-n&lt;/span&gt; &lt;span class="nb"&gt;k3s-node2&lt;/span&gt; &lt;span class="n"&gt;-c&lt;/span&gt; &lt;span class="mf"&gt;2&lt;/span&gt; &lt;span class="n"&gt;-m&lt;/span&gt; &lt;span class="n"&gt;2G&lt;/span&gt; &lt;span class="n"&gt;-d&lt;/span&gt; &lt;span class="n"&gt;20G&lt;/span&gt; &lt;span class="n"&gt;impish&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;multipass&lt;/span&gt; &lt;span class="n"&gt;launch&lt;/span&gt; &lt;span class="n"&gt;-n&lt;/span&gt; &lt;span class="nb"&gt;k3s-node3&lt;/span&gt; &lt;span class="n"&gt;-c&lt;/span&gt; &lt;span class="mf"&gt;2&lt;/span&gt; &lt;span class="n"&gt;-m&lt;/span&gt; &lt;span class="n"&gt;2G&lt;/span&gt; &lt;span class="n"&gt;-d&lt;/span&gt; &lt;span class="n"&gt;20G&lt;/span&gt; &lt;span class="n"&gt;impish&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;각 VM은 CPU 2코어, 메모리 2GB, 디스크 20GB로 설정합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-2-swap-비활성화"&gt;
 🚫 2. Swap 비활성화
 &lt;a class="heading-anchor" href="#-2-swap-%eb%b9%84%ed%99%9c%ec%84%b1%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;각 Ubuntu VM에서 Swap을 끕니다. (k3s/k8s 필수)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo swapoff -a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;각 노드에서 동일하게 실행합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-3-네트워크-고려사항"&gt;
 📡 3. 네트워크 고려사항
 &lt;a class="heading-anchor" href="#-3-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac-%ea%b3%a0%eb%a0%a4%ec%82%ac%ed%95%ad" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Multipass가 Hyper-V에서 제공하는 기본 네트워크는 재부팅 시 IP가 바뀝니다.
이를 해결할 수 있는 2가지 방법:&lt;/p&gt;
&lt;h3 id="-방법-1-hyper-v-내부-네트워크--고정-ip"&gt;
 ✔ 방법 1: Hyper-V 내부 네트워크 + 고정 IP
 &lt;a class="heading-anchor" href="#-%eb%b0%a9%eb%b2%95-1-hyper-v-%eb%82%b4%eb%b6%80-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac--%ea%b3%a0%ec%a0%95-ip" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Hyper-V 내부 스위치를 생성하고 NAT로 네트워크를 구성해 고정 IP를 할당할 수 있습니다.
이후 multipass VM 생성 시 &lt;strong&gt;새로 생성한 스위치&lt;/strong&gt;를 지정합니다.&lt;/p&gt;
&lt;h3 id="-방법-2-호스트-시스템-hosts-파일-활용"&gt;
 ✔ 방법 2: 호스트 시스템 hosts 파일 활용
 &lt;a class="heading-anchor" href="#-%eb%b0%a9%eb%b2%95-2-%ed%98%b8%ec%8a%a4%ed%8a%b8-%ec%8b%9c%ec%8a%a4%ed%85%9c-hosts-%ed%8c%8c%ec%9d%bc-%ed%99%9c%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;재부팅 시 IP 변경이 빈번한 환경에서 hosts 파일에 도메인/IP 관계를 적어 관리할 수도 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-4-k3s-설치--master"&gt;
 ☸️ 4. k3s 설치 – Master
 &lt;a class="heading-anchor" href="#-4-k3s-%ec%84%a4%ec%b9%98--master" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Master 노드에서 다음 명령으로 k3s를 설치합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -sfL https://get.k3s.io &lt;span class="p"&gt;|&lt;/span&gt; sh -&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;설치가 완료되면 다음 파일을 복사합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo cat /var/lib/rancher/k3s/server/node-token&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이 토큰은 Worker가 Master에 조인할 때 필요합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-5-k3s-설치--worker-노드-조인"&gt;
 👷 5. k3s 설치 – Worker 노드 조인
 &lt;a class="heading-anchor" href="#-5-k3s-%ec%84%a4%ec%b9%98--worker-%eb%85%b8%eb%93%9c-%ec%a1%b0%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Master에서 받은 토큰을 이용하여 각 Worker 노드를 클러스터에 조인합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -sfL https://get.k3s.io &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nv"&gt;K3S_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;lt;토큰&amp;gt;&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;K3S_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://&amp;lt;MASTER_IP&amp;gt;:6443&amp;#34;&lt;/span&gt; sh -&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;각 Worker에서도 위 명령을 반복 실행합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-6-kubectl-설정-관리-pc"&gt;
 🔧 6. kubectl 설정 (관리 PC)
 &lt;a class="heading-anchor" href="#-6-kubectl-%ec%84%a4%ec%a0%95-%ea%b4%80%eb%a6%ac-pc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Master VM에서 kubeconfig 파일을 복사하여 로컬 kubectl에서 활용합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;multipass &lt;span class="nb"&gt;exec&lt;/span&gt; k3s-master -- sudo cat /etc/rancher/k3s/k3s.yaml &amp;gt; k3s.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;복사한 &lt;code&gt;k3s.yaml&lt;/code&gt;을 열고 &lt;strong&gt;server 주소&lt;/strong&gt;를 Master IP로 변경합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://&amp;lt;MASTER_IP&amp;gt;:6443&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;그 후 로컬에서 아래처럼 kubectl을 실행합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;/k3s.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl get nodes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;성공적으로 노드가 등록되어 있는지 확인합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-팁"&gt;
 💡 팁
 &lt;a class="heading-anchor" href="#-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;k9s&lt;/strong&gt; 같은 터미널 UI 도구를 설치하면 클러스터 모니터링이 편해집니다.&lt;/li&gt;
&lt;li&gt;yaml manifest를 여러 VM에 배포할 때는 네트워크 지연을 고려하세요.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-정리"&gt;
 🧠 정리
 &lt;a class="heading-anchor" href="#-%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;단계&lt;/th&gt;
					&lt;th&gt;요약&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;VM 생성&lt;/td&gt;
					&lt;td&gt;Multipass로 Ubuntu VM 띄우기&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Swap Off&lt;/td&gt;
					&lt;td&gt;Kubernetes 요구 스왑 비활성화&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;k3s 설치&lt;/td&gt;
					&lt;td&gt;Master + Worker&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;토큰&lt;/td&gt;
					&lt;td&gt;Master node-token 확보&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Worker Join&lt;/td&gt;
					&lt;td&gt;토큰 + Master IP 활용&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;kubectl&lt;/td&gt;
					&lt;td&gt;kubeconfig로 원격 제어&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📌 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;k3s는 &lt;strong&gt;lightweight Kubernetes&lt;/strong&gt;로, 실제 운영보다는 &lt;strong&gt;개발/테스트/엣지 환경&lt;/strong&gt;에서 적합합니다.
멀티 VM 환경을 손쉽게 시도해보고 싶을 때 매우 유용합니다.&lt;/p&gt;
&lt;hr&gt;</description></item><item><title>[Kubernetes] kubectl attach command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-attach/</link><pubDate>Sat, 05 Mar 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-attach/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl attach &lt;span class="o"&gt;[&lt;/span&gt;파드 이름&lt;span class="o"&gt;]&lt;/span&gt; -c &lt;span class="o"&gt;[&lt;/span&gt;컨테이너 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod Pod의 my-container 컨테이너 내부의 터미널 세션에 접속할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl attach my-pod -c my-container&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-c&lt;/code&gt;, &lt;code&gt;--container&lt;/code&gt;: 컨테이너 이름을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 파드의 my-container 컨테이너 내부의 터미널 세션에 접속&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl attach my-pod -c my-container&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--stdin&lt;/code&gt;, &lt;code&gt;--tty&lt;/code&gt;: 터미널 입력/출력을 가능하게 한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 파드의 my-container 컨테이너 내부의 터미널 세션에 접속하면서 터미널 입력/출력을 가능하게 한다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl attach my-pod -c my-container --stdin --tty&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubectl certificate command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-certificate/</link><pubDate>Tue, 15 Feb 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-certificate/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create certificate &lt;span class="o"&gt;[&lt;/span&gt;이름&lt;span class="o"&gt;]&lt;/span&gt; --cert &lt;span class="o"&gt;[&lt;/span&gt;인증서 파일 경로&lt;span class="o"&gt;]&lt;/span&gt; --key &lt;span class="o"&gt;[&lt;/span&gt;개인 키 파일 경로&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-cert.crt 파일과 my-cert.key 파일을 사용하여 my-cert 인증서를 생성할 수 있습니다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl create certificate my-cert --cert&lt;span class="o"&gt;=&lt;/span&gt;./my-cert.crt --key&lt;span class="o"&gt;=&lt;/span&gt;./my-cert.key&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--cert&lt;/code&gt;: 인증서 파일 경로를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-cert.crt 파일을 사용하여 인증서를 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl create certificate my-cert --cert&lt;span class="o"&gt;=&lt;/span&gt;./my-cert.crt --key&lt;span class="o"&gt;=&lt;/span&gt;./my-cert.key&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--key&lt;/code&gt;: 개인 키 파일 경로를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-cert.key 파일을 사용하여 인증서를 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl create certificate my-cert --cert&lt;span class="o"&gt;=&lt;/span&gt;./my-cert.crt --key&lt;span class="o"&gt;=&lt;/span&gt;./my-cert.key&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--namespace&lt;/code&gt;: 네임스페이스를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-namespace 네임스페이스에 my-cert 인증서를 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl create certificate my-cert --cert&lt;span class="o"&gt;=&lt;/span&gt;./my-cert.crt --key&lt;span class="o"&gt;=&lt;/span&gt;./my-cert.key --namespace&lt;span class="o"&gt;=&lt;/span&gt;my-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] 사이드카 컨테이너(Sidecar Container) 이해</title><link>https://kyungryeol-yoon.github.io/kubernetes/concepts/sidecar-container/</link><pubDate>Wed, 02 Feb 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/concepts/sidecar-container/</guid><description>&lt;h2 id="-사이드카-컨테이너sidecar-container란"&gt;
 🚀 사이드카 컨테이너(Sidecar Container)란?
 &lt;a class="heading-anchor" href="#-%ec%82%ac%ec%9d%b4%eb%93%9c%ec%b9%b4-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88sidecar-container%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;사이드카 컨테이너&lt;/strong&gt;는 주 컨테이너(main container)와 함께 &lt;strong&gt;동일 Pod에서 실행되는 보조 컨테이너&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;주 목적은:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;주 컨테이너의 기능을 &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;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="1-특징"&gt;
 1️⃣ 특징
 &lt;a class="heading-anchor" href="#1-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;독립적 실행&lt;/strong&gt;: 주 컨테이너와 별개로 실행되지만 Pod 단위로 배포&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;보조 역할&lt;/strong&gt;: 로깅, 모니터링, 프록시, 보안, 설정 관리 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;재사용 가능&lt;/strong&gt;: 동일한 사이드카 컨테이너를 여러 Pod에서 활용 가능&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;주 컨테이너와 통신&lt;/strong&gt;: 로컬 네트워크, 공유 볼륨, 환경 변수 등을 통해 통신&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="2-대표-사용-사례"&gt;
 2️⃣ 대표 사용 사례
 &lt;a class="heading-anchor" href="#2-%eb%8c%80%ed%91%9c-%ec%82%ac%ec%9a%a9-%ec%82%ac%eb%a1%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;역할&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;로깅&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Fluentd/Logstash 같은 로그 수집 에이전트&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;모니터링/메트릭&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Prometheus exporter, 데이터 수집&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;프록시/서비스 메시&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Envoy, Istio Sidecar Proxy&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;보안/인증&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;TLS 인증서 갱신, Vault agent&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;캐싱/프록시&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Redis/Memcached 프록시로 요청 처리&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="3-아키텍처-예시"&gt;
 3️⃣ 아키텍처 예시
 &lt;a class="heading-anchor" href="#3-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Pod
├─ Main Container (애플리케이션)
├─ Sidecar Container (로깅/프록시)
└─ 공유 볼륨&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Main Container: 비즈니스 로직&lt;/li&gt;
&lt;li&gt;Sidecar Container: 보조 기능&lt;/li&gt;
&lt;li&gt;Shared Volume: 로그, 설정, 캐시 데이터 공유&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 주 컨테이너 코드를 건드리지 않고 기능을 확장할 수 있는 구조&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="4-kubernetes에서의-사이드카"&gt;
 4️⃣ Kubernetes에서의 사이드카
 &lt;a class="heading-anchor" href="#4-kubernetes%ec%97%90%ec%84%9c%ec%9d%98-%ec%82%ac%ec%9d%b4%eb%93%9c%ec%b9%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Pod 단위로 배포&lt;/li&gt;
&lt;li&gt;Deployment/StatefulSet 안에서 Main Container와 동일 Pod에 정의&lt;/li&gt;
&lt;li&gt;Sidecar는 주 컨테이너 시작 전후 관계 설정 가능 (&lt;code&gt;initContainer&lt;/code&gt;와 구분)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-app-pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-app:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;log-agent&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;fluentd:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;shared-logs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/log/app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;shared-logs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;emptyDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="5-장점"&gt;
 5️⃣ 장점
 &lt;a class="heading-anchor" href="#5-%ec%9e%a5%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;주 컨테이너를 &lt;strong&gt;단순하게 유지&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;기능 확장&lt;/strong&gt;과 &lt;strong&gt;유지보수 분리&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;재사용 가능&lt;/strong&gt; → 여러 서비스에 공통 기능 적용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="6-요약"&gt;
 6️⃣ 요약
 &lt;a class="heading-anchor" href="#6-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;사이드카 컨테이너 = &lt;strong&gt;주 컨테이너 보조 컨테이너&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;로그 수집, 프록시, 모니터링 등 부가 기능 수행&lt;/li&gt;
&lt;li&gt;Pod 단위로 배포되고 공유 볼륨/네트워크로 주 컨테이너와 상호작용&lt;/li&gt;
&lt;li&gt;주 컨테이너 코드를 변경하지 않고 기능 확장 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 결론: 사이드카 패턴은 &lt;strong&gt;마이크로서비스 환경에서 확장성과 재사용성을 높이는 핵심 패턴&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubectl get command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-get/</link><pubDate>Sat, 22 Jan 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-get/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;옵션&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;리소스 종류
&lt;ul&gt;
&lt;li&gt;Pod&lt;/li&gt;
&lt;li&gt;Service&lt;/li&gt;
&lt;li&gt;Deployment&lt;/li&gt;
&lt;li&gt;ConfigMap&lt;/li&gt;
&lt;li&gt;Secret&lt;/li&gt;
&lt;li&gt;Node&lt;/li&gt;
&lt;li&gt;Namespace&lt;/li&gt;
&lt;li&gt;PersistentVolume&lt;/li&gt;
&lt;li&gt;StorageClass&lt;/li&gt;
&lt;li&gt;Ingress&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--all-namespaces&lt;/code&gt;, &lt;code&gt;-A&lt;/code&gt;: 모든 네임스페이스에서 리소스를 조회&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods --all-namespaces&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--selector&lt;/code&gt;, &lt;code&gt;-l&lt;/code&gt;: 라벨 셀렉터를 사용하여 특정 리소스를 조회&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods -l &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;myapp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--output&lt;/code&gt;, &lt;code&gt;-o&lt;/code&gt;: 출력 형식을 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods -o wide&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--watch&lt;/code&gt;, &lt;code&gt;-w&lt;/code&gt;: 리소스 변경 사항을 실시간으로 모니터링&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods -w&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--sort-by&lt;/code&gt;: 조회 결과를 정렬&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# &amp;#34;--sort-by=.metadata.creationTimestamp&amp;#34; 명령은 생성된 시간에 따라 정렬&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods --sort-by&lt;span class="o"&gt;=&lt;/span&gt;.status.phase&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;-&lt;code&gt; --field-selector&lt;/code&gt;: 필드 셀렉터를 사용하여 특정 필드의 값을 기준으로 리소스를 조회
&lt;code&gt;bash kubectl get pods --field-selector=status.phase=Running &lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--show-labels&lt;/code&gt;: 리소스에 대한 라벨 정보를 표시&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods --show-labels&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--no-headers&lt;/code&gt;: 표 헤더를 표시하지 않는다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods --no-headers&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--export&lt;/code&gt;: 출력 결과에서 불필요한 정보를 제거&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# &amp;#34;my-pod&amp;#34; 이름을 가진 파드의 YAML 파일을 생성, 이 때 --export 옵션을 사용하면 출력 결과에서 상태 및 메타데이터와 같은 불필요한 정보가 제거&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pod my-pod -o yaml --export &amp;gt; my-pod.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--field-selector&lt;/code&gt;와 함께 사용할 수 있는 필드는 다양&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;quot;status.phase&amp;quot;&lt;/code&gt; 필드는 파드의 실행 상태를 나타내며, &lt;code&gt;&amp;quot;metadata.name&amp;quot;&lt;/code&gt; 필드는 파드의 이름을 나타낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--show-kind&lt;/code&gt;: 조회 결과에 리소스 유형을 표시&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods --show-kind&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--ignore-not-found&lt;/code&gt;: 조회 결과가 없는 경우 에러를 발생시키지 않고 정상적으로 종료&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods my-pod --ignore-not-found&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--timeout&lt;/code&gt;: 조회 시간 제한을 설정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# &amp;#34;--timeout=5s&amp;#34; 명령은 5초 동안 조회를 시도&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods --timeout&lt;span class="o"&gt;=&lt;/span&gt;10s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--selector&lt;/code&gt;와 함께 사용할 수 있는 라벨 셀렉터의 사용 예시는 다음과 같다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# &amp;#34;app=myapp&amp;#34; 라벨을 가진 파드를 조회&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods -l &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;myapp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# &amp;#34;app&amp;#34; 라벨이 &amp;#34;myapp&amp;#34;이 아닌 파드를 조회&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods -l app!&lt;span class="o"&gt;=&lt;/span&gt;myapp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# &amp;#34;app&amp;#34; 라벨이 &amp;#34;myapp&amp;#34; 또는 &amp;#34;yourapp&amp;#34;인 파드를 조회&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods -l &lt;span class="s1"&gt;&amp;#39;app in (myapp, yourapp)&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# &amp;#34;app&amp;#34; 라벨이 &amp;#34;myapp&amp;#34; 또는 &amp;#34;yourapp&amp;#34;이 아닌 파드를 조회&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods -l &lt;span class="s1"&gt;&amp;#39;app notin (myapp, yourapp)&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubectl describe command</title><link>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-describe/</link><pubDate>Tue, 11 Jan 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/kubectl/kubernetes-command-describe/</guid><description>&lt;h2 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl describe &lt;span class="o"&gt;[&lt;/span&gt;리소스 종류&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;리소스 이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 Pod 리소스에 대한 자세한 정보를 출력할 수 있다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kubectl describe pod my-pod&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--namespace&lt;/code&gt;: 리소스가 포함된 Namespace를 지정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-namespace Namespace에 속한 my-pod 이름의 Pod 리소스에 대한 자세한 정보를 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl describe pod my-pod --namespace my-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--show-events&lt;/code&gt;: 리소스의 이벤트를 출력&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 Pod 리소스에 대한 자세한 정보와 해당 리소스의 이벤트를 함께 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl describe pod my-pod --show-events&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--export&lt;/code&gt;: YAML 형식으로 출력&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-pod 이름의 Pod 리소스에 대한 자세한 정보를 YAML 형식으로 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl describe pod my-pod --export&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--recursive&lt;/code&gt;: 서브리소스의 정보도 출력&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# my-deployment 이름의 Deployment 리소스에 대한 자세한 정보와 해당 Deployment 리소스에 포함된 Pod 리소스의 자세한 정보도 함께 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl describe deployment my-deployment --recursive&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://kubernetes.io/docs/reference/kubectl/cheatsheet/"&gt;kubectl-cheatsheet&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Microservices &amp; Container] 마이크로서비스 패턴과 컨테이너 이미지 구조</title><link>https://kyungryeol-yoon.github.io/backend/architecture/microservices-and-container-architecture/</link><pubDate>Sun, 02 Jan 2022 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/architecture/microservices-and-container-architecture/</guid><description>&lt;h1 id="-마이크로서비스와-컨테이너-이미지-구조-시리즈"&gt;
 🚀 마이크로서비스와 컨테이너 이미지 구조 시리즈
 &lt;a class="heading-anchor" href="#-%eb%a7%88%ec%9d%b4%ed%81%ac%eb%a1%9c%ec%84%9c%eb%b9%84%ec%8a%a4%ec%99%80-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%ec%9d%b4%eb%af%b8%ec%a7%80-%ea%b5%ac%ec%a1%b0-%ec%8b%9c%eb%a6%ac%ec%a6%88" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;이번 포스트는 &lt;strong&gt;마이크로서비스 패턴&lt;/strong&gt;과 &lt;strong&gt;컨테이너 이미지 구조 및 최적화&lt;/strong&gt;를&lt;br&gt;
연계해서 이해할 수 있도록 정리한 시리즈 글입니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 각 섹션은 독립적으로 읽을 수 있으며, 링크를 통해 관련 주제를 탐색할 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-1-microservice-pattern-개요"&gt;
 📌 1. Microservice Pattern 개요
 &lt;a class="heading-anchor" href="#-1-microservice-pattern-%ea%b0%9c%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;마이크로서비스 아키텍처(Microservice Architecture)는 하나의 애플리케이션을&lt;br&gt;
&lt;strong&gt;작고 독립적인 서비스 단위&lt;/strong&gt;로 분리하여 운영하는 아키텍처 스타일입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;특징
&lt;ul&gt;
&lt;li&gt;작은 단위, 단일 책임&lt;/li&gt;
&lt;li&gt;독립 배포 가능&lt;/li&gt;
&lt;li&gt;독립 데이터 저장소&lt;/li&gt;
&lt;li&gt;REST, gRPC, 메시지 큐 등 통신&lt;/li&gt;
&lt;li&gt;팀 단위 개발 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="핵심-패턴"&gt;
 핵심 패턴
 &lt;a class="heading-anchor" href="#%ed%95%b5%ec%8b%ac-%ed%8c%a8%ed%84%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;패턴&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Database per Service&lt;/td&gt;
					&lt;td&gt;서비스별 독립 DB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;API Gateway&lt;/td&gt;
					&lt;td&gt;단일 진입점, 인증/로깅/라우팅&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Circuit Breaker&lt;/td&gt;
					&lt;td&gt;서비스 장애 시 fallback&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Saga&lt;/td&gt;
					&lt;td&gt;분산 트랜잭션 관리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Event-Driven&lt;/td&gt;
					&lt;td&gt;이벤트 기반 비동기 통신&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;🔗 &lt;a href="https://kyungryeol-yoon.github.io/posts/microservice-pattern-overview/"&gt;상세 Microservice Pattern 글 보기&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-2-컨테이너-이미지-사이즈--ufs-이해"&gt;
 📌 2. 컨테이너 이미지 사이즈 &amp;amp; UFS 이해
 &lt;a class="heading-anchor" href="#-2-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%ec%9d%b4%eb%af%b8%ec%a7%80-%ec%82%ac%ec%9d%b4%ec%a6%88--ufs-%ec%9d%b4%ed%95%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;컨테이너 이미지는 &lt;strong&gt;애플리케이션 + 라이브러리 + OS 레이어&lt;/strong&gt;의 합입니다.&lt;br&gt;
Union File System(UFS)은 이 레이어들을 합쳐 &lt;strong&gt;하나의 파일 시스템처럼 보이도록&lt;/strong&gt; 하는 기술입니다.&lt;/p&gt;
&lt;h3 id="21-컨테이너-이미지-구조"&gt;
 2.1 컨테이너 이미지 구조
 &lt;a class="heading-anchor" href="#21-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%ec%9d%b4%eb%af%b8%ec%a7%80-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[Read-Only Layers]
├─ Base OS
├─ Dependencies
├─ Application Code
[Writable Layer]
└─ Runtime Changes
------------------

Merged View → Container 내부 파일 시스템&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="22-이미지-최적화-실전-팁"&gt;
 2.2 이미지 최적화 실전 팁
 &lt;a class="heading-anchor" href="#22-%ec%9d%b4%eb%af%b8%ec%a7%80-%ec%b5%9c%ec%a0%81%ed%99%94-%ec%8b%a4%ec%a0%84-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;불필요 파일 제거 (&lt;code&gt;.dockerignore&lt;/code&gt;, apt clean)&lt;/li&gt;
&lt;li&gt;멀티스테이지 빌드 활용&lt;/li&gt;
&lt;li&gt;자주 변경되는 파일은 하위 레이어 배치 → 캐시 활용&lt;/li&gt;
&lt;li&gt;경량 베이스 이미지 사용 (Alpine, Distroless)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Multi-stage Build 예제&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;maven:3.9-jdk17&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/app&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; pom.xml .&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; src ./src&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; mvn clean package -DskipTests&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;openjdk:17-jdk-slim&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/app&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; --from&lt;span class="o"&gt;=&lt;/span&gt;build /app/target/myapp.jar .&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;java&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;-jar&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;myapp.jar&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;🔗 &lt;a href="https://kyungryeol-yoon.github.io/posts/container-size-ufs-optimized/"&gt;상세 컨테이너 이미지 최적화 글 보기&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-3-실무-연계-포인트"&gt;
 📌 3. 실무 연계 포인트
 &lt;a class="heading-anchor" href="#-3-%ec%8b%a4%eb%ac%b4-%ec%97%b0%ea%b3%84-%ed%8f%ac%ec%9d%b8%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;마이크로서비스 서비스 단위별로 &lt;strong&gt;독립 이미지 관리&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;컨테이너 이미지 최적화로 &lt;strong&gt;배포 속도와 CI/CD 효율 개선&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;UFS와 레이어 캐시 활용으로 &lt;strong&gt;빌드 시간 단축&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;이벤트 기반 서비스와 컨테이너 배포 전략 연계&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-4-시리즈-요약"&gt;
 📌 4. 시리즈 요약
 &lt;a class="heading-anchor" href="#-4-%ec%8b%9c%eb%a6%ac%ec%a6%88-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;주제&lt;/th&gt;
					&lt;th&gt;핵심 포인트&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Microservice Pattern&lt;/td&gt;
					&lt;td&gt;작은 단위, 독립 배포, 패턴 기반 설계&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Container &amp;amp; UFS&lt;/td&gt;
					&lt;td&gt;이미지 구조 이해, 최적화 전략, 멀티스테이지 빌드&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;연계 실무&lt;/td&gt;
					&lt;td&gt;이미지와 서비스 구조 최적화, 이벤트/배포 전략 통합&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 결론: 마이크로서비스 설계와 컨테이너 이미지 최적화는 서로 보완적입니다.
설계를 이해하고, 최적화 전략을 적용하면 &lt;strong&gt;유연하고 효율적인 서비스 운영&lt;/strong&gt;이 가능합니다.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Ansible] Ansible YAML에서 Multiline 처리 방법</title><link>https://kyungryeol-yoon.github.io/devops/ansible/ansible-yaml-multiline-guide/</link><pubDate>Thu, 23 Dec 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/ansible/ansible-yaml-multiline-guide/</guid><description>&lt;h2 id="multiline-스타일-종류"&gt;
 Multiline 스타일 종류
 &lt;a class="heading-anchor" href="#multiline-%ec%8a%a4%ed%83%80%ec%9d%bc-%ec%a2%85%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;YAML에서 멀티라인을 표현하는 가장 대표적인 두 가지 스타일은 다음과 같습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Literal style (&lt;code&gt;|&lt;/code&gt;)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Folded style (&lt;code&gt;&amp;gt;&lt;/code&gt;)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="literal-style-"&gt;
 Literal style (&lt;code&gt;|&lt;/code&gt;)
 &lt;a class="heading-anchor" href="#literal-style-" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Literal 스타일은 &lt;strong&gt;줄바꿈을 그대로 보존&lt;/strong&gt;합니다.&lt;br&gt;
즉 입력한 그대로 여러 줄이 결과에 포함됩니다.&lt;/p&gt;
&lt;p&gt;예:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;my_pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; This is line one
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; This is line two
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; Line three&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;위와 같이 작성하면 출력 결과는 &lt;strong&gt;정확히 입력한 줄바꿈까지 그대로 반영&lt;/strong&gt;됩니다.&lt;/p&gt;
&lt;p&gt;이는 아래와 같은 상황에서 유용합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Shell script 삽입&lt;/li&gt;
&lt;li&gt;여러 줄 리터럴 텍스트&lt;/li&gt;
&lt;li&gt;정형화된 로그 메시지&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="folded-style-"&gt;
 Folded style (&lt;code&gt;&amp;gt;&lt;/code&gt;)
 &lt;a class="heading-anchor" href="#folded-style-" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Folded 스타일은 &lt;strong&gt;줄바꿈을 접어서 하나의 공간(space)로 변환&lt;/strong&gt;합니다.
다만 연속된 줄바꿈이나 빈 줄은 중복 줄바꿈으로 유지됩니다.&lt;/p&gt;
&lt;p&gt;예:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;my_pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; This is line one
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; This is line two
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; Line three&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;위 문법은 실제 값으로는 아래처럼 해석됩니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;This is line one This is line two Line three&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;즉 줄바꿈이 기본적으로 공백으로 대체됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="block-chomping"&gt;
 Block Chomping
 &lt;a class="heading-anchor" href="#block-chomping" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;YAML은 Multiline에서 &lt;strong&gt;줄바꿈 처리 방식을 제어&lt;/strong&gt;하기 위해 Chomping indicator를 제공합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Indicator&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
					&lt;th&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;`&lt;/td&gt;
					&lt;td&gt;-`&lt;/td&gt;
					&lt;td&gt;마지막 줄바꿈 제거&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;`&lt;/td&gt;
					&lt;td&gt;+`&lt;/td&gt;
					&lt;td&gt;모든 줄바꿈 보존&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;&amp;gt;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;공백으로 줄바꿈 접기&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;예를 들어 &lt;code&gt;|+&lt;/code&gt;를 사용하면 입력한 &lt;strong&gt;줄바꿈이 모두 유지&lt;/strong&gt;됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;my_pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|+&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; First line
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; Second line
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; Third line&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이 경우 출력은 &lt;strong&gt;많은 줄바꿈까지 유지된 형태&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="실무-활용-예"&gt;
 실무 활용 예
 &lt;a class="heading-anchor" href="#%ec%8b%a4%eb%ac%b4-%ed%99%9c%ec%9a%a9-%ec%98%88" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Ansible에서 multiline을 활용하는 대표적인 예는 다음과 같습니다.&lt;/p&gt;
&lt;h3 id="shell-스크립트-삽입"&gt;
 Shell 스크립트 삽입
 &lt;a class="heading-anchor" href="#shell-%ec%8a%a4%ed%81%ac%eb%a6%bd%ed%8a%b8-%ec%82%bd%ec%9e%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Run custom script&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;shell&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Start process&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; mkdir -p /etc/example
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; cp files/app.conf /etc/example/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이처럼 스크립트를 그대로 Playbook에 포함할 수 있습니다.&lt;/p&gt;
&lt;h3 id="큰-텍스트-변수"&gt;
 큰 텍스트 변수
 &lt;a class="heading-anchor" href="#%ed%81%b0-%ed%85%8d%ec%8a%a4%ed%8a%b8-%eb%b3%80%ec%88%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;vars&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;banner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; Welcome to the server!
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; Please follow the instructions below.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;문자열 안에서 줄바꿈을 텍스트 흐름으로 처리하고 싶을 때 &lt;code&gt;&amp;gt;&lt;/code&gt; 스타일이 적합합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="정리"&gt;
 정리
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Ansible Playbook에서 YAML Multiline은 다음과 같이 이해하면 됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;|&lt;/code&gt;: 입력 그대로 줄바꿈 유지 (Literal)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;gt;&lt;/code&gt;: 줄바꿈을 &lt;strong&gt;공백으로 합침&lt;/strong&gt; (Folded)&lt;/li&gt;
&lt;li&gt;추가적인 &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;를 통해 줄바꿈 유지/삭제 옵션 조정 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;YAML 멀티라인을 잘 활용하면 Playbook을 더 읽기 좋고 유지보수하기 쉬운 코드로 작성할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;</description></item><item><title>[Kubernetes] metrics-server</title><link>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-metrics-server/</link><pubDate>Sun, 21 Nov 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-metrics-server/</guid><description>&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Kubernetes의 Metrics-Server는 각 Node에 설치된 kubelet을 통해서 node 및 pod의 CPU, Memory 의 사용량 Metric을 수집&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;node 리소스 사용량 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl top node
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;NAME CPU&lt;span class="o"&gt;(&lt;/span&gt;cores&lt;span class="o"&gt;)&lt;/span&gt; CPU&lt;span class="o"&gt;(&lt;/span&gt;%&lt;span class="o"&gt;)&lt;/span&gt; MEMORY&lt;span class="o"&gt;(&lt;/span&gt;bytes&lt;span class="o"&gt;)&lt;/span&gt; MEMORY&lt;span class="o"&gt;(&lt;/span&gt;%&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;mp-master 180m 2% 1593Mi 20%
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;mp-worker-1 115m 1% 2409Mi 30%
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;mp-worker-2 79m 0% 786Mi 10%&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;pod 리소스 사용량 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;kubectl top po -A
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;NAMESPACE NAME CPU&lt;span class="o"&gt;(&lt;/span&gt;cores&lt;span class="o"&gt;)&lt;/span&gt; MEMORY&lt;span class="o"&gt;(&lt;/span&gt;bytes&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;alloy alloy-5ms5k 4m 49Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;alloy alloy-7q8fc 4m 49Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;alloy alloy-mcswx 4m 49Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;grafana grafana-55cdd669f-rmwmr 12m 80Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;kafka kafbat-ui-kafka-ui-6fd44cc8fc-ksq8w 2m 426Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;kafka my-cluster-dual-role-0 17m 886Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;kafka my-cluster-entity-operator-6f988ccdb-cwwq7 4m 434Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;kafka strimzi-cluster-operator-74f9cd5689-x6sjp 29m 275Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;kube-system calico-kube-controllers-658d97c59c-h5c5t 2m 22Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;kube-system calico-node-85fsz 26m 104Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;kube-system calico-node-sz2q8 22m 104Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;kube-system calico-node-wttp9 24m 104Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;kube-system coredns-76f75df574-hnhwx 2m 18Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;kube-system coredns-76f75df574-pfvts 2m 17Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;kube-system etcd-mp-master 32m 55Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;kube-system kube-apiserver-mp-master 53m 329Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;kube-system kube-controller-manager-mp-master 17m 53Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;kube-system kube-proxy-64pst 1m 22Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;kube-system kube-proxy-bnfnp 1m 22Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;kube-system kube-proxy-h79m7 1m 22Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;kube-system kube-scheduler-mp-master 3m 22Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;kube-system metrics-server-596474b58-bjhf8 4m 23Mi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;mgmt-system gitlab-runner-56c8f85494-4hhz4 11m 78Mi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Install metrics-server 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes-sigs/metrics-server"&gt;https://github.com/kubernetes-sigs/metrics-server&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="metrics-server-설치"&gt;
 Metrics-Server 설치
 &lt;a class="heading-anchor" href="#metrics-server-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="metrics-server-설치-중-오류"&gt;
 Metrics-server 설치 중 오류
 &lt;a class="heading-anchor" href="#metrics-server-%ec%84%a4%ec%b9%98-%ec%a4%91-%ec%98%a4%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="readiness-probe-failed-http-probe-failed-with-statuscode-500"&gt;
 Readiness probe failed: HTTP probe failed with statuscode: 500
 &lt;a class="heading-anchor" href="#readiness-probe-failed-http-probe-failed-with-statuscode-500" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;아래와 같이 상태가 0/1이고, &lt;code&gt;Readiness probe failed: HTTP probe failed with statuscode: 500&lt;/code&gt;라는 Event가 발견&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;Events:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; Type Reason Age From Message
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; ---- ------ ---- ---- -------
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; Normal Scheduled 16m default-scheduler Successfully assigned kube-system/metrics-server-75bf97fcc9-xhrnz to mp-worker-2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; Normal Pulling 16m kubelet Pulling image &lt;span class="s2"&gt;&amp;#34;registry.k8s.io/metrics-server/metrics-server:v0.7.2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; Normal Pulled 16m kubelet Successfully pulled image &lt;span class="s2"&gt;&amp;#34;registry.k8s.io/metrics-server/metrics-server:v0.7.2&amp;#34;&lt;/span&gt; in 14.31s &lt;span class="o"&gt;(&lt;/span&gt;14.31s including waiting&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; Normal Created 16m kubelet Created container: metrics-server
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; Normal Started 16m kubelet Started container metrics-server
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; Warning Unhealthy 11m &lt;span class="o"&gt;(&lt;/span&gt;x31 over 15m&lt;span class="o"&gt;)&lt;/span&gt; kubelet Readiness probe failed: HTTP probe failed with statuscode: &lt;span class="m"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; Normal SandboxChanged 6m3s &lt;span class="o"&gt;(&lt;/span&gt;x2 over 6m34s&lt;span class="o"&gt;)&lt;/span&gt; kubelet Pod sandbox changed, it will be killed and re-created.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; Normal Pulled 6m1s kubelet Container image &lt;span class="s2"&gt;&amp;#34;registry.k8s.io/metrics-server/metrics-server:v0.7.2&amp;#34;&lt;/span&gt; already present on machine
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; Normal Created 6m kubelet Created container: metrics-server
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; Normal Started 6m kubelet Started container metrics-server
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; Warning Unhealthy 89s &lt;span class="o"&gt;(&lt;/span&gt;x29 over 5m39s&lt;span class="o"&gt;)&lt;/span&gt; kubelet Readiness probe failed: HTTP probe failed with statuscode: &lt;span class="m"&gt;500&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;설치된 metrics-server에서 아래와 같이 &lt;code&gt;--kubelet-insecure-tls&lt;/code&gt;라는 Command를 추가&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl edit deploy -n kube-system metrics-server &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;cert-dir=/tmp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;secure-port=443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;kubelet-use-node-status-port&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;metric-resolution=15s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- --&lt;span class="l"&gt;kubelet-insecure-tls &amp;lt;&amp;lt; 추가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="error-from-server-serviceunavailable-the-server-is-currently-unable-to-handle-the-request-get-nodesmetricsk8sio"&gt;
 Error from server (ServiceUnavailable): the server is currently unable to handle the request (get nodes.metrics.k8s.io)
 &lt;a class="heading-anchor" href="#error-from-server-serviceunavailable-the-server-is-currently-unable-to-handle-the-request-get-nodesmetricsk8sio" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;kubecetl top 명령어 오류&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl top node
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;Error from server &lt;span class="o"&gt;(&lt;/span&gt;ServiceUnavailable&lt;span class="o"&gt;)&lt;/span&gt;: the server is currently unable to handle the request &lt;span class="o"&gt;(&lt;/span&gt;get nodes.metrics.k8s.io&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;metrics-server를 수정해서 &lt;code&gt;spec.template.spec&lt;/code&gt; 라인에 &lt;code&gt;hostNetwork: true&lt;/code&gt; 를 추가&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl edit deploy -n kube-system metrics-server &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;dnsPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterFirst&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;hostNetwork&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;&amp;lt;&amp;lt; 추가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;nodeSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kubernetes.io/os&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;linux&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="high-availability"&gt;
 High Availability
 &lt;a class="heading-anchor" href="#high-availability" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;On Kubernetes v1.21+&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/high-availability-1.21+.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On Kubernetes v1.19-1.21&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/high-availability.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Microservice Pattern 실전] 주문-결제-배송 시스템 설계와 Docker/K8s 적용</title><link>https://kyungryeol-yoon.github.io/backend/architecture/microservice-pattern/</link><pubDate>Thu, 11 Nov 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/architecture/microservice-pattern/</guid><description>&lt;h1 id="-microservice-pattern-실전-예제-주문-결제-배송-시스템"&gt;
 🚀 Microservice Pattern 실전 예제: 주문-결제-배송 시스템
 &lt;a class="heading-anchor" href="#-microservice-pattern-%ec%8b%a4%ec%a0%84-%ec%98%88%ec%a0%9c-%ec%a3%bc%eb%ac%b8-%ea%b2%b0%ec%a0%9c-%eb%b0%b0%ec%86%a1-%ec%8b%9c%ec%8a%a4%ed%85%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;마이크로서비스 아키텍처는 하나의 큰 애플리케이션을 &lt;strong&gt;작고 독립적인 서비스 단위&lt;/strong&gt;로 나누어 운영하는 방법론입니다.&lt;br&gt;
이번 글에서는 실전 예제와 함께 &lt;strong&gt;Docker/Kubernetes 환경 + 이벤트 기반 Saga&lt;/strong&gt;를 적용해보겠습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="1-핵심-패턴-요약"&gt;
 1️⃣ 핵심 패턴 요약
 &lt;a class="heading-anchor" href="#1-%ed%95%b5%ec%8b%ac-%ed%8c%a8%ed%84%b4-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;패턴&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
					&lt;th&gt;실전 예제 적용&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Database per Service&lt;/td&gt;
					&lt;td&gt;각 서비스가 자체 DB 보유&lt;/td&gt;
					&lt;td&gt;Order DB, Payment DB, Shipping DB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;API Gateway&lt;/td&gt;
					&lt;td&gt;단일 진입점, 인증/로깅/라우팅&lt;/td&gt;
					&lt;td&gt;Client → API Gateway → 각 서비스&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Circuit Breaker&lt;/td&gt;
					&lt;td&gt;서비스 장애 시 fallback&lt;/td&gt;
					&lt;td&gt;Payment Service 실패 시 주문 롤백&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Saga&lt;/td&gt;
					&lt;td&gt;분산 트랜잭션 관리&lt;/td&gt;
					&lt;td&gt;주문 → 결제 → 배송 순서 처리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Event-Driven&lt;/td&gt;
					&lt;td&gt;이벤트 기반 비동기 통신&lt;/td&gt;
					&lt;td&gt;OrderCreatedEvent → Payment → Shipping&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="2-서비스-구조-예시"&gt;
 2️⃣ 서비스 구조 예시
 &lt;a class="heading-anchor" href="#2-%ec%84%9c%eb%b9%84%ec%8a%a4-%ea%b5%ac%ec%a1%b0-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;microservice-app/
├── order-service/
│ ├── src/
│ └── database/
├── payment-service/
│ ├── src/
│ └── database/
├── shipping-service/
│ ├── src/
│ └── database/
└── api-gateway/
└── src/&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;각 서비스는 독립 배포 가능하며, API Gateway로 외부 요청 처리&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h1 id="3-도메인-모델링"&gt;
 3️⃣ 도메인 모델링
 &lt;a class="heading-anchor" href="#3-%eb%8f%84%eb%a9%94%ec%9d%b8-%eb%aa%a8%eb%8d%b8%eb%a7%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="31-order-엔티티"&gt;
 3.1 Order 엔티티
 &lt;a class="heading-anchor" href="#31-order-%ec%97%94%ed%8b%b0%ed%8b%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;customerId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OrderItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;PENDING&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OrderItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;confirm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;CONFIRMED&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="32-payment-도메인-서비스"&gt;
 3.2 Payment 도메인 서비스
 &lt;a class="heading-anchor" href="#32-payment-%eb%8f%84%eb%a9%94%ec%9d%b8-%ec%84%9c%eb%b9%84%ec%8a%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentService&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getStatus&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;CONFIRMED&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IllegalStateException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;결제 전 주문만 처리 가능&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 실제 결제 로직&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="33-이벤트-발행"&gt;
 3.3 이벤트 발행
 &lt;a class="heading-anchor" href="#33-%ec%9d%b4%eb%b2%a4%ed%8a%b8-%eb%b0%9c%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderCreatedEvent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;OrderCreatedEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orderId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;OrderService → 이벤트 발행 → PaymentService → 처리 → ShippingService로 이벤트 전파&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="4-이벤트-기반-saga-예제"&gt;
 4️⃣ 이벤트 기반 Saga 예제
 &lt;a class="heading-anchor" href="#4-%ec%9d%b4%eb%b2%a4%ed%8a%b8-%ea%b8%b0%eb%b0%98-saga-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 주문 생성 → 결제 → 배송&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;OrderService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OrderCreatedEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;PaymentService&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subscribes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OrderCreatedEvent&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;결제&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;성공&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;시&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PaymentCompletedEvent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;발행&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;실패&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;시&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OrderCancelledEvent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;발행&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ShippingService&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subscribes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PaymentCompletedEvent&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;배송&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;처리&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Saga를 통해 &lt;strong&gt;분산 트랜잭션&lt;/strong&gt;을 안전하게 처리&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h1 id="5-docker--kubernetes-예제"&gt;
 5️⃣ Docker &amp;amp; Kubernetes 예제
 &lt;a class="heading-anchor" href="#5-docker--kubernetes-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="51-dockerfile-order-service-예시"&gt;
 5.1 Dockerfile (Order Service 예시)
 &lt;a class="heading-anchor" href="#51-dockerfile-order-service-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;openjdk:17-jdk-slim&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/app&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; target/order-service.jar .&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;java&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;-jar&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;order-service.jar&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="52-docker-compose-예시"&gt;
 5.2 docker-compose 예시
 &lt;a class="heading-anchor" href="#52-docker-compose-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;order-service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./order-service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;8081:8081&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;micro-net&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;payment-service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./payment-service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;8082:8082&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;micro-net&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;shipping-service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./shipping-service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;8083:8083&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;micro-net&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;micro-net:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="53-kubernetes-deployment-order-service"&gt;
 5.3 Kubernetes Deployment (Order Service)
 &lt;a class="heading-anchor" href="#53-kubernetes-deployment-order-service" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order-service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order-service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order-service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order-service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order-service:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8081&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="6-실무-팁"&gt;
 6️⃣ 실무 팁
 &lt;a class="heading-anchor" href="#6-%ec%8b%a4%eb%ac%b4-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;📝 &lt;strong&gt;서비스 독립성&lt;/strong&gt;: 각 서비스 DB와 로직 독립&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;API Gateway 활용&lt;/strong&gt;: 인증/라우팅/로깅 집중 관리&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;이벤트 기반 설계&lt;/strong&gt;: Saga, Event-Driven으로 느슨한 결합&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;Circuit Breaker&lt;/strong&gt;: 장애 시 fallback 처리 필수&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;모니터링 &amp;amp; 로깅&lt;/strong&gt;: Prometheus, ELK 등 활용&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="7-정리"&gt;
 7️⃣ 정리
 &lt;a class="heading-anchor" href="#7-%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;마이크로서비스 패턴&lt;/strong&gt;은 단순히 나누는 구조가 아니라, &lt;strong&gt;패턴 기반 설계 + 인프라 적용&lt;/strong&gt;까지 포함&lt;/li&gt;
&lt;li&gt;핵심 패턴: Database per Service, API Gateway, Circuit Breaker, Saga, Event-Driven&lt;/li&gt;
&lt;li&gt;실무 적용: 작은 서비스부터 시작 → 이벤트 기반 통신 → Docker/K8s 배포 → 모니터링&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 결론: 마이크로서비스는 단순한 구조 분리보다
&lt;strong&gt;설계 패턴과 운영 전략을 포함한 전반적 아키텍처 접근&lt;/strong&gt;이 핵심입니다.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Microservice Pattern] 마이크로서비스 패턴 개요와 핵심 설계</title><link>https://kyungryeol-yoon.github.io/backend/architecture/microservice-pattern-overview/</link><pubDate>Sun, 07 Nov 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/architecture/microservice-pattern-overview/</guid><description>&lt;h1 id="-microservice-pattern-마이크로서비스-패턴-개요"&gt;
 🏗️ Microservice Pattern (마이크로서비스 패턴) 개요
 &lt;a class="heading-anchor" href="#-microservice-pattern-%eb%a7%88%ec%9d%b4%ed%81%ac%eb%a1%9c%ec%84%9c%eb%b9%84%ec%8a%a4-%ed%8c%a8%ed%84%b4-%ea%b0%9c%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;**마이크로서비스 아키텍처(Microservice Architecture)**는 하나의 큰 애플리케이션을&lt;br&gt;
&lt;strong&gt;작고 독립적인 서비스 단위&lt;/strong&gt;로 분리하여 운영하는 아키텍처 스타일입니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;🔑 핵심: &lt;strong&gt;작은 서비스 단위 + 독립 배포 + 명확한 책임&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h1 id="1-마이크로서비스-특징"&gt;
 1️⃣ 마이크로서비스 특징
 &lt;a class="heading-anchor" href="#1-%eb%a7%88%ec%9d%b4%ed%81%ac%eb%a1%9c%ec%84%9c%eb%b9%84%ec%8a%a4-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;특징&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;작은 단위&lt;/td&gt;
					&lt;td&gt;각 서비스는 단일 책임(Single Responsibility) 중심&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;독립 배포&lt;/td&gt;
					&lt;td&gt;서비스별로 독립적으로 빌드/배포 가능&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;독립 데이터&lt;/td&gt;
					&lt;td&gt;각 서비스는 자체 데이터 저장소를 가짐&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;통신 방식&lt;/td&gt;
					&lt;td&gt;REST API, gRPC, 메시지 큐 등 사용&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;팀 단위 개발&lt;/td&gt;
					&lt;td&gt;서비스 단위로 팀이 독립적으로 개발 가능&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 모놀리식 아키텍처와 비교하면, 마이크로서비스는 &lt;strong&gt;유연성과 확장성&lt;/strong&gt;을 강조합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h1 id="2-주요-마이크로서비스-패턴"&gt;
 2️⃣ 주요 마이크로서비스 패턴
 &lt;a class="heading-anchor" href="#2-%ec%a3%bc%ec%9a%94-%eb%a7%88%ec%9d%b4%ed%81%ac%eb%a1%9c%ec%84%9c%eb%b9%84%ec%8a%a4-%ed%8c%a8%ed%84%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;마이크로서비스 설계에서 자주 활용되는 &lt;strong&gt;패턴&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;h2 id="21-database-per-service"&gt;
 2.1 Database per Service
 &lt;a class="heading-anchor" href="#21-database-per-service" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;각 서비스가 &lt;strong&gt;자체 데이터베이스&lt;/strong&gt;를 보유&lt;/li&gt;
&lt;li&gt;장점: 서비스 간 결합도 최소화&lt;/li&gt;
&lt;li&gt;단점: 데이터 일관성 관리 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Order Service DB &amp;lt;-- 독립
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;Payment Service DB &amp;lt;-- 독립&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="22-api-gateway-pattern"&gt;
 2.2 API Gateway Pattern
 &lt;a class="heading-anchor" href="#22-api-gateway-pattern" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;클라이언트 요청을 &lt;strong&gt;단일 진입점&lt;/strong&gt;에서 처리&lt;/li&gt;
&lt;li&gt;인증, 로깅, 라우팅, 응답 집계 등 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Client → API Gateway → Order Service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; → Payment Service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; → Shipping Service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="23-circuit-breaker-pattern"&gt;
 2.3 Circuit Breaker Pattern
 &lt;a class="heading-anchor" href="#23-circuit-breaker-pattern" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;서비스 호출 실패 시 &lt;strong&gt;전체 시스템 장애 방지&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;실패하면 fallback 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;paymentService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ServiceUnavailableException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fallbackPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="24-saga-pattern"&gt;
 2.4 Saga Pattern
 &lt;a class="heading-anchor" href="#24-saga-pattern" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;분산 트랜잭션 관리&lt;/strong&gt;를 위한 패턴&lt;/li&gt;
&lt;li&gt;예: 주문 → 결제 → 배송 순서 중 일부 실패 시 이전 단계 롤백&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Order Service → Payment Service → Shipping Service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; 실패 → Payment Service 취소 → Order Service 취소&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="25-event-driven-pattern"&gt;
 2.5 Event-Driven Pattern
 &lt;a class="heading-anchor" href="#25-event-driven-pattern" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;서비스 간 이벤트 기반 &lt;strong&gt;비동기 통신&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;장점: 느슨한 결합, 확장성 우수&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;OrderCreatedEvent → Payment Service → PaymentProcessedEvent → Shipping Service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="3-마이크로서비스-구조-예시"&gt;
 3️⃣ 마이크로서비스 구조 예시
 &lt;a class="heading-anchor" href="#3-%eb%a7%88%ec%9d%b4%ed%81%ac%eb%a1%9c%ec%84%9c%eb%b9%84%ec%8a%a4-%ea%b5%ac%ec%a1%b0-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;microservice-app/
 ├── order-service/
 │ ├── src/
 │ └── database/
 ├── payment-service/
 │ ├── src/
 │ └── database/
 ├── shipping-service/
 │ ├── src/
 │ └── database/
 └── api-gateway/
 └── src/&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;각 서비스는 독립적으로 배포 가능하며, API Gateway로 외부 요청을 처리합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h1 id="4-실무-고려사항"&gt;
 4️⃣ 실무 고려사항
 &lt;a class="heading-anchor" href="#4-%ec%8b%a4%eb%ac%b4-%ea%b3%a0%eb%a0%a4%ec%82%ac%ed%95%ad" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;📝 &lt;strong&gt;통합 로깅 &amp;amp; 모니터링&lt;/strong&gt;: 모든 서비스 로그를 통합 관리&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;데이터 일관성 관리&lt;/strong&gt;: Saga 또는 이벤트 기반 설계&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;테스트 전략&lt;/strong&gt;: 단위 테스트 + 통합 테스트&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;배포/인프라 자동화&lt;/strong&gt;: CI/CD, Docker, Kubernetes 활용&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="5-요약"&gt;
 5️⃣ 요약
 &lt;a class="heading-anchor" href="#5-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;마이크로서비스 패턴&lt;/strong&gt; = 작은 단위 서비스 + 독립 배포 + 명확한 책임&lt;/li&gt;
&lt;li&gt;핵심 패턴: Database per Service, API Gateway, Circuit Breaker, Saga, Event-Driven&lt;/li&gt;
&lt;li&gt;장점: 확장성, 팀 단위 독립 개발, 유연성&lt;/li&gt;
&lt;li&gt;단점: 분산 관리 복잡성, 데이터 일관성 문제, 운영 부담&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 결론: 마이크로서비스는 단순히 애플리케이션을 나누는 것이 아니라,
&lt;strong&gt;설계 패턴과 운영 전략을 포함한 전체 아키텍처 접근&lt;/strong&gt;이 핵심입니다.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] About Argo CD</title><link>https://kyungryeol-yoon.github.io/devops/argo-cd/kubernetes-argo-cd/</link><pubDate>Sun, 17 Oct 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/argo-cd/kubernetes-argo-cd/</guid><description>&lt;ul&gt;
&lt;li&gt;Argo CD는 GitOps 스타일의 배포를 지원하는 CD 도구&lt;/li&gt;
&lt;li&gt;Git 저장소의 내용과 Kubernetes 클러스터를 동기화해주는 역할을 하는 에이전트&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="작동-원리"&gt;
 작동 원리
 &lt;a class="heading-anchor" href="#%ec%9e%91%eb%8f%99-%ec%9b%90%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Argo CD는 원하는 애플리케이션 상태를 정의하기위한 소스로 Git repository를 사용하는 GitOps 패턴을 따른다.&lt;/li&gt;
&lt;li&gt;Kubernetes 매니페스트는 여러 방법으로 지정할 수 있다.&lt;/li&gt;
&lt;li&gt;Argo CD는 지정된 대상 환경에서 원하는 애플리케이션 상태의 배포를 자동화한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/argo-cd/argo-cd-architecture.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="설치"&gt;
 설치
 &lt;a class="heading-anchor" href="#%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create namespace argocd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="gitops"&gt;
 GitOps
 &lt;a class="heading-anchor" href="#gitops" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;핵심은 git repository에 저장된 Kubernetes manifest 같은 파일을 이용하여 배포를 선언적으로 하는 것이다.&lt;/li&gt;
&lt;li&gt;git 저장소에 있는 것을 Kubernetes 클러스터에 동기화한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="gitops의-원칙"&gt;
 GitOps의 원칙
 &lt;a class="heading-anchor" href="#gitops%ec%9d%98-%ec%9b%90%ec%b9%99" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;모든 시스템은 선언적으로 선언되어야 함\
&lt;code&gt;선언적(declarative)&lt;/code&gt;이라 함은 명령들의 집합이 아니라 사실(fact)들의 집합으로 구성이 되었음을 보장한다는 의미
쿠버네티스의 manifest들은 모두 선언적으로 작성되었고 이를 Git으로 관리한다면 versioning과 같은 Git의 장점과 더불어, SSOT(single source of truth)를 소유하게 됨&lt;/li&gt;
&lt;li&gt;시스템의 상태는 Git의 버전을 따라감\
Git에 저장된 쿠버네티스 manifest를 기준으로 시스템에 배포되기 때문에 이전 버전의 시스템을 배포하고싶으면 git revert와 같은 명령어를 사용하면 됨&lt;/li&gt;
&lt;li&gt;승인된 변화는 자동으로 시스템에 적용됨\
한 번 선언된 manifest가 Git에 등록되고 관리되기 시작하면 변화(코드수정 등)가 발생할때마다 자동으로 시스템에 적용되어야 하며, 클러스터에 배포할때마다 자격증명은 필요하지 않아야 함&lt;/li&gt;
&lt;li&gt;배포에 실패하면 이를 사용자에게 경고해야 함\
시스템 상태가 선언되고 버전 제어 하에 유지되었을 때 배포가 실패하게되면 사용자에게 경고할 수 있는 시스템을 마련해야 함&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="기존의-배포-방식"&gt;
 기존의 배포 방식
 &lt;a class="heading-anchor" href="#%ea%b8%b0%ec%a1%b4%ec%9d%98-%eb%b0%b0%ed%8f%ac-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;개발자가 소스코드를 작성&lt;/li&gt;
&lt;li&gt;git 저장소에 push&lt;/li&gt;
&lt;li&gt;Jenkins, CircleCI, Github Action과 같은 CI를 통해 테스트와 빌드 작업&lt;/li&gt;
&lt;li&gt;생성한 Container Image를 저장소(ex: Harbor)에 업로드&lt;/li&gt;
&lt;li&gt;업로드 된 Container Image의 정보를 참조해서 서버에 배포&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/argo-cd/argo-cd-001.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="gitops의-배포방식"&gt;
 GitOps의 배포방식
 &lt;a class="heading-anchor" href="#gitops%ec%9d%98-%eb%b0%b0%ed%8f%ac%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;개발자가 소스코드를 작성&lt;/li&gt;
&lt;li&gt;git 저장소에 push&lt;/li&gt;
&lt;li&gt;Jenkins, CircleCI, Github Action 같은 CI에 의해서 테스트와 빌드 작업이 실행, 생성한 Container Image를 저장소(ex: Harbor)에 업로드&lt;/li&gt;
&lt;li&gt;GitOps방식으로 관리되는 Manifest 파일의 변경사항을 감시하며, 현재 배포된 환경의 상태와 Git에 정의된 Manifest 상태를 동일하게 유지하는 역할을 수행&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/argo-cd/argo-cd-002.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>[Docker] 컨테이너 이미지 최적화와 UFS 심화 이해</title><link>https://kyungryeol-yoon.github.io/docker/container-size-ufs-optimized/</link><pubDate>Tue, 05 Oct 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/docker/container-size-ufs-optimized/</guid><description>&lt;h2 id="-컨테이너-이미지-최적화와-ufsunion-file-system-심화"&gt;
 🐳 컨테이너 이미지 최적화와 UFS(Union File System) 심화
 &lt;a class="heading-anchor" href="#-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%ec%9d%b4%eb%af%b8%ec%a7%80-%ec%b5%9c%ec%a0%81%ed%99%94%ec%99%80-ufsunion-file-system-%ec%8b%ac%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Docker 컨테이너를 다루다 보면 &lt;strong&gt;이미지 사이즈&lt;/strong&gt;와 **Union File System(UFS)**를 이해하는 것이 필수입니다.&lt;br&gt;
이번 글에서는 &lt;strong&gt;이미지 구조 분석, UFS 동작 원리, 최적화 실전 예제&lt;/strong&gt;까지 다룹니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-컨테이너-이미지-사이즈container-size-이해"&gt;
 1️⃣ 컨테이너 이미지 사이즈(Container Size) 이해
 &lt;a class="heading-anchor" href="#1-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%ec%9d%b4%eb%af%b8%ec%a7%80-%ec%82%ac%ec%9d%b4%ec%a6%88container-size-%ec%9d%b4%ed%95%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;컨테이너 이미지는 &lt;strong&gt;애플리케이션 코드 + 런타임 + 라이브러리 + OS 레이어&lt;/strong&gt;가 합쳐진 패키지입니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Container Image = Base OS Layer + App Dependencies + Application Code&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;이미지가 크면: 다운로드/배포 시간이 길어지고 디스크 사용량 증가&lt;/li&gt;
&lt;li&gt;이미지가 작으면: 배포 속도 빠르고 CI/CD 효율 상승&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;🔹 Tip: Alpine, Distroless 같은 &lt;strong&gt;경량 베이스 이미지&lt;/strong&gt; 활용&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="2-ufsunion-file-system-이해"&gt;
 2️⃣ UFS(Union File System) 이해
 &lt;a class="heading-anchor" href="#2-ufsunion-file-system-%ec%9d%b4%ed%95%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Union File System&lt;/strong&gt;은 컨테이너 이미지의 &lt;strong&gt;레이어 구조&lt;/strong&gt;를 합쳐서 관리하는 파일 시스템입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;여러 파일 시스템 레이어를 &lt;strong&gt;합쳐 하나의 파일 시스템처럼 표시&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;읽기 전용(Read-Only) 레이어 + 쓰기 가능한(Writeable) 레이어 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[Read-Only Layers]
├─ Base OS
├─ Dependencies
├─ Application Code
[Writable Layer]
└─ Container Runtime Changes
----------------------------

Merged View → 컨테이너에서 하나의 파일 시스템처럼 보임&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h3 id="21-ufs-동작-원리"&gt;
 2.1 UFS 동작 원리
 &lt;a class="heading-anchor" href="#21-ufs-%eb%8f%99%ec%9e%91-%ec%9b%90%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Read-Only 레이어&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이미지 빌드 시 생성&lt;/li&gt;
&lt;li&gt;재사용 가능 → 레이어 캐싱 효과&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Writable 레이어&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너 실행 시 생성&lt;/li&gt;
&lt;li&gt;컨테이너 내부 변경 사항 반영&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;파일 읽기/쓰기 흐름&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파일 읽기 → 가장 위 레이어부터 검색&lt;/li&gt;
&lt;li&gt;파일 쓰기 → Writable 레이어에 기록&lt;/li&gt;
&lt;li&gt;파일 삭제 → “whiteout” 파일 생성 → 하위 레이어 숨김 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="3-이미지-최적화-실전-예제"&gt;
 3️⃣ 이미지 최적화 실전 예제
 &lt;a class="heading-anchor" href="#3-%ec%9d%b4%eb%af%b8%ec%a7%80-%ec%b5%9c%ec%a0%81%ed%99%94-%ec%8b%a4%ec%a0%84-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="31-불필요-파일-제거"&gt;
 3.1 불필요 파일 제거
 &lt;a class="heading-anchor" href="#31-%eb%b6%88%ed%95%84%ec%9a%94-%ed%8c%8c%ec%9d%bc-%ec%a0%9c%ea%b1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 불필요 캐시 제거&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get install -y curl &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; rm -rf /var/lib/apt/lists/*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="32-멀티스테이지-빌드multi-stage-build"&gt;
 3.2 멀티스테이지 빌드(Multi-stage Build)
 &lt;a class="heading-anchor" href="#32-%eb%a9%80%ed%8b%b0%ec%8a%a4%ed%85%8c%ec%9d%b4%ec%a7%80-%eb%b9%8c%eb%93%9cmulti-stage-build" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Build stage&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;maven:3.9-jdk17&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/app&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; pom.xml .&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; src ./src&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; mvn clean package -DskipTests&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Production stage&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;openjdk:17-jdk-slim&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/app&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; --from&lt;span class="o"&gt;=&lt;/span&gt;build /app/target/myapp.jar .&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;java&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;-jar&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;myapp.jar&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;✅ 결과: 최종 이미지에는 &lt;strong&gt;빌드 도구와 캐시가 제거&lt;/strong&gt;되어 사이즈 최소화&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="4-이미지-레이어-확인"&gt;
 4️⃣ 이미지 레이어 확인
 &lt;a class="heading-anchor" href="#4-%ec%9d%b4%eb%af%b8%ec%a7%80-%eb%a0%88%ec%9d%b4%ec%96%b4-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 로컬 이미지 사이즈 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;docker images
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 레이어별 사이즈 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;docker &lt;span class="nb"&gt;history&lt;/span&gt; &amp;lt;image-name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;레이어 구조를 분석하면 &lt;strong&gt;어디서 이미지가 커지는지&lt;/strong&gt; 쉽게 파악 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="5-실무-팁"&gt;
 5️⃣ 실무 팁
 &lt;a class="heading-anchor" href="#5-%ec%8b%a4%eb%ac%b4-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;📝 &lt;code&gt;.dockerignore&lt;/code&gt; 활용 → 불필요 파일 제외&lt;/li&gt;
&lt;li&gt;📝 자주 변경되는 파일은 하위 레이어에 두어 &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;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="6-요약"&gt;
 6️⃣ 요약
 &lt;a class="heading-anchor" href="#6-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;컨테이너 이미지 사이즈&lt;/strong&gt; = OS + 라이브러리 + 애플리케이션 코드&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;UFS(Union File System)&lt;/strong&gt; = 레이어를 합쳐 &lt;strong&gt;읽기 전용 + 쓰기 레이어&lt;/strong&gt; 구조 제공&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이미지 최적화 포인트:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;불필요 파일 제거&lt;/li&gt;
&lt;li&gt;멀티스테이지 빌드&lt;/li&gt;
&lt;li&gt;레이어 캐시 전략&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 결론: 컨테이너 효율과 배포 속도를 높이려면
&lt;strong&gt;이미지 구조와 UFS 동작 원리, 멀티스테이지 최적화 전략&lt;/strong&gt;을 이해하는 것이 필수입니다.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Docker/Container] 컨테이너 사이즈와 UFS(Union File System) 이해</title><link>https://kyungryeol-yoon.github.io/docker/container-size-ufs/</link><pubDate>Sat, 02 Oct 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/docker/container-size-ufs/</guid><description>&lt;h2 id="-컨테이너-이미지-사이즈container-size와-ufs-이해"&gt;
 🐳 컨테이너 이미지 사이즈(Container Size)와 UFS 이해
 &lt;a class="heading-anchor" href="#-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%ec%9d%b4%eb%af%b8%ec%a7%80-%ec%82%ac%ec%9d%b4%ec%a6%88container-size%ec%99%80-ufs-%ec%9d%b4%ed%95%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Docker나 OCI 기반 컨테이너를 다루다 보면,&lt;br&gt;
컨테이너 &lt;strong&gt;이미지 크기&lt;/strong&gt;와 &lt;strong&gt;Union File System(UFS)&lt;/strong&gt; 개념이 중요하게 등장합니다.&lt;/p&gt;
&lt;p&gt;이 글에서는:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너 사이즈 개념&lt;/li&gt;
&lt;li&gt;UFS(Union File System)의 동작 원리&lt;/li&gt;
&lt;li&gt;실무에서 이미지 최적화 팁&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;등을 다룹니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-컨테이너-이미지-사이즈란"&gt;
 1️⃣ 컨테이너 이미지 사이즈란?
 &lt;a class="heading-anchor" href="#1-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%ec%9d%b4%eb%af%b8%ec%a7%80-%ec%82%ac%ec%9d%b4%ec%a6%88%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;컨테이너 이미지는 &lt;strong&gt;애플리케이션 코드 + 런타임 + 라이브러리 + OS 레이어&lt;/strong&gt;가 합쳐진 패키지입니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Container Image = Base OS Layer + App Dependencies + Application Code&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;이미지가 클수록:
&lt;ul&gt;
&lt;li&gt;다운로드/배포 시간이 길어짐&lt;/li&gt;
&lt;li&gt;디스크 공간 사용 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이미지가 작을수록:
&lt;ul&gt;
&lt;li&gt;배포 속도 빠름&lt;/li&gt;
&lt;li&gt;CI/CD 효율 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;🔹 Tip: Alpine, Distroless 같은 &lt;strong&gt;경량 베이스 이미지&lt;/strong&gt; 활용&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="2-ufsunion-file-system란"&gt;
 2️⃣ UFS(Union File System)란?
 &lt;a class="heading-anchor" href="#2-ufsunion-file-system%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Union File System&lt;/strong&gt;은 컨테이너 이미지의 &lt;strong&gt;계층(Layer) 구조&lt;/strong&gt;를 관리하는 파일 시스템입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;여러 파일 시스템 레이어를 &lt;strong&gt;합쳐서 하나처럼 보여줌&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;읽기 전용(Read-Only) 레이어 + 쓰기 가능한(Writeable) 레이어 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[Read-Only Layers]
├─ Base OS
├─ Dependencies
├─ Application Code
[Writable Layer]
└─ Container Runtime Changes
----------------------------

Merged View → Container에서 하나의 파일 시스템처럼 보임&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h3 id="21-ufs의-동작-원리"&gt;
 2.1 UFS의 동작 원리
 &lt;a class="heading-anchor" href="#21-ufs%ec%9d%98-%eb%8f%99%ec%9e%91-%ec%9b%90%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Read-Only 레이어&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이미지 생성 시마다 쌓이는 레이어&lt;/li&gt;
&lt;li&gt;재사용 가능 → 레이어 캐싱&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Writable 레이어&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너가 실행될 때 생성&lt;/li&gt;
&lt;li&gt;컨테이너 내부 변경 사항 반영&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;파일 읽기/쓰기 흐름&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파일 읽기 → 가장 위 레이어부터 검색&lt;/li&gt;
&lt;li&gt;파일 쓰기 → Writable 레이어에 기록&lt;/li&gt;
&lt;li&gt;파일 삭제 → “whiteout” 파일 생성 → 하위 레이어 숨김 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="3-레이어와-이미지-최적화"&gt;
 3️⃣ 레이어와 이미지 최적화
 &lt;a class="heading-anchor" href="#3-%eb%a0%88%ec%9d%b4%ec%96%b4%ec%99%80-%ec%9d%b4%eb%af%b8%ec%a7%80-%ec%b5%9c%ec%a0%81%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;UFS 덕분에 &lt;strong&gt;레이어 단위 캐싱&lt;/strong&gt;과 &lt;strong&gt;이미지 재사용&lt;/strong&gt;이 가능하지만,&lt;br&gt;
레이어 구조에 따라 이미지 사이즈가 커질 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;레이어 합병이 많으면 관리 복잡도 증가&lt;/li&gt;
&lt;li&gt;불필요한 파일 추가 시 이미지 사이즈 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="-실무-팁"&gt;
 🔹 실무 팁
 &lt;a class="heading-anchor" href="#-%ec%8b%a4%eb%ac%b4-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;apt-get clean&lt;/code&gt;, &lt;code&gt;.dockerignore&lt;/code&gt; 활용 → 불필요 파일 제외&lt;/li&gt;
&lt;li&gt;자주 변경되는 파일은 &lt;strong&gt;하위 레이어&lt;/strong&gt;에 두어 캐시 활용&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;멀티스테이지 빌드(Multi-stage build)&lt;/strong&gt; 활용 → 최종 이미지 최소화&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="4-컨테이너-이미지-사이즈-확인"&gt;
 4️⃣ 컨테이너 이미지 사이즈 확인
 &lt;a class="heading-anchor" href="#4-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%ec%9d%b4%eb%af%b8%ec%a7%80-%ec%82%ac%ec%9d%b4%ec%a6%88-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 로컬 이미지 사이즈 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;docker images
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 컨테이너 실행 후 레이어별 사이즈 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;docker &lt;span class="nb"&gt;history&lt;/span&gt; &amp;lt;image-name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="5-요약"&gt;
 5️⃣ 요약
 &lt;a class="heading-anchor" href="#5-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;컨테이너 이미지 사이즈&lt;/strong&gt; = OS + 라이브러리 + 애플리케이션 코드&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;UFS(Union File System)&lt;/strong&gt; = 레이어를 합쳐 &lt;strong&gt;읽기 전용 + 쓰기 레이어&lt;/strong&gt; 구조 제공&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이미지 최적화 포인트:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;불필요 파일 제거&lt;/li&gt;
&lt;li&gt;멀티스테이지 빌드&lt;/li&gt;
&lt;li&gt;레이어 캐시 전략&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 결론: 컨테이너 효율과 배포 속도를 높이려면 &lt;strong&gt;이미지 구조와 UFS 동작 원리&lt;/strong&gt;를 이해하는 것이 필수입니다.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Docker-Compose] Install Harbor(v2.12.1)</title><link>https://kyungryeol-yoon.github.io/devops/harbor/docker-compose-harborv2.12.1/</link><pubDate>Sun, 19 Sep 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/harbor/docker-compose-harborv2.12.1/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/docker-install-compose(1.27.4)/"&gt;Docker-Compose 설치 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="harbor"&gt;
 Harbor
 &lt;a class="heading-anchor" href="#harbor" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;기존 docker-registry와는 달리 policy와 role 기반으로 access를 제어(RBAC)하는 것이 가능하다는 점이 가장 큰 특징&lt;/li&gt;
&lt;li&gt;또한 Harbor가 보관하고 있는 이미지의 취약성 등을 체크하여 해당 이미지가 신뢰할 수 있는 것인지 증빙해주는 역할도 수행&lt;/li&gt;
&lt;li&gt;그리고 Container Image만 보관할 수 있는 것이 아니라, Helm Package와 Cloud Native Application Bundle이라 하는 CNAB 패키지도 보관할 수 있다.&lt;/li&gt;
&lt;li&gt;또한 자체 WEB UI도 제공하여 관리가 편리하다는 장점이 있다.
&lt;ul&gt;
&lt;li&gt;물론 기존에도 docker-registry 용 UI container를 구성하여 이용하고는 있었지만, 특정 이미지가 Registry에 보관되어 있는지 등을 확인하는 정도로만 사용할 수 있어서 그 활용도가 굉장히 제한적이었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="인증기관-인증서-생성---ca-certificates-생성"&gt;
 인증기관 인증서 생성 - CA Certificates 생성
 &lt;a class="heading-anchor" href="#%ec%9d%b8%ec%a6%9d%ea%b8%b0%ea%b4%80-%ec%9d%b8%ec%a6%9d%ec%84%9c-%ec%83%9d%ec%84%b1---ca-certificates-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;실제 RootCA (신뢰할 수 있는 루트 인증 기관)를 사용하는게 아니라면, 직접 CA (인증 기관)를 생성하여 Server의 인증서가 안전하다고 인증해주어야 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;따라서 아래의 명령어로 개인용 Root CA 역할을 할 CA.key를 생성하고, CA.key의 짝이 되는 CA.crt 공개키를 생성한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Root CA의 비밀키 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;openssl genrsa -out ca.key &lt;span class="m"&gt;4096&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Root CA의 비밀키와 짝지을 공개키 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;openssl req -x509 -new -nodes -sha512 -days &lt;span class="m"&gt;3650&lt;/span&gt; -key ca.key -out ca.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;openssl req -x509 -new -nodes -sha512 -days &lt;span class="m"&gt;3650&lt;/span&gt; -subj &lt;span class="s2"&gt;&amp;#34;&amp;lt;원하는 도메인 명&amp;gt;&amp;#34;&lt;/span&gt; -key ca.key -out ca.crt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="서버인증서-생성---server-certificates-생성"&gt;
 서버인증서 생성 - Server Certificates 생성
 &lt;a class="heading-anchor" href="#%ec%84%9c%eb%b2%84%ec%9d%b8%ec%a6%9d%ec%84%9c-%ec%83%9d%ec%84%b1---server-certificates-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;서버의 인증서를 생성한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Root CA의 비밀키와 공개키를 만들 때와 마찬가지로 서버의 비밀키를 생성하고, 생성한 비밀키를 넣어 CSR 파일을 생성한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CSR 파일은 Certificate Signing Request 파일로, 인증서를 발급하기 위해 필요한 정보를 담고 있는 데이터이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CSR 파일은 SSL 발급을 신청하기 위해 해당 파일 내용을 Root CA에 제출하는 용도로 사용하게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Server Key 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;openssl genrsa -out server.key &lt;span class="m"&gt;4096&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;openssl genrsa -out &amp;lt;원하는 도메인 명&amp;gt;.key &lt;span class="m"&gt;4096&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Server의 csr 파일 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;openssl req -sha512 -new -key server.key -out server.csr
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;openssl req -sha512 -new -subj &lt;span class="s2"&gt;&amp;#34;/C=KR/ST=Seoul/L=Seoul/O=example/OU=Personal/CN=&amp;lt;원하는 도메인 명&amp;gt;&amp;#34;&lt;/span&gt; -key &amp;lt;원하는 도메인 명&amp;gt;.key -out &amp;lt;원하는 도메인 명&amp;gt;.csr&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="설정-파일-생성---san-등록"&gt;
 설정 파일 생성 - SAN 등록
 &lt;a class="heading-anchor" href="#%ec%84%a4%ec%a0%95-%ed%8c%8c%ec%9d%bc-%ec%83%9d%ec%84%b1---san-%eb%93%b1%eb%a1%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;이제 위에서 생성한 서버의 CSR 파일을, 직접 만든 Root CA에 인증해달라고 요청하는 작업을 수행한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CSR 파일을 가지고 서버의 인증키를 생성하게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;vi v3.ext&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
IP.1=192.168.0.54 # (인증서를 사용할 서버 IP 입력)
IP.2=127.0.0.1
# DNS.1=&amp;lt;원하는 도메인명&amp;gt;
# hostname=&amp;lt;원하는 호스트명&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="위-작업-수행-이후-sansubject-alternative-name-등록하는-작업-수행"&gt;
 위 작업 수행 이후, SAN(Subject Alternative Name) 등록하는 작업 수행
 &lt;a class="heading-anchor" href="#%ec%9c%84-%ec%9e%91%ec%97%85-%ec%88%98%ed%96%89-%ec%9d%b4%ed%9b%84-sansubject-alternative-name-%eb%93%b1%eb%a1%9d%ed%95%98%eb%8a%94-%ec%9e%91%ec%97%85-%ec%88%98%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;openssl x509 -req -sha512 -days &lt;span class="m"&gt;3650&lt;/span&gt; -extfile v3.ext -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;openssl x509 -req -sha512 -days &lt;span class="m"&gt;3650&lt;/span&gt; -extfile v3.ext -CA ca.crt -CAkey ca.key -CAcreateserial -in &amp;lt;원하는 도메인 명&amp;gt;.csr -out &amp;lt;원하는 도메인 명&amp;gt;.crt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="certificate-업데이트"&gt;
 Certificate 업데이트
 &lt;a class="heading-anchor" href="#certificate-%ec%97%85%eb%8d%b0%ec%9d%b4%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Docker에서는 .crt 파일을 CA (인증 기관)의 인증서라고 간주한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;서버의 인증서라는 것을 표현하고 싶다면 .crt 형식이 아닌 .cert 형식으로 변환해주어야 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;따라서 server.crt 파일을 server.cert 파일로 변환한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;openssl x509 -inform PEM -in server.crt -out server.cert&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;만들어진 인증서 파일들을 Docker와 Host에 등록(아래에서 한번 더 설명), 업데이트하는 작업을 수행한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;host의 이름을 server라고 했으므로, &lt;code&gt;/certs.d/server&lt;/code&gt;로 생성&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;폴더 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo mkdir -p /etc/docker/certs.d/server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Docker&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;cp server.cert /etc/docker/certs.d/server/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;cp server.key /etc/docker/certs.d/server/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;cp ca.crt /etc/docker/certs.d/server/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Host&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;sudo cp ca.crt /usr/local/share/ca-certificates/harbor-ca.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;sudo cp server.crt /usr/local/share/ca-certificates/harbor-server.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;sudo update-ca-certificates&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="특정-도메인으로-생성할-때"&gt;
 특정 도메인으로 생성할 때
 &lt;a class="heading-anchor" href="#%ed%8a%b9%ec%a0%95-%eb%8f%84%eb%a9%94%ec%9d%b8%ec%9c%bc%eb%a1%9c-%ec%83%9d%ec%84%b1%ed%95%a0-%eb%95%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Docker&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;cp &amp;lt;원하는 도메인 명&amp;gt;.cert /etc/docker/certs.d/&amp;lt;원하는 도메인 명&amp;gt;/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;cp &amp;lt;원하는 도메인 명&amp;gt;.key /etc/docker/certs.d/&amp;lt;원하는 도메인 명&amp;gt;/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;cp &amp;lt;원하는 도메인 명&amp;gt;.crt /etc/docker/certs.d/&amp;lt;원하는 도메인 명&amp;gt;/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Host&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;sudo cp ca.crt /usr/local/share/ca-certificates/harbor-ca.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;sudo cp &amp;lt;원하는 도메인 명&amp;gt;.crt /usr/local/share/ca-certificates/harbor-server.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;sudo update-ca-certificates&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="docker-재시작"&gt;
 Docker 재시작
 &lt;a class="heading-anchor" href="#docker-%ec%9e%ac%ec%8b%9c%ec%9e%91" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;systemctl restart docker&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="harbor-package-다운로드"&gt;
 Harbor package 다운로드
 &lt;a class="heading-anchor" href="#harbor-package-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Harbor는 Offline Install과 Online Install 두 가지 방식으로 설치를 지원하고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;wget https://github.com/goharbor/harbor/releases/download/v2.12.1/harbor-offline-installer-v2.12.1.tgz &lt;span class="c1"&gt;# habor 다운&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;tar xvzf harbor-offline-installer-v2.12.1.tgz &lt;span class="c1"&gt;# 압축해제&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="harboryml-작성"&gt;
 harbor.yml 작성
 &lt;a class="heading-anchor" href="#harboryml-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;기본적으로 Directory 내에는 harbor.yml.tmpl 파일이 존재&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이 파일의 이름을 harbor.yml로 수정하고 내용을 필요에 맞게 수정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cp harbor.yml.tmpl harbor.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;vi harbor.yml&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 아래 내용 수정&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;reg.mydomain.com &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# IP주소로 수정 (예시, 192.168.X.X)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# http related config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# port for http, default is 80. If https enabled, this port will redirect to https port&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# https related config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# https port for harbor, default is 443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# The path of cert and key files for nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;certificate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/your/certificate/path &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# server.cert로 수정 (예시, /etc/docker/certs.d/server/server.cert)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/your/private/key/path &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# server.key로 수정 (예시, /etc/docker/certs.d/server/server.key)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# enable strong ssl ciphers (default: false)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# strong_ssl_ciphers: false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="l"&gt;..&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="l"&gt;..&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;harbor_admin_password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Harbor12345 &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# admin 로그인 비밀번호 수정&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="deploy"&gt;
 Deploy
 &lt;a class="heading-anchor" href="#deploy" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;위 문단에서 작업한 harbor.yml의 작성이 끝나면, Harbor 설치의 사전 작업을 수행하는 prepare 스크립트를 실행&lt;/li&gt;
&lt;li&gt;prepare 스크립트는 결과적으로 prepare 컨테이너를 생성
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./prepare
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo ./install.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="다른-방법으로는"&gt;
 다른 방법으로는
 &lt;a class="heading-anchor" href="#%eb%8b%a4%eb%a5%b8-%eb%b0%a9%eb%b2%95%ec%9c%bc%eb%a1%9c%eb%8a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ./prepare&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;정상적으로 Script가 돌아가면 docker-compose.yml 파일이 생성
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker compose up -d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="repository-login-및-image-upload"&gt;
 Repository Login 및 Image Upload
 &lt;a class="heading-anchor" href="#repository-login-%eb%b0%8f-image-upload" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker login ip:8443&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;이미지를 저장소로 push하기 위해서는 login이 되어야 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;아래와 같이 새 저장소 서버에 로그인을 해보면 인증서 fail 에러가 남을 볼 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Error response from daemon: Get &lt;span class="s2"&gt;&amp;#34;https://192.168.0.54:8443/v2/&amp;#34;&lt;/span&gt;: tls: failed to verify certificate: x509: certificate signed by unknown authority&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;현재 서버에 사용했던 인증서가 docker 실행 wsl 리눅스 상에 install되어 있지 않기 때문이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;위에서 서버에 사용하기 위해 생성한 crt 인증서 파일을 아래 위치에 복사하고 update-ca-certificates 명령으로 적용한 후 docker, harbor를 재시작 하면 정상적으로 로그인 됨을 볼 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="인증-방법"&gt;
 인증 방법
 &lt;a class="heading-anchor" href="#%ec%9d%b8%ec%a6%9d-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Host&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo cp ca.crt /usr/local/share/ca-certificates/harbor-ca.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo cp server.crt /usr/local/share/ca-certificates/harbor-server.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;sudo update-ca-certificates&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker-compose down -v&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl restart docker.service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker-compose up -d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker login 192.168.0.54:8443
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;Username: admin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;Password:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;Configure a credential helper to remove this warning. See
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;https://docs.docker.com/engine/reference/commandline/login/#credentials-store
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;Login Succeeded&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="인증-skip"&gt;
 인증 Skip
 &lt;a class="heading-anchor" href="#%ec%9d%b8%ec%a6%9d-skip" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="docker"&gt;
 docker
 &lt;a class="heading-anchor" href="#docker" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;만약 /etc/docker Directory에 daemon.json 파일이 없는 경우 새롭게 생성&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;vi /etc/docker/daemon.json (아래 insecure 입력)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;insecure-registries&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;192.168.0.54:8443&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Docker Restart&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl restart docker&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Repository Login&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker login 192.168.0.54:8443&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Docker Tag&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker tag gitlab/gitlab-ce:17.6.2-ce.0 192.168.0.54:8443/mgmt-system/gitlab/gitlab-ce:17.6.2-ce.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Docker 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker images&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Docker Push&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker push 192.168.0.54:8443/mgmt-system/gitlab/gitlab-ce:17.6.2-ce.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Web Page에서 확인
&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/docker/harbor/docker-harbor-3.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="containerd"&gt;
 containerd
 &lt;a class="heading-anchor" href="#containerd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;private registry dns name &lt;code&gt;/etc/hosts&lt;/code&gt; 등록&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;172.x.x.x harbor.kryoon.io&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;config.toml 파일 확인&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;containerd 설정 파일을 확인 해줍니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/etc/containerd/config.toml&lt;/code&gt; 에 주로 있지만, 혹시 파일이 없다면&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;containerd config default &amp;gt; /etc/containerd/config.toml&lt;/code&gt; 명령어를 통해 생성해줍니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;private registry 주소 등록&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;[plugins.&amp;quot;io.containerd.grpc.v1.cri&amp;quot;.registry.mirrors]&lt;/code&gt; 아래에 registry 주소 추가&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ex)
[plugins.&amp;#34;io.containerd.grpc.v1.cri&amp;#34;.registry.mirrors]
 [plugins.&amp;#34;io.containerd.grpc.v1.cri&amp;#34;.registry.mirrors.&amp;#34;&amp;lt;private-registry 주소&amp;gt;&amp;#34;]
 endpoint = [&amp;#34;https://&amp;lt;private-registry 주소&amp;gt;&amp;#34;]&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;tls 설정 제외&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;원래라면 https 인증이 필요하지만 cert가 없어도 이미지를 받을 수 있게 설정해보도록 하겠습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;[plugins.&amp;quot;io.containerd.grpc.v1.cri&amp;quot;.registry.configs]&lt;/code&gt; 아래에 harbor 레지스트리의 ID, PW 정보와 verify skip 설정을 넣도록 하겠습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ex) 
[plugins.&amp;#34;io.containerd.grpc.v1.cri&amp;#34;.registry.configs]
 [plugins.&amp;#34;io.containerd.grpc.v1.cri&amp;#34;.registry.configs.&amp;#34;&amp;lt;private-registry 주소&amp;gt;&amp;#34;.auth]
 username = &amp;#34;&amp;lt;harbor ID&amp;gt;&amp;#34;
 password = &amp;#34;&amp;lt;harbor PW&amp;gt;&amp;#34;
 [plugins.&amp;#34;io.containerd.grpc.v1.cri&amp;#34;.registry.configs.&amp;#34;&amp;lt;private-registry 주소&amp;gt;&amp;#34;.tls]
 insecure_skip_verify = true &amp;lt;= 이 설정을 넣어주어야 인증서 없이도 이미지를 받을 수 있습니다.&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;[plugins.cri.registry]
[plugins.cri.registry.mirrors]
[plugins.cri.registry.mirrors.&amp;#34;docker.io&amp;#34;]
 endpoint = [&amp;#34;https://mirror.gcr.io&amp;#34;,&amp;#34;https://registry-1.docker.io&amp;#34;,&amp;#34;https://harbor.spk.io&amp;#34;]
[plugins.cri.registry.configs.&amp;#34;harbor.spk.io&amp;#34;.tls]
 insecure_skip_verify = true
# mirrors 설정은 굳이 필요 없기는 하다. 도커 허브(docker.io) 이미지를 2번째 pull 부터는 내부 private registry 에서 가져오겠다는 설정이다. &lt;/code&gt;&lt;/pre&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;systemctl restart containerd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="image-upload"&gt;
 image upload
 &lt;a class="heading-anchor" href="#image-upload" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker pull 192.168.0.54:8443/mgmt-system/gitlab/gitlab-ce:17.6.2-ce.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;or
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;sudo crictl pull harbor.kryoon.io/mgmt-system/gitlab/gitlab-ce:17.6.2-ce.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="접속"&gt;
 접속
 &lt;a class="heading-anchor" href="#%ec%a0%91%ec%86%8d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;IP 주소로 접속(192.168.77.163)해보면 NET::ERR_CERT_AUTHORITY_INVALID 에러가 뜬다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/docker/harbor/docker-harbor-1.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/docker/harbor/docker-harbor-2.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;접속한 웹사이트의 SSL/TLS 인증서가 신뢰할 수 있는 인증 기관(CA)에서 발급한 것이 아닌 경우에 발생하는데, 자체 서명된 인증서라 로컬에 인증서를 등록해야 https 연결이 가능하다(로컬에서만 연결됨).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/docker/harbor/docker-harbor-4.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/docker/harbor/docker-harbor-5.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="인증서-설치"&gt;
 인증서 설치
 &lt;a class="heading-anchor" href="#%ec%9d%b8%ec%a6%9d%ec%84%9c-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="windows"&gt;
 Windows
 &lt;a class="heading-anchor" href="#windows" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;h4 id="mac"&gt;
 Mac
 &lt;a class="heading-anchor" href="#mac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;keychain Access 실행 및 가져오기
&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/docker/harbor/harbor-mac-1.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;인증서 &lt;strong&gt;항상 신뢰&lt;/strong&gt;로 설정
&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/docker/harbor/harbor-mac-2.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;확인
&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/docker/harbor/harbor-mac-3.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="로그인"&gt;
 로그인
 &lt;a class="heading-anchor" href="#%eb%a1%9c%ea%b7%b8%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;reg.mydomain.com:8443
&lt;ul&gt;
&lt;li&gt;admin&lt;/li&gt;
&lt;li&gt;Harbor12345&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Gitlab CI</title><link>https://kyungryeol-yoon.github.io/devops/gitlab/kubernetes-gitlab-ci/</link><pubDate>Wed, 15 Sep 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/gitlab/kubernetes-gitlab-ci/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-install-gitlab-runner-using-helm/"&gt;Install Gitlab Runner 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;stages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;build&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# DOCKER_HOST: tcp://docker:2376&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# DOCKER_HOST: tcp://docker:2375&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;DOCKER_HOST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tcp://localhost:2375&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;DOCKER_TLS_CERTDIR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;DOCKER_DRIVER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;overlay2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# - docker:24.0.5-dind # Docker-in-Docker (dind) 서비스 사용&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker:19.03.12-dind&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;before_script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker info &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Docker 데몬 연결 확인&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;build&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;k8s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# image: docker:24.0.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;docker:19.03.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker build -t 192.168.0.54:8443/sample-app/test:0.0.1 .&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker push 192.168.0.54:8443/sample-app/test:0.0.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;manual&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;k8s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;docker:19.03.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker run my-image test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;manual&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;stages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="l"&gt;build&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="l"&gt;test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;docker-build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;build&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;only&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;DOCKER_HOST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tcp://docker:2376&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;DOCKER_TLS_CERTDIR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/certs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;DOCKER_TLS_VERIFY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;DOCKER_CERT_PATH&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;$DOCKER_TLS_CERTDIR/client&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;RND&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;CI_DOCKER_CONFIG&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;CI_IMAGE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;harbor.localhost.com/sample-api/sample-api&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;IMAGE_TAG&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;1.0.1&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mgmt-system/library-docker:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mgmt-system/docker-runner:dind&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;docker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;before_script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;echo &amp;#34;run.. CI_REGISTRY = $CI_REGISTRY&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;echo &amp;#34;run.. CI_DOCKER_CONFIG = $CI_DOCKER_CONFIG&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mkdir ~/.docker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;echo &amp;#34;$CI_DOCKER_CONFIG&amp;#34; | base64 -d &amp;gt; ~/.docker/config.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;cat ~/.docker/config.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker build --no-cache -t &amp;#34;$CI_IMAGE&amp;#34;:&amp;#34;$IMAGE_TAG&amp;#34; .&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker push &amp;#34;$CI_IMAGE&amp;#34;:&amp;#34;$IMAGE_TAG&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;manual&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;unit_test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;system/system-python3.8.8:1.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;echo &amp;#34;Running unit tests...&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;python3 -m venv venv&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;source venv/bin/activate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pip install --no-cache-dir -r requirements.txt -i http://nexus.com/repo/pypi/simple --trusted-host nexus.com&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pytest test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;manual&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="error-docker190312-dind-docker190312"&gt;
 error (docker:19.03.12-dind, docker:19.03.12)
 &lt;a class="heading-anchor" href="#error-docker190312-dind-docker190312" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;x509: certificate signed by unknown authority&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="error-docker2405-dind-docker2405"&gt;
 error (docker:24.0.5-dind, docker:24.0.5)
 &lt;a class="heading-anchor" href="#error-docker2405-dind-docker2405" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ERROR: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?
errors pretty printing info&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;만약 gitlab-ci.yml 에서 runner의 tag 또는 name을 지정할 경우 helm의 values.yaml에서 tags 혹은 name에 값을 설정해주면 된다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## Specify the tags associated with the runner. Comma-separated list of tags.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## ref: https://docs.gitlab.com/ee/ci/runners/configure_runners.html#use-tags-to-control-which-jobs-a-runner-can-run&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my-runner&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## Specify the name for the runner.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# name: &amp;#34;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Install Gitlab Runner Using Helm Chart</title><link>https://kyungryeol-yoon.github.io/devops/gitlab/kubernetes-install-gitlab-runner-using-helm/</link><pubDate>Sat, 11 Sep 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/gitlab/kubernetes-install-gitlab-runner-using-helm/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-helm/"&gt;Helm 설치 및 설명 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;gitlab runner 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.gitlab.com/runner/install/kubernetes.html"&gt;https://docs.gitlab.com/runner/install/kubernetes.html&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="helm-chart를-사용하여-gitlab-runner-설치"&gt;
 Helm Chart를 사용하여 GitLab Runner 설치
 &lt;a class="heading-anchor" href="#helm-chart%eb%a5%bc-%ec%82%ac%ec%9a%a9%ed%95%98%ec%97%ac-gitlab-runner-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;GitLab Helm 리포지터리를 추가&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm repo add gitlab https://charts.gitlab.io&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;values.yaml&lt;/code&gt; 파일을 사용하여 실행&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install --namespace &amp;lt;NAMESPACE&amp;gt; gitlab-runner -f &amp;lt;CONFIG_VALUES_FILE&amp;gt; gitlab/gitlab-runner&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;NAMESPACE&amp;gt;&lt;/code&gt;는 GitLab Runner를 설치하기 원하는 Kubernetes Namespace&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;CONFIG_VALUES_FILE&amp;gt;&lt;/code&gt;은 커스텀 설정이 포함된 파일의 경로. Helm Chart를 사용&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="values-작성"&gt;
 Values 작성
 &lt;a class="heading-anchor" href="#values-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;values.yaml 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://gitlab.com/gitlab-org/charts/gitlab-runner/blob/main/values.yaml"&gt;https://gitlab.com/gitlab-org/charts/gitlab-runner/blob/main/values.yaml&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;gitlab과 연결을 위해 아래와 같이 설정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;gitlabUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://gitlab.com&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# gitlab url 입력&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;runnerRegistrationToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;a-trnA24KR77Mh*****&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# registration token 생성(CI/CD &amp;gt; Runner &amp;gt; New Project Runner)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/docker/gitlab/gitlab-runner-step4.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="만약-ci를-사용하여-image-build를-하는-경우"&gt;
 만약 ci를 사용하여 image build를 하는 경우
 &lt;a class="heading-anchor" href="#%eb%a7%8c%ec%95%bd-ci%eb%a5%bc-%ec%82%ac%ec%9a%a9%ed%95%98%ec%97%ac-image-build%eb%a5%bc-%ed%95%98%eb%8a%94-%ea%b2%bd%ec%9a%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Docker In Docker (Dind) 혹은 buildah 같은 image를 사용하여 container 안에서 image를 생성해야 하는데 이 경우 gitlab-runner의 옵션을 추가해야 한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;runners&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; [[runners]]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; [runners.kubernetes]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; namespace = &amp;#34;{{.Release.Namespace}}&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; image = &amp;#34;ubuntu:20.04&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; privileged = true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;...&lt;/span&gt;&lt;span class="l"&gt;✂...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;기본 runner 설정은 ubuntu 이미지를 base로 사용하도록 되어있는데 이 부분에 &lt;code&gt;privileged = true&lt;/code&gt; 옵션을 추가해야 container 내부에서 image를 생성할 수 있는 권한이 추가된다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rbac-지원-활성화하기"&gt;
 RBAC 지원 활성화하기
 &lt;a class="heading-anchor" href="#rbac-%ec%a7%80%ec%9b%90-%ed%99%9c%ec%84%b1%ed%99%94%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ERROR: Job failed (system failure): secrets is forbidden&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;만약 다음 에러가 발생한다면 RBAC 기능을 활성화해야 한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Using Kubernetes executor with image alpine ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;ERROR: Job failed &lt;span class="o"&gt;(&lt;/span&gt;system failure&lt;span class="o"&gt;)&lt;/span&gt;: secrets is forbidden: User &lt;span class="s2"&gt;&amp;#34;system:serviceaccount:gitlab:default&amp;#34;&lt;/span&gt; cannot create resource &lt;span class="s2"&gt;&amp;#34;secrets&amp;#34;&lt;/span&gt; in API group &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt; in the namespace &lt;span class="s2"&gt;&amp;#34;gitlab&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;만약 클러스터가 RBAC를 사용하도록 설정한 경우, 차트가 자신의 서비스 계정을 만들거나 이미 만들어진 것을 사용하는 것을 선택할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;차트에서 서비스 계정을 만들려면 rbac.create를 true로 설정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;rbac&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;configmaps&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;events&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods/attach&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods/exec&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;secrets&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;services&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;list&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;watch&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;patch&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;update&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;delete&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods/exec&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;patch&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;delete&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods/log&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;rbac.create	: rbac을 생성한다. (create를 권장)&lt;/li&gt;
&lt;li&gt;rbac.resource	: rbac으로 접근가능한 resource를 설정한다.&lt;/li&gt;
&lt;li&gt;rbac.verbs : rbac으로 resource에 대해 부여할 권한을 설정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#############################################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;## WARNING: You enabled `rbac` without specifying if a service account should be created. ##&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;## Please set `serviceAccount.create` to either `true` or `false`. ##&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;## For backwards compatibility a service account will be created. ##&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#############################################################################################&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;위와 같은 경고가 뜬다면, 아래와 같이 &lt;code&gt;values.yaml&lt;/code&gt; 파일에 추가&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;serviceAccount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이미 존재하는 서비스 계정을 사용하려면 아래의 명령어를 사용 (아래 &lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-install-gitlab-runner-using-helm/#kubernetes-rbac-%EC%84%A4%EC%A0%95"&gt;Kubernetes RBAC 설정&lt;/a&gt; 설명 참고)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;rbac&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serviceAccountName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;your-service-account&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="helm-설치하기valuesyaml-파일이-있는-폴더에서-아래-명령어를-수행"&gt;
 helm 설치하기(&lt;code&gt;values.yaml&lt;/code&gt; 파일이 있는 폴더에서 아래 명령어를 수행)
 &lt;a class="heading-anchor" href="#helm-%ec%84%a4%ec%b9%98%ed%95%98%ea%b8%b0valuesyaml-%ed%8c%8c%ec%9d%bc%ec%9d%b4-%ec%9e%88%eb%8a%94-%ed%8f%b4%eb%8d%94%ec%97%90%ec%84%9c-%ec%95%84%eb%9e%98-%eb%aa%85%eb%a0%b9%ec%96%b4%eb%a5%bc-%ec%88%98%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm install --namespace hello-world gitlab-runner -f values.yaml gitlab/gitlab-runner&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="helm-chart를-사용하여-gitlab-runner-업그레이드"&gt;
 Helm Chart를 사용하여 GitLab Runner 업그레이드
 &lt;a class="heading-anchor" href="#helm-chart%eb%a5%bc-%ec%82%ac%ec%9a%a9%ed%95%98%ec%97%ac-gitlab-runner-%ec%97%85%ea%b7%b8%eb%a0%88%ec%9d%b4%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GitLab Runner를 업그레이드하기 전에, GitLab에 Runner를 중지시키고 모든 Job이 끝났는지 확인&lt;/li&gt;
&lt;li&gt;Runner를 중지시키는 것은 완료 시 권한부여 오류 같이 Job에서 발생하는 문제를 방지할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;helm upgrade --namespace &amp;lt;NAMESPACE&amp;gt; -f &amp;lt;CONFIG_VALUES_FILE&amp;gt; &amp;lt;RELEASE-NAME&amp;gt; gitlab/gitlab-runner&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;NAMESPACE&amp;gt;&lt;/code&gt;는 GitLab Runner를 설치하기 원하는 Kubernetes Namespace&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;CONFIG_VALUES_FILE&amp;gt;&lt;/code&gt;은 커스텀 설정이 포함된 파일의 경로. Helm Chart를 사용하여 GitLab Runner 설정하기를 참고&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;RELEASE-NMAE&amp;gt;&lt;/code&gt;은 차트를 설치할 때 지어주는 이름. Helm Chart를 사용하여 GitLab Runner 설치하기에서는 gitlab-runner라고 했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;GitLab Runner Helm Chart를 최신 버전이 아닌 특정 버전으로 업데이트하길 원한다면, &lt;code&gt;helm upgrade&lt;/code&gt; 명령어에 &lt;code&gt;--version &amp;lt;RUNNER_HELM_CHART_VERSION&amp;gt;&lt;/code&gt;을 추가
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="kubernetes-rbac-설정"&gt;
 Kubernetes RBAC 설정
 &lt;a class="heading-anchor" href="#kubernetes-rbac-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;특정 Namespace에 Runner를 사용하기 위해서는 몇 가지 설정이 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="namespace-생성"&gt;
 Namespace 생성
 &lt;a class="heading-anchor" href="#namespace-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Namespace의 경우 그룹이나 팀, 혹은 파트별로 구성&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;예시: group-a, group-b, team-a, team-b, part-a, part-b, dep-a, dep-b&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;아래 명령어를 실행하여 hello-world라는 Namespace를 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create namespace hello-world&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;생성된 Namespace 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get namespaces&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;생성된 Namespace로 이동(kubens가 설치되지 않았을 때 get 명령어에 -n 옵션으로 네임스페이스를 지정하면 된다.)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubens hello-world&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="service-account-생성"&gt;
 Service Account 생성
 &lt;a class="heading-anchor" href="#service-account-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Namespace를 관리할 Service Account 생성하여 관리&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;예시: sa-group-a, sa-group-b, sa-team-a, sa-team-b&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;아래 명령어를 실행하여 hello-sa라는 이름의 Service Account 생성&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;namespace를 지정(예시는 hello-world namespace를 연결)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF | kubectl apply -f -
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;apiVersion: v1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;kind: ServiceAccount
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; name: hello-sa
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; namespace: hello-world
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Service Account 정보 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get serviceaccounts hello-sa -o yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="role-생성"&gt;
 Role 생성
 &lt;a class="heading-anchor" href="#role-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;hello-role&lt;/code&gt;이라는 이름의 Role을 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF | kubectl apply -f -
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;apiVersion: rbac.authorization.k8s.io/v1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;kind: Role
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; namespace: hello-world
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; name: hello-role
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;rules:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;- apiGroups: [&amp;#34;extensions&amp;#34;, &amp;#34;apps&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; resources: [&amp;#34;deployments&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; verbs: [&amp;#34;get&amp;#34;, &amp;#34;list&amp;#34;, &amp;#34;watch&amp;#34;, &amp;#34;create&amp;#34;, &amp;#34;update&amp;#34;, &amp;#34;patch&amp;#34;, &amp;#34;delete&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;- apiGroups: [&amp;#34;&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; resources: [&amp;#34;pods&amp;#34;,&amp;#34;services&amp;#34;,&amp;#34;secrets&amp;#34;,&amp;#34;pods/exec&amp;#34;, &amp;#34;serviceaccounts&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; verbs: [&amp;#34;get&amp;#34;, &amp;#34;list&amp;#34;, &amp;#34;watch&amp;#34;, &amp;#34;create&amp;#34;, &amp;#34;update&amp;#34;, &amp;#34;patch&amp;#34;, &amp;#34;delete&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Role 정보 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get roles hello-role -o yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="role-binding-생성"&gt;
 Role Binding 생성
 &lt;a class="heading-anchor" href="#role-binding-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;hello-rb&lt;/code&gt;라는 이름의 Role Binding을 생성하여 &lt;code&gt;hello-sa&lt;/code&gt; Service Account와 &lt;code&gt;hello-role&lt;/code&gt; Role을 바인딩&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF | kubectl apply -f -
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;apiVersion: rbac.authorization.k8s.io/v1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;kind: RoleBinding
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; namespace: hello-world
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; name: hello-rb
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;subjects:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;- kind: ServiceAccount
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; name: hello-sa
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; namespace: hello-world
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;roleRef:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; kind: Role
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; name: hello-role
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; apiGroup: rbac.authorization.k8s.io
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Role Binding 정보를 확인&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get rolebindings hello-rb -o yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;만약 gitlab-ci.yml 에서 runner의 tag 또는 name을 지정할 경우 helm의 values.yaml에서 tags 혹은 name에 값을 설정해주면 된다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## Specify the tags associated with the runner. Comma-separated list of tags.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## ref: https://docs.gitlab.com/ee/ci/runners/configure_runners.html#use-tags-to-control-which-jobs-a-runner-can-run&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my-runner&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## Specify the name for the runner.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;##&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# name: &amp;#34;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>About Celery</title><link>https://kyungryeol-yoon.github.io/backend/python/celery/</link><pubDate>Sun, 05 Sep 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/python/celery/</guid><description>&lt;ul&gt;
&lt;li&gt;비동기 작업 큐이며, 스케쥴링이 가능하지만 실시간 처리에 중점을 두고 있음.&lt;/li&gt;
&lt;li&gt;동기/비동기 처리가 가능.&lt;/li&gt;
&lt;li&gt;작업단위를 Task, 작업자를 Worker라고 함.&lt;/li&gt;
&lt;li&gt;메시지 브로커를 사용함.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;주로 RabbitMQ나 Redis를 사용하는데, RabbitMQ와 궁합이 가장 잘 맞는다고 알려져있음.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="메세지-전달을-기반으로-한-비동기-task-queue"&gt;
 메세지 전달을 기반으로 한 비동기 task Queue
 &lt;a class="heading-anchor" href="#%eb%a9%94%ec%84%b8%ec%a7%80-%ec%a0%84%eb%8b%ac%ec%9d%84-%ea%b8%b0%eb%b0%98%ec%9c%bc%eb%a1%9c-%ed%95%9c-%eb%b9%84%eb%8f%99%ea%b8%b0-task-queue" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;작업 == 메세지&lt;/li&gt;
&lt;li&gt;Client는 작업을 요청&lt;/li&gt;
&lt;li&gt;Worker는 작업을 수행&lt;/li&gt;
&lt;li&gt;Broker는 메세지를 전달&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="비대칭적인-구조"&gt;
 비대칭적인 구조
 &lt;a class="heading-anchor" href="#%eb%b9%84%eb%8c%80%ec%b9%ad%ec%a0%81%ec%9d%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Client와 Worker가 각각 scale 가능&lt;/li&gt;
&lt;li&gt;Client : 불필요하게 무거운 작업으로부터 자유로움&lt;/li&gt;
&lt;li&gt;Worker : 필요에 따라 확장 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="비동기-처리기"&gt;
 비동기 처리기?
 &lt;a class="heading-anchor" href="#%eb%b9%84%eb%8f%99%ea%b8%b0-%ec%b2%98%eb%a6%ac%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;비동기 처리기는 동기적으로 수행하지 않아도 되는 일들을 처리해주는 역할&lt;/li&gt;
&lt;li&gt;결과를 즉시 받을 필요가 없거나 지연하여 처리해야 되는 일들을 보통 처리&lt;/li&gt;
&lt;li&gt;물론 그것이 제대로 처리가 되지 않아도 된다는 이야기는 아니기 떄문에 별도라 잘 만들어진 처리기가 필요하다. =&amp;gt; 항상 잘 처리되고 유실도 되지 않아야 한다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Error] Kubernetes configuration file is group-readable, world-readable</title><link>https://kyungryeol-yoon.github.io/kubernetes/security/kubernetes-configuration-file-is-group-readable-world-readable/</link><pubDate>Sun, 22 Aug 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/security/kubernetes-configuration-file-is-group-readable-world-readable/</guid><description>&lt;h2 id="아래와-같이-error"&gt;
 아래와 같이 Error
 &lt;a class="heading-anchor" href="#%ec%95%84%eb%9e%98%ec%99%80-%ea%b0%99%ec%9d%b4-error" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/.kube/config
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /root/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="해결-방법"&gt;
 해결 방법
 &lt;a class="heading-anchor" href="#%ed%95%b4%ea%b2%b0-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo chmod o-r ~/.kube/config
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo chmod g-r ~/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Install kubectl</title><link>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-install-kubectl/</link><pubDate>Sat, 21 Aug 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-install-kubectl/</guid><description>&lt;blockquote&gt;
&lt;p&gt;참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/ko/docs/tasks/tools/install-kubectl-linux/"&gt;https://kubernetes.io/ko/docs/tasks/tools/install-kubectl-linux/&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="install-kubectl"&gt;
 Install kubectl
 &lt;a class="heading-anchor" href="#install-kubectl" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -LO &lt;span class="s2"&gt;&amp;#34;https://dl.k8s.io/release/&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;curl -L -s https://dl.k8s.io/release/stable.txt&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/bin/linux/amd64/kubectl&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="kube-폴더-만들기"&gt;
 &lt;code&gt;.kube&lt;/code&gt; 폴더 만들기
 &lt;a class="heading-anchor" href="#kube-%ed%8f%b4%eb%8d%94-%eb%a7%8c%eb%93%a4%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mkdir ~/.kube&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="config-파일-작성"&gt;
 config 파일 작성
 &lt;a class="heading-anchor" href="#config-%ed%8c%8c%ec%9d%bc-%ec%9e%91%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi ~/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Docker] Install Gitlab Runner(v17.6.1)</title><link>https://kyungryeol-yoon.github.io/devops/gitlab/docker-install-gitlab-runnerv17.6.1/</link><pubDate>Wed, 11 Aug 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/gitlab/docker-install-gitlab-runnerv17.6.1/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/docker-install-compose(1.27.4)/"&gt;Docker-Compose 설치 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="gitlab-runner-설치"&gt;
 GitLab Runner 설치
 &lt;a class="heading-anchor" href="#gitlab-runner-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;GitLab Runner 작업 Directory (Working directory)와 데이터를 영속적(Persistent)으로 저장하기 위한 바인드 마운트(Bind mount)용 Directory를 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo mkdir -p /data/gitlab-runner/config &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; /data/gitlab-runner&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;gitlab-runner&lt;/code&gt; Directory의 소유권을 &lt;code&gt;$USER&lt;/code&gt;로 변경하고 권한을 변경&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo chown -R &lt;span class="nv"&gt;$USER&lt;/span&gt;:&lt;span class="nv"&gt;$USER&lt;/span&gt; /data/gitlab-runner&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;docker-compose.yml 파일을 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;3.9&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;gitlab-runner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;gitlab/gitlab-runner:v17.6.1&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gitlab-runner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;always&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s1"&gt;&amp;#39;./config:/etc/gitlab-runner&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s1"&gt;&amp;#39;/var/run/docker.sock:/var/run/docker.sock&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="gitlab-runner-시작"&gt;
 GitLab Runner 시작
 &lt;a class="heading-anchor" href="#gitlab-runner-%ec%8b%9c%ec%9e%91" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker-compose up -d&lt;/code&gt; 명령을 실행하여 Runner를 시작&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="gitlab-runner-등록"&gt;
 GitLab Runner 등록
 &lt;a class="heading-anchor" href="#gitlab-runner-%eb%93%b1%eb%a1%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GitLab UI에는 액세스 할 사용자에 따라 세 가지 유형의 Runner가 있다.
&lt;ul&gt;
&lt;li&gt;공유 러너는 GitLab 인스턴스의 모든 그룹 및 프로젝트에서 사용할 수 있다. (Admin Area의 &lt;strong&gt;CI/CD &amp;gt; Runners&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;그룹 러너는 그룹의 모든 프로젝트와 하위 그룹에서 사용할 수 있다. (그룹의 &lt;strong&gt;Settings &amp;gt; CI/CD &amp;gt; Runners 섹션&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;특정 러너는 특정 프로젝트와 연결됩니다. 일반적으로 특정 러너는 하나의 프로젝트에서만 사용된다. (프로젝트의 &lt;strong&gt;Settings &amp;gt; CI/CD &amp;gt; Runners&lt;/strong&gt; 섹션)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;여기에서는 &lt;strong&gt;공유 러너(Shared runner)&lt;/strong&gt; 를 등록하는 방법을 설명 (Admin 권한 필요)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="gitlab-admin-area-페이지로-이동한다"&gt;
 GitLab Admin Area 페이지로 이동한다.
 &lt;a class="heading-anchor" href="#gitlab-admin-area-%ed%8e%98%ec%9d%b4%ec%a7%80%eb%a1%9c-%ec%9d%b4%eb%8f%99%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/docker/gitlab/gitlab-runner-step1.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="사이드-바에서-cicd--runners를-클릭한다-이후-new-instance-runner-를-클릭한다"&gt;
 사이드 바에서 CI/CD &amp;gt; Runners를 클릭한다. 이후 New instance runner 를 클릭한다.
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9d%b4%eb%93%9c-%eb%b0%94%ec%97%90%ec%84%9c-cicd--runners%eb%a5%bc-%ed%81%b4%eb%a6%ad%ed%95%9c%eb%8b%a4-%ec%9d%b4%ed%9b%84-new-instance-runner-%eb%a5%bc-%ed%81%b4%eb%a6%ad%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/docker/gitlab/gitlab-runner-step2.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="태그-없이-runner을-사용하기-위해-run-untaged-jobs-를-체크한다-이후-create-runner-를-클릭하여-러너를-생성한다"&gt;
 태그 없이 Runner을 사용하기 위해 Run untaged jobs 를 체크한다. 이후 Create runner 를 클릭하여 러너를 생성한다.
 &lt;a class="heading-anchor" href="#%ed%83%9c%ea%b7%b8-%ec%97%86%ec%9d%b4-runner%ec%9d%84-%ec%82%ac%ec%9a%a9%ed%95%98%ea%b8%b0-%ec%9c%84%ed%95%b4-run-untaged-jobs-%eb%a5%bc-%ec%b2%b4%ed%81%ac%ed%95%9c%eb%8b%a4-%ec%9d%b4%ed%9b%84-create-runner-%eb%a5%bc-%ed%81%b4%eb%a6%ad%ed%95%98%ec%97%ac-%eb%9f%ac%eb%84%88%eb%a5%bc-%ec%83%9d%ec%84%b1%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/docker/gitlab/gitlab-runner-step3.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="step1-의-명령어를-복사한다"&gt;
 Step1 의 명령어를 복사한다.
 &lt;a class="heading-anchor" href="#step1-%ec%9d%98-%eb%aa%85%eb%a0%b9%ec%96%b4%eb%a5%bc-%eb%b3%b5%ec%82%ac%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/docker/gitlab/gitlab-runner-step4.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;gitlab-runner register --url http://192.168.0.54 --token glrt-t1__YKDoWm-di4smDhcNoCX&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="gitlab-runner-컨네이너에-대화형interactive-bash-shell을-실행"&gt;
 gitlab-runner 컨네이너에 대화형(interactive) Bash Shell을 실행
 &lt;a class="heading-anchor" href="#gitlab-runner-%ec%bb%a8%eb%84%a4%ec%9d%b4%eb%84%88%ec%97%90-%eb%8c%80%ed%99%94%ed%98%95interactive-bash-shell%ec%9d%84-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; -it gitlab-runner bash&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;프로젝트와 연동하는 방법은 두가지가 있다.
&lt;ul&gt;
&lt;li&gt;비대화식 모드(non-interactive mode)로 등록&lt;/li&gt;
&lt;li&gt;대화식 모드(interactive mode)로 등록&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="비대화식-모드non-interactive-mode"&gt;
 비대화식 모드(non-interactive mode)
 &lt;a class="heading-anchor" href="#%eb%b9%84%eb%8c%80%ed%99%94%ec%8b%9d-%eb%aa%a8%eb%93%9cnon-interactive-mode" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;gitlab-runner register -n &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;--url http://&lt;span class="nv"&gt;$IP&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;--registration-token &lt;span class="nv"&gt;$TOKEN&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;--description gitlab-runner &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;--executor shell &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;--tag-list deploy-1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;...✂...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;Runner registered successfully. Feel free to start it, but &lt;span class="k"&gt;if&lt;/span&gt; it&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;s running already the config should be automatically reloaded!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;Option&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Description&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;--url&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;GitLab 인스턴스 URL&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;--registration-token&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Project의 token&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;--description&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;설명&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;--executor&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;빌드를 실행하는 데 사용할 수 있는 여러 실행 프로그램&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;--docker-image&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Docker를 실행 프로그램으로 선택한 경우 사용할 이미지&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;--docker-volumes&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Docker를 실행 프로그램으로 선택한 경우 사용할 볼륨&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;--tag-list&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;.gitlab-ci.yml&lt;/code&gt; 파일에서 작업할 runner를 지정할때 사용&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="대화식-모드interactive-mode"&gt;
 대화식 모드(interactive mode)
 &lt;a class="heading-anchor" href="#%eb%8c%80%ed%99%94%ec%8b%9d-%eb%aa%a8%eb%93%9cinteractive-mode" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gitlab-runner register ~&lt;/code&gt; 명령을 실행하고 지침에 따라 아래 항목을 입력
&lt;ul&gt;
&lt;li&gt;Enter the GitLab instance URL : 아무것도 입력하지 않고 Enter 키를 누른다. &lt;code&gt;--url&lt;/code&gt; 값이 설정된다.&lt;/li&gt;
&lt;li&gt;Enter the registration token : 아무것도 입력하지 않고 Enter 키를 누른다. &lt;code&gt;--token&lt;/code&gt; 값이 설정된다.&lt;/li&gt;
&lt;li&gt;Enter a description for the runner : 러너에 대한 설명을 입력하고 Enter 키를 누른다. (예: &lt;code&gt;docker runner&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Enter tags for the runner : 아무것도 입력하지 않고 Enter 키를 누른다.&lt;/li&gt;
&lt;li&gt;Enter an executor : &lt;code&gt;docker&lt;/code&gt;을 입력하고 Enter 키를 누른다.&lt;/li&gt;
&lt;li&gt;Enter the default Docker image : &lt;code&gt;alpine:latest&lt;/code&gt;을 입력하고 Enter 키를 누른다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;ubuntu@mp-repo:/data/gitlab-runner$ sudo docker &lt;span class="nb"&gt;exec&lt;/span&gt; -it gitlab-runner bash
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;root@183e583bf883:/# gitlab-runner register --url http://192.168.0.54 --token glrt-t1_bkEhznhp1Qbdow6o44TK
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;Runtime platform &lt;span class="nv"&gt;arch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;amd64 &lt;span class="nv"&gt;os&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;linux &lt;span class="nv"&gt;pid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;52&lt;/span&gt; &lt;span class="nv"&gt;revision&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;6826a62f &lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;17.6.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;Running in system-mode.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;Enter the GitLab instance URL &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; example, https://gitlab.com/&lt;span class="o"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;http://192.168.0.54&lt;span class="o"&gt;]&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;Verifying runner... is valid &lt;span class="nv"&gt;runner&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;t1_bkEhzn
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;Enter a name &lt;span class="k"&gt;for&lt;/span&gt; the runner. This is stored only in the &lt;span class="nb"&gt;local&lt;/span&gt; config.toml file:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;183e583bf883&lt;span class="o"&gt;]&lt;/span&gt;: docker runner
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;Enter an executor: shell, docker-windows, docker+machine, kubernetes, docker-autoscaler, instance, custom, ssh, parallels, virtualbox, docker:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;Enter the default Docker image &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; example, ruby:2.7&lt;span class="o"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;alpine:latest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;Runner registered successfully. Feel free to start it, but &lt;span class="k"&gt;if&lt;/span&gt; it&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;s running already the config should be automatically reloaded!
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;Configuration &lt;span class="o"&gt;(&lt;/span&gt;with the authentication token&lt;span class="o"&gt;)&lt;/span&gt; was saved in &lt;span class="s2"&gt;&amp;#34;/etc/gitlab-runner/config.toml&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;정상적으로 등록이 완료되면 You’ve created a new runner! 문구가 나타난다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/docker/gitlab/gitlab-runner-step5.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="cicd--runners-페이지에서-gitlab-ui를-새로고침하면-등록된-러너가-목록에-나타난다"&gt;
 CI/CD &amp;gt; Runners 페이지에서 GitLab UI를 새로고침하면 등록된 러너가 목록에 나타난다.
 &lt;a class="heading-anchor" href="#cicd--runners-%ed%8e%98%ec%9d%b4%ec%a7%80%ec%97%90%ec%84%9c-gitlab-ui%eb%a5%bc-%ec%83%88%eb%a1%9c%ea%b3%a0%ec%b9%a8%ed%95%98%eb%a9%b4-%eb%93%b1%eb%a1%9d%eb%90%9c-%eb%9f%ac%eb%84%88%ea%b0%80-%eb%aa%a9%eb%a1%9d%ec%97%90-%eb%82%98%ed%83%80%eb%82%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/kubernetes/docker/gitlab/gitlab-runner-step6.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="gitlab-runner-구성"&gt;
 GitLab Runner 구성
 &lt;a class="heading-anchor" href="#gitlab-runner-%ea%b5%ac%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GitLab Runner 및 등록된 개별 Runner의 동작을 변경할 수 있다.&lt;/li&gt;
&lt;li&gt;GitLab Runner의 구성을 변경하려면 &lt;code&gt;config.toml&lt;/code&gt; 파일을 수정해야 한다.&lt;/li&gt;
&lt;li&gt;대부분의 옵션을 변경할 때 GitLab Runner를 다시 시작할 필요가 없다. 여기에는 &lt;code&gt;listen_address&lt;/code&gt;를 제외한 &lt;code&gt;[[runners]]&lt;/code&gt; 섹션의 파라미터와 글로벌 섹션의 대부분의 파라미터가 포함된다.&lt;/li&gt;
&lt;li&gt;GitLab Runner는 3 초마다 구성 수정사항을 확인하고 필요한 경우 다시 로드한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="job-동시성concurrency-설정"&gt;
 Job 동시성(concurrency) 설정
 &lt;a class="heading-anchor" href="#job-%eb%8f%99%ec%8b%9c%ec%84%b1concurrency-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;GitLab Runner가 동시에 여러 Job을 실행할 수 있도록 적절하게 &lt;code&gt;concurrent&lt;/code&gt;을 수정한다.&lt;/li&gt;
&lt;li&gt;예를 들어, 4vCPU/16GiB인 경우 &lt;code&gt;concurrent = 4&lt;/code&gt;로 설정한다.&lt;/li&gt;
&lt;li&gt;GitLab.com의 &lt;a href="https://docs.gitlab.com/ee/install/requirements.html#gitlab-runner"&gt;자동 확장(Auto-scaling) Shared Runner&lt;/a&gt;는 단일 작업이 1 vCPU와 3.75GiB를 사용하여 단일 인스턴스에서 실행되도록 구성된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="docker-특권privileged-모드-설정"&gt;
 Docker 특권(privileged) 모드 설정
 &lt;a class="heading-anchor" href="#docker-%ed%8a%b9%ea%b6%8cprivileged-%eb%aa%a8%eb%93%9c-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;아래 CI 파이프라인(.gitlab-ci.yml)과 같이, &lt;a href="https://hub.docker.com/_/docker"&gt;Docker-in-Docker&lt;/a&gt; 컨테이너를 사용하여 docker build와 같은 스크립트를 실행하기 위해서는 &lt;a href="https://docs.docker.com/engine/containers/run/#runtime-privilege-and-linux-capabilities"&gt;특권 모드(privileged mode)&lt;/a&gt; 설정이 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;docker:git&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="l"&gt;docker:dind&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker build -t my-image .&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker push my-image&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;위에서 언급한 Runner 옵션을 수정하려면 Runner 작업 Directory(예: &lt;code&gt;/data/gitlab-runner&lt;/code&gt;)에서 아래 명령을 실행하고 수정한다. 또는 gitlab-runner bash에 접속하여 &lt;code&gt;/etc/gitlab-runner&lt;/code&gt;에서 &lt;code&gt;config.toml&lt;/code&gt;를 수정하여도 된다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo vi config/config.toml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;[runners.docker]&lt;/code&gt;에서 &lt;code&gt;privileged = true&lt;/code&gt;로 설정한다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;...✂...

concurrent = 2
check_interval = 0
connection_max_age = &amp;#34;15m0s&amp;#34;
shutdown_timeout = 0

[session_server]
 session_timeout = 1800

[[runners]]

 ...✂...

 [runners.docker]
 tls_verify = false
 image = &amp;#34;alpine:latest&amp;#34;
 privileged = true

...✂...&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;gitlab-runner restart&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker restart &lt;span class="o"&gt;[&lt;/span&gt;gitlab-runner 컨테이너 id&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;gitlab ci yml 구성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;AWS_ACCOUNT_ID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;AWS 계정 아이디]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;DOCKER_REGISTRY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;CPU&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;MEMORY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2048&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;DOCKER_HOST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tcp://localhost:2375&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;DOCKER_DRIVER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;overlay2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;DOCKER_TLS_CERTDIR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;build_prod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;build&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;docker:stable&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;docker:20-dind&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;localhost&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;--tls=false&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ECR_REPOSITORIES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;레포지토리명]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;before_script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;apk add --no-cache curl python3 py3-pip&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pip install awscli botocore==1.29.21&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;aws s3 cp $AWS_S3_BUCKET_URI/$APP_NAME ./ --recursive --exclude=&amp;#34;*.development&amp;#34; --exclude=&amp;#34;prisma/*&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;aws s3 cp $AWS_S3_BUCKET_URI/$APP_NAME/prisma/production/.env ./prisma/.env&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.$DOCKER_REGISTRY&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;export DOCKER_HOST=tcp://localhost:2375&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;aws --version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker info&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker --version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;echo &amp;#34;Building image...&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker build -f Dockerfile.prod -t $ECR_REPOSITORIES:$CI_COMMIT_SHORT_SHA .&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;echo &amp;#34;Tagging image...&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker tag $ECR_REPOSITORIES:$CI_COMMIT_SHORT_SHA $AWS_ACCOUNT_ID.$DOCKER_REGISTRY/$ECR_REPOSITORIES:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;echo &amp;#34;Pushing image...&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docker push $AWS_ACCOUNT_ID.$DOCKER_REGISTRY/$ECR_REPOSITORIES:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;only&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;production&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;deploy_prod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;deploy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;docker:stable&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;docker:20-dind&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;localhost&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;--tls=false&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ECR_REPOSITORIES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;레포지토리명]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;TASK_DEFINITION_NAME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;테스크명]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;CLUSTER_NAME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;클러스터명]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;SERVICE_NAME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;서비스명]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;needs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;build_prod]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;before_script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;apk add --no-cache curl jq python3 py3-pip&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pip install awscli botocore==1.29.21&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.$DOCKER_REGISTRY&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;echo $DOCKER_REGISTRY/$APP_NAME:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;echo &amp;#34;Updating the service...&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;aws ecs update-service --region &amp;#34;$AWS_DEFAULT_REGION&amp;#34; --cluster &amp;#34;$CLUSTER_NAME&amp;#34; --service &amp;#34;$SERVICE_NAME&amp;#34; --task-definition &amp;#34;$TASK_DEFINITION_NAME&amp;#34; --force-new-deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;only&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;production&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Python] Fast API</title><link>https://kyungryeol-yoon.github.io/backend/python/python-fast-api/</link><pubDate>Thu, 15 Jul 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/python/python-fast-api/</guid><description>&lt;h2 id="fastapi란"&gt;
 FastAPI란?
 &lt;a class="heading-anchor" href="#fastapi%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;파이썬 3.6+ 으로 API서버를 구축하기 위한 모던하고, 빠른 웹 프레임 워크&lt;/p&gt;
&lt;h3 id="fastapi-설치"&gt;
 fastapi 설치
 &lt;a class="heading-anchor" href="#fastapi-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pip install fastapi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="uvicorn-설치"&gt;
 uvicorn 설치
 &lt;a class="heading-anchor" href="#uvicorn-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pip install uvicorn&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="간단한-실행"&gt;
 간단한 실행
 &lt;a class="heading-anchor" href="#%ea%b0%84%eb%8b%a8%ed%95%9c-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;root&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;message&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Hello World&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="fastapi--uvicorn-실행"&gt;
 fastapi + uvicorn 실행
 &lt;a class="heading-anchor" href="#fastapi--uvicorn-%ec%8b%a4%ed%96%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;uvicorn main:app --reload --host&lt;span class="o"&gt;=&lt;/span&gt;0.0.0.0 --port&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;8000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;Name&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Description&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;main&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;여기서 main은 main.py의 main을 말한다&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;app&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;main.py안에 있는 app=FastAPI()&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;--reload&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;코드 변경 시 자동으로 저장되어 재시작 됨&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;--host&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;모든 접근이 가능하게 하려면 0.0.0.0을 입력한다.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;code&gt;--port&lt;/code&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;접속 원하는 포트를 지정해준다.&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;</description></item><item><title>[Python] 가상환경 venv 사용법</title><link>https://kyungryeol-yoon.github.io/backend/python/python-venv/</link><pubDate>Fri, 02 Jul 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/python/python-venv/</guid><description>&lt;h2 id="-왜-파이썬-가상환경venv을-써야-할까"&gt;
 🐍 왜 파이썬 가상환경(venv)을 써야 할까?
 &lt;a class="heading-anchor" href="#-%ec%99%9c-%ed%8c%8c%ec%9d%b4%ec%8d%ac-%ea%b0%80%ec%83%81%ed%99%98%ea%b2%bdvenv%ec%9d%84-%ec%8d%a8%ec%95%bc-%ed%95%a0%ea%b9%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;파이썬 프로젝트를 진행하다 보면 &amp;ldquo;A 프로젝트에서는 Django 3.2가 필요한데, B 프로젝트에서는 4.0이 필요하네?&amp;rdquo; 같은 상황이 발생합니다. 이때 시스템에 패키지를 전역으로 설치하면 버전 충돌로 인해 코드가 깨질 수 있습니다. 😱&lt;/p&gt;
&lt;p&gt;**가상환경(Virtual Environment)**은 프로젝트마다 독립된 방을 만들어 주는 것과 같습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&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;/strong&gt;: 팀원들과 동일한 패키지 환경을 공유하기 매우 쉬워집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-1-가상환경-생성하기"&gt;
 🛠️ 1. 가상환경 생성하기
 &lt;a class="heading-anchor" href="#-1-%ea%b0%80%ec%83%81%ed%99%98%ea%b2%bd-%ec%83%9d%ec%84%b1%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;프로젝트 루트 폴더(예: &lt;code&gt;my_project&lt;/code&gt;)로 이동한 뒤 아래 명령어를 입력합니다. 가상환경 이름은 관례적으로 &lt;code&gt;venv&lt;/code&gt;를 가장 많이 사용합니다.&lt;/p&gt;
&lt;h3 id="기본-생성"&gt;
 기본 생성
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# python -m venv [가상환경이름]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;python -m venv venv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="특정-버전으로-생성-설치된-경우"&gt;
 특정 버전으로 생성 (설치된 경우)
 &lt;a class="heading-anchor" href="#%ed%8a%b9%ec%a0%95-%eb%b2%84%ec%a0%84%ec%9c%bc%eb%a1%9c-%ec%83%9d%ec%84%b1-%ec%84%a4%ec%b9%98%eb%90%9c-%ea%b2%bd%ec%9a%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Windows&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;py -3.10 -m venv venv
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# macOS / Linux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;python3.10 -m venv venv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: &lt;code&gt;--system-site-packages&lt;/code&gt; 옵션을 붙이면 시스템에 이미 설치된 전역 패키지들을 포함한 상태로 가상환경을 시작할 수 있습니다.
{: .prompt-tip }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-2-가상환경-활성화--비활성화"&gt;
 🚀 2. 가상환경 활성화 &amp;amp; 비활성화
 &lt;a class="heading-anchor" href="#-2-%ea%b0%80%ec%83%81%ed%99%98%ea%b2%bd-%ed%99%9c%ec%84%b1%ed%99%94--%eb%b9%84%ed%99%9c%ec%84%b1%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;가상환경을 만들었으면 그 &amp;lsquo;방&amp;rsquo;으로 들어가야 합니다. 운영체제에 따라 명령어가 다르니 주의하세요!&lt;/p&gt;
&lt;h3 id="활성화-activate"&gt;
 활성화 (Activate)
 &lt;a class="heading-anchor" href="#%ed%99%9c%ec%84%b1%ed%99%94-activate" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;운영체제&lt;/th&gt;
					&lt;th&gt;터미널 (Shell)&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;strong&gt;Windows&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;CMD / PowerShell&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;venv\Scripts\activate&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;macOS / Linux&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;bash / zsh&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;source venv/bin/activate&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;활성화되면 터미널 프롬프트 앞에 &lt;code&gt;(venv)&lt;/code&gt;라는 표시가 나타납니다.&lt;/p&gt;
&lt;h3 id="비활성화-deactivate"&gt;
 비활성화 (Deactivate)
 &lt;a class="heading-anchor" href="#%eb%b9%84%ed%99%9c%ec%84%b1%ed%99%94-deactivate" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;작업이 끝났다면 어느 환경에서든 아래 명령어 한 줄이면 됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;deactivate&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-3-패키지-관리-설치-및-공유"&gt;
 📦 3. 패키지 관리 (설치 및 공유)
 &lt;a class="heading-anchor" href="#-3-%ed%8c%a8%ed%82%a4%ec%a7%80-%ea%b4%80%eb%a6%ac-%ec%84%a4%ec%b9%98-%eb%b0%8f-%ea%b3%b5%ec%9c%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;가상환경이 활성화된 상태에서 패키지를 관리하는 방법입니다.&lt;/p&gt;
&lt;h3 id="패키지-설치-및-확인"&gt;
 패키지 설치 및 확인
 &lt;a class="heading-anchor" href="#%ed%8c%a8%ed%82%a4%ec%a7%80-%ec%84%a4%ec%b9%98-%eb%b0%8f-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pip install pandas &lt;span class="c1"&gt;# 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;pip uninstall pandas &lt;span class="c1"&gt;# 삭제&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;pip list &lt;span class="c1"&gt;# 설치된 패키지 목록 확인&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="협업의-핵심-requirementstxt"&gt;
 협업의 핵심: requirements.txt
 &lt;a class="heading-anchor" href="#%ed%98%91%ec%97%85%ec%9d%98-%ed%95%b5%ec%8b%ac-requirementstxt" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;내가 사용한 패키지 목록을 파일로 만들어 팀원에게 전달하거나, 서버에 배포할 때 사용합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 현재 환경의 패키지 목록 추출&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;pip freeze &amp;gt; requirements.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 파일에 기록된 패키지 한 번에 설치 (새 환경에서)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;pip install -r requirements.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-4-주의사항-git-관리"&gt;
 ⚠️ 4. 주의사항 (Git 관리)
 &lt;a class="heading-anchor" href="#-4-%ec%a3%bc%ec%9d%98%ec%82%ac%ed%95%ad-git-%ea%b4%80%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;가상환경 폴더(&lt;code&gt;venv/&lt;/code&gt;)는 용량이 크고 사용자의 로컬 경로에 의존적입니다. 따라서 &lt;strong&gt;Git에 절대 올리지 않습니다.&lt;/strong&gt; 🙅‍♂️&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.gitignore&lt;/code&gt; 파일에 반드시 아래 내용을 추가해 주세요.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;# .gitignore
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;venv/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;__pycache__/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;*.pyc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;참고 자료: &lt;a href="https://kyungryeol-yoon.github.io/posts/python-venv-virtualenv/"&gt;venv와 virtualenv 차이&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Python] 가상환경 venv, virtualenv</title><link>https://kyungryeol-yoon.github.io/backend/python/python-venv-virtualenv/</link><pubDate>Tue, 22 Jun 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/python/python-venv-virtualenv/</guid><description>&lt;h2 id="virtualenv와-venv의-차이"&gt;
 virtualenv와 venv의 차이?
 &lt;a class="heading-anchor" href="#virtualenv%ec%99%80-venv%ec%9d%98-%ec%b0%a8%ec%9d%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;기본적으로 둘 다 가상 환경을 만드는 라이브러리지만, 약간의 차이가 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;venv&lt;/strong&gt; : Python 3.3 버전 이후부터 기본 라이브러리로 포함되어 별도의 설치 과정이 필요없다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;virtualenv&lt;/strong&gt; : Python 2 버전부터 쓰던 라이브러리로, Python 3에서도 사용 가능하고 별도의 설치 과정 필요&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;더 정확하게 venv 모듈은 virtualenv의 경량화된 모듈로, 속도와 확장성 측면에서 virtualenv이 더 우수하다고 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;대신 venv는 기본 내장 라이브러리이기 때문에 pip install의 설치 과정이 필요없어서 간단한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="venv으로-가상환경-만들기"&gt;
 venv으로 가상환경 만들기
 &lt;a class="heading-anchor" href="#venv%ec%9c%bc%eb%a1%9c-%ea%b0%80%ec%83%81%ed%99%98%ea%b2%bd-%eb%a7%8c%eb%93%a4%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 버전 지정 없이 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;python -m venv &lt;span class="o"&gt;[&lt;/span&gt;가상환경이름&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 버전을 지정해서 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;py -버전 -m venv &lt;span class="o"&gt;[&lt;/span&gt;가상환경이름&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="virtualenv로-가상환경-만들기"&gt;
 virtualenv로 가상환경 만들기
 &lt;a class="heading-anchor" href="#virtualenv%eb%a1%9c-%ea%b0%80%ec%83%81%ed%99%98%ea%b2%bd-%eb%a7%8c%eb%93%a4%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;venv와 달리 pip install로 virtualenv 라이브러리 설치 과정이 필요하다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;pip는 Python 버전마다 다르므로, Python 버전을 확인한 뒤 해당 버전에 맞는 pip로 설치를 진행해주어야 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Python을 설치하면 기본적으로 &lt;code&gt;Python버전명\lib\site-packages\&lt;/code&gt; 내부에 pip폴더가 존재한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="virtualenv-version-지정하여-설치"&gt;
 virtualenv Version 지정하여 설치
 &lt;a class="heading-anchor" href="#virtualenv-version-%ec%a7%80%ec%a0%95%ed%95%98%ec%97%ac-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;pip Version 지정 설치&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;py -버전 -m pip install virtualenv
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;py -3.7 -m pip install virtualenv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;virtualenv 가상환경 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;virtualenv 가상환경이름 --python&lt;span class="o"&gt;=[&lt;/span&gt;Python Version&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;virtualenv myenv --python&lt;span class="o"&gt;=&lt;/span&gt;3.7&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;venv 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3/library/venv.htm"&gt;https://docs.python.org/3/library/venv.htm&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Python] pip install Package</title><link>https://kyungryeol-yoon.github.io/backend/python/python-pip/</link><pubDate>Sat, 05 Jun 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/python/python-pip/</guid><description>&lt;h2 id="pip의-일괄-설치-옵션---r-requirementstxt"&gt;
 pip의 일괄 설치 옵션 : -r requirements.txt
 &lt;a class="heading-anchor" href="#pip%ec%9d%98-%ec%9d%bc%ea%b4%84-%ec%84%a4%ec%b9%98-%ec%98%b5%ec%85%98---r-requirementstxt" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;아래의 Command로 설정 파일 requirements.txt에 작성된 내용에 따라 패키지를 일괄 설치된다.&lt;/li&gt;
&lt;li&gt;설정 파일명은 임의로 어떠한 이름으로해도 상관없지만, requirements.txt이라는 이름으로 하는 것이 일반적이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pip install -r requirements.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="설정-파일-requirementstxt의-작성법"&gt;
 설정 파일 requirements.txt의 작성법
 &lt;a class="heading-anchor" href="#%ec%84%a4%ec%a0%95-%ed%8c%8c%ec%9d%bc-requirementstxt%ec%9d%98-%ec%9e%91%ec%84%b1%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;설정 파일 requirements.txt의 예는 아래와 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;###### Requirements without Version Specifiers ######`
fastapi
click
uvicorn

###### Requirements with Version Specifiers ######`
annotated-types==0.7.0
anyio==4.4.0
click==8.1.7
colorama==0.4.6
fastapi==0.112.1
h11==0.14.0
idna==3.7
pydantic==2.8.2
pydantic_core==2.20.1
sniffio==1.3.1
starlette==0.38.2
typing_extensions==4.12.2
uvicorn==0.30.6&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Python 코드와 동일하게 &lt;code&gt;#&lt;/code&gt;는 Command 주석 처리한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;==&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;등으로 패키지를 지정할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;버전 지정을 생략한 겅우에는 자동으로 그 패키지의 최신버전이 설치된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;,(Comma)로 구분하면 2개의 조건을 AND로 지정할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;아래의 예는 1.0이상이면서 2.0이하의 버전을 인스톨하도록 지정한 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;package &amp;gt;= 1.0, &amp;lt;=2.0&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="현재-환경의-설정-파일을-출력하는-pip-freeze"&gt;
 현재 환경의 설정 파일을 출력하는 pip freeze
 &lt;a class="heading-anchor" href="#%ed%98%84%ec%9e%ac-%ed%99%98%ea%b2%bd%ec%9d%98-%ec%84%a4%ec%a0%95-%ed%8c%8c%ec%9d%bc%ec%9d%84-%ec%b6%9c%eb%a0%a5%ed%95%98%eb%8a%94-pip-freeze" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pip freeze Command&lt;/code&gt;로 현재 환경에 설치되어 있는 패키지와 버전이 &lt;code&gt;pip install -r&lt;/code&gt;로 사용할 수 있는 설정 파일 형식을 출력해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pip freeze &amp;gt; requirements.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;이렇게 출력된 파일은 맨 처음에 소개 했던 &lt;code&gt;pip install -r&lt;/code&gt; Command로 파일에 기재되어 있는 패키지, 버전을 한 번에 설치해준다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Docker] DFOREGROUND 옵션 이해 및 활용</title><link>https://kyungryeol-yoon.github.io/docker/dforeground/</link><pubDate>Fri, 21 May 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/docker/dforeground/</guid><description>&lt;h2 id="-dforeground-옵션이란"&gt;
 ⚡ DFOREGROUND 옵션이란?
 &lt;a class="heading-anchor" href="#-dforeground-%ec%98%b5%ec%85%98%ec%9d%b4%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;DFOREGROUND&lt;/code&gt;는 일반적으로 &lt;strong&gt;컨테이너나 리눅스 서비스&lt;/strong&gt;에서 사용되는 옵션으로,&lt;br&gt;
&lt;strong&gt;프로세스를 포그라운드(Foreground)에서 실행&lt;/strong&gt;하라는 의미입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-비유로-이해하기"&gt;
 1️⃣ 비유로 이해하기
 &lt;a class="heading-anchor" href="#1-%eb%b9%84%ec%9c%a0%eb%a1%9c-%ec%9d%b4%ed%95%b4%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;백그라운드(Background)&lt;/strong&gt;: 몰래 일하는 비밀 요원&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;터미널과 분리되어 혼자 일함&lt;/li&gt;
&lt;li&gt;로그 확인이 어렵고, 터미널 종료와는 무관하게 돌아감&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;포그라운드(-DFOREGROUND)&lt;/strong&gt;: 무대 위 주인공&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;지금 터미널/컨테이너 앞에서 바로 실행됨&lt;/li&gt;
&lt;li&gt;로그도 바로 확인 가능&lt;/li&gt;
&lt;li&gt;컨테이너 PID 1 프로세스로 살아있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="2-도커에서-필요한-이유"&gt;
 2️⃣ 도커에서 필요한 이유
 &lt;a class="heading-anchor" href="#2-%eb%8f%84%ec%bb%a4%ec%97%90%ec%84%9c-%ed%95%84%ec%9a%94%ed%95%9c-%ec%9d%b4%ec%9c%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;도커 컨테이너는 &lt;strong&gt;메인 프로세스가 종료되면 컨테이너도 종료&lt;/strong&gt;됨&lt;/li&gt;
&lt;li&gt;Apache를 백그라운드로 실행하면 → 컨테이너가 바로 종료됨 😱&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DFOREGROUND&lt;/strong&gt; 옵션으로 실행하면 → Apache가 포그라운드에서 남아있어 컨테이너가 계속 실행됨 ✅&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="3-실행-예시"&gt;
 3️⃣ 실행 예시
 &lt;a class="heading-anchor" href="#3-%ec%8b%a4%ed%96%89-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 백그라운드(daemon) 실행&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;apache2 &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 포그라운드 실행 (DFOREGROUND)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;apache2 -D FOREGROUND&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;&lt;/code&gt; → 몰래 일하는 비밀 요원&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-D FOREGROUND&lt;/code&gt; → 무대 위 주인공&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="4-핵심-포인트"&gt;
 4️⃣ 핵심 포인트
 &lt;a class="heading-anchor" href="#4-%ed%95%b5%ec%8b%ac-%ed%8f%ac%ec%9d%b8%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;DFOREGROUND = Apache를 포그라운드에서 실행&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;주니어 개발자 기억법:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“백그라운드는 몰래 일하고, 포그라운드는 눈앞에서 바로 실행된다”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;도커/컨테이너 환경에서 컨테이너 종료 방지 + 로그 확인 가능&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;💡 &lt;strong&gt;Tip&lt;/strong&gt;:
컨테이너에서 항상 주 프로세스는 &lt;strong&gt;포그라운드&lt;/strong&gt;로 실행하는 것이 안전합니다.&lt;/p&gt;</description></item><item><title>[Kubernetes] 🔍 containerd OverlayFS 스냅샷 디스크 점유 컨테이너 추적하기</title><link>https://kyungryeol-yoon.github.io/kubernetes/storage/containerd-overlayfs-snapshot-disk-usage-troubleshooting/</link><pubDate>Tue, 11 May 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/storage/containerd-overlayfs-snapshot-disk-usage-troubleshooting/</guid><description>&lt;p&gt;이 글에서는 &lt;code&gt;/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/&lt;/code&gt; 하위의 특정 숫자 폴더가 수십 GB를 차지하는 상황에서, 어떤 Pod가 원인인지 찾아내는 과정을 다룹니다. Snapshot ID → Container ID → Pod Name 순서로 역추적하며, &lt;code&gt;crictl&lt;/code&gt;과 &lt;code&gt;kubectl&lt;/code&gt;을 중심으로 실무에서 바로 사용할 수 있는 명령어를 정리했습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-문제-상황-디스크-용량-경고"&gt;
 🚨 문제 상황: 디스크 용량 경고
 &lt;a class="heading-anchor" href="#-%eb%ac%b8%ec%a0%9c-%ec%83%81%ed%99%a9-%eb%94%94%ec%8a%a4%ed%81%ac-%ec%9a%a9%eb%9f%89-%ea%b2%bd%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;서버에 DiskPressure 경고가 발생했습니다. 원인을 추적하기 위해 &lt;code&gt;du&lt;/code&gt; 명령어로 용량을 확인합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 최상위 디렉토리별 용량 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;du -sh /var/lib/containerd/*
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 또는 커스텀 데이터 경로라면&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;du -sh /appdata/cri/*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;계속 파고들다 보면 아래와 같은 경로에서 특정 숫자 폴더가 수십 GB를 차지하는 것을 발견합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;du -sh /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/* &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; sort -rh &lt;span class="p"&gt;|&lt;/span&gt; head -20&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;38G /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/11773
2.1G /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/11201
...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이제 &lt;code&gt;11773&lt;/code&gt;이라는 스냅샷 폴더가 어느 컨테이너·Pod의 것인지 추적해야 합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-overlayfs와-snapshotter-개념-이해"&gt;
 🧩 OverlayFS와 Snapshotter 개념 이해
 &lt;a class="heading-anchor" href="#-overlayfs%ec%99%80-snapshotter-%ea%b0%9c%eb%85%90-%ec%9d%b4%ed%95%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;추적 방법을 이해하려면 containerd의 레이어 구조를 먼저 파악해야 합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;디렉토리&lt;/th&gt;
					&lt;th&gt;역할&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;lowerdir&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;읽기 전용 이미지 레이어 (Image Layer)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;upperdir&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;컨테이너의 쓰기 레이어 (Write Layer)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;workdir&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;OverlayFS 내부 임시 작업 디렉토리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;merged&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;lowerdir + upperdir를 합쳐 컨테이너에 보이는 최종 뷰&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;containerd의 &lt;strong&gt;Snapshotter&lt;/strong&gt;는 각 컨테이너 레이어를 숫자 ID로 관리합니다. 컨테이너가 실행되면 해당 컨테이너 전용 &lt;code&gt;upperdir&lt;/code&gt;가 스냅샷 폴더 안에 생성되며, 이 공간에 로그·임시 파일 등이 쌓입니다. 로그가 폭발하거나 임시 파일이 누수되면 스냅샷 폴더가 무한정 커지게 됩니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: &lt;code&gt;snapshots/&amp;lt;ID&amp;gt;/fs&lt;/code&gt;는 컨테이너의 실제 파일시스템(upperdir)입니다. 이 안에 파일이 쌓이면 해당 스냅샷의 크기가 증가합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-1단계-mount로-스냅샷-마운트-정보-확인"&gt;
 🛠️ 1단계: mount로 스냅샷 마운트 정보 확인
 &lt;a class="heading-anchor" href="#-1%eb%8b%a8%ea%b3%84-mount%eb%a1%9c-%ec%8a%a4%eb%83%85%ec%83%b7-%eb%a7%88%ec%9a%b4%ed%8a%b8-%ec%a0%95%eb%b3%b4-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;가장 먼저 시도할 수 있는 방법은 &lt;code&gt;mount&lt;/code&gt; 명령어로 해당 스냅샷 ID가 어떤 컨테이너에 마운트되어 있는지 확인하는 것입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;SNAPSHOT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;11773&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;mount &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="s2"&gt;&amp;#34;snapshots/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SNAPSHOT_ID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;결과 예시:&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;overlay on /run/containerd/io.containerd.runtime.v2.task/k8s.io/a3f2b1c0d4e5.../rootfs
type overlay (rw,relatime,lowerdir=.../11770/fs:.../11769/fs,
upperdir=.../11773/fs,workdir=.../11773/work)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;upperdir&lt;/code&gt; 경로 안에 컨테이너의 Task ID(해시값)가 포함되어 있습니다. 이 해시를 메모합니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ 컨테이너가 이미 종료된 경우 mount 결과에 나타나지 않을 수 있습니다. 이 경우 2단계로 넘어가세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-2단계-task-id로-컨테이너-찾기"&gt;
 🔎 2단계: Task ID로 컨테이너 찾기
 &lt;a class="heading-anchor" href="#-2%eb%8b%a8%ea%b3%84-task-id%eb%a1%9c-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%ec%b0%be%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;mount 결과에서 얻은 Task 해시로 컨테이너를 조회합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;TASK_HASH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;a3f2b1c0d4e5...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;ctr -n k8s.io c ls &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TASK_HASH&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;또는 &lt;code&gt;crictl&lt;/code&gt;을 사용합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;crictl ps -a &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TASK_HASH&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-3단계-crictl-inspect로-snapshot-id-역추적"&gt;
 🔑 3단계: crictl inspect로 Snapshot ID 역추적
 &lt;a class="heading-anchor" href="#-3%eb%8b%a8%ea%b3%84-crictl-inspect%eb%a1%9c-snapshot-id-%ec%97%ad%ec%b6%94%ec%a0%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;mount 결과 없이 스냅샷 ID만 알고 있을 때, &lt;code&gt;crictl inspect&lt;/code&gt;의 &lt;code&gt;snapshotKey&lt;/code&gt; 필드를 이용합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 모든 컨테이너를 순회하면서 스냅샷 ID 검색&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;crictl ps -a -q &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; CONTAINER_ID&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;RESULT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;crictl inspect &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CONTAINER_ID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="p"&gt;|&lt;/span&gt; grep -i &lt;span class="s2"&gt;&amp;#34;11773&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; -n &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RESULT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Found in container: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CONTAINER_ID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; crictl inspect &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CONTAINER_ID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep -E &lt;span class="s1"&gt;&amp;#39;&amp;#34;name&amp;#34;|&amp;#34;image&amp;#34;|snapshotKey&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;또는&lt;/strong&gt; &lt;code&gt;jq&lt;/code&gt;가 설치된 환경에서는 더 정확하게 추출할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;SNAPSHOT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;11773&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;crictl ps -a -q &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; CID&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;SNAP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;crictl inspect &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; jq -r &lt;span class="s1"&gt;&amp;#39;.info.runtimeSpec.annotations[&amp;#34;io.kubernetes.cri.sandbox-id&amp;#34;] // empty&amp;#39;&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;ROOTFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;crictl inspect &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; jq -r &lt;span class="s1"&gt;&amp;#39;.info.config.image.image // empty&amp;#39;&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; crictl inspect &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="p"&gt;|&lt;/span&gt; grep -q &lt;span class="s2"&gt;&amp;#34;snapshots/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SNAPSHOT_ID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Container ID : &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Image : &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ROOTFS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-4단계-container-id--pod-name-연결"&gt;
 🗂️ 4단계: Container ID → Pod Name 연결
 &lt;a class="heading-anchor" href="#-4%eb%8b%a8%ea%b3%84-container-id--pod-name-%ec%97%b0%ea%b2%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;컨테이너 ID를 찾았다면, 해당 컨테이너가 속한 Pod를 확인합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;CONTAINER_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;a3f2b1c0d4e5
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Pod ID(샌드박스 ID) 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;crictl inspect &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CONTAINER_ID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep -i sandbox
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Pod 상세 정보 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;crictl inspectp &amp;lt;POD_SANDBOX_ID&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;또는 &lt;code&gt;crictl ps&lt;/code&gt; 출력에서 직접 Pod 이름을 확인할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;crictl ps -a --output&lt;span class="o"&gt;=&lt;/span&gt;table &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CONTAINER_ID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;출력 예시:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD
a3f2b1c0d4e5 ... 2h ago Running app 0 b4c3d2e1 my-app-7d6f9b-xkpqr&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pod 이름을 확인했다면 &lt;code&gt;kubectl&lt;/code&gt;로 상세 정보를 조회합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pod my-app-7d6f9b-xkpqr -n &amp;lt;namespace&amp;gt; -o wide
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl describe pod my-app-7d6f9b-xkpqr -n &amp;lt;namespace&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-5단계-스냅샷-내부-파일-확인"&gt;
 🔬 5단계: 스냅샷 내부 파일 확인
 &lt;a class="heading-anchor" href="#-5%eb%8b%a8%ea%b3%84-%ec%8a%a4%eb%83%85%ec%83%b7-%eb%82%b4%eb%b6%80-%ed%8c%8c%ec%9d%bc-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;어떤 파일이 용량을 점유하는지 직접 확인합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 스냅샷의 upperdir(실제 컨테이너 쓰기 레이어) 탐색&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;ls -lh /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/11773/fs/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 하위 디렉토리별 용량 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;du -sh /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/11773/fs/* &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; sort -rh &lt;span class="p"&gt;|&lt;/span&gt; head -20&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;대부분의 경우 다음 경로에서 파일이 폭증합니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/var/log/ ← 애플리케이션 로그 누수
/tmp/ ← 임시 파일 누수
/var/cache/ ← 캐시 파일 미정리&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="-해결-방법"&gt;
 ✅ 해결 방법
 &lt;a class="heading-anchor" href="#-%ed%95%b4%ea%b2%b0-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="범인-pod-재시작-또는-삭제"&gt;
 범인 Pod 재시작 또는 삭제
 &lt;a class="heading-anchor" href="#%eb%b2%94%ec%9d%b8-pod-%ec%9e%ac%ec%8b%9c%ec%9e%91-%eb%98%90%eb%8a%94-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Pod 재시작 (Deployment 등 상위 오브젝트가 있을 경우)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubectl rollout restart deployment/&amp;lt;deployment-name&amp;gt; -n &amp;lt;namespace&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Pod 직접 삭제 (ReplicaSet이 새 Pod를 생성)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;kubectl delete pod my-app-7d6f9b-xkpqr -n &amp;lt;namespace&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;code&gt;rm -rf snapshots/11773&lt;/code&gt; 같은 직접 삭제는 절대 하지 마세요. containerd 런타임 메타데이터와 불일치가 발생해 노드가 불안정해질 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="미사용-이미지컨테이너-정리"&gt;
 미사용 이미지·컨테이너 정리
 &lt;a class="heading-anchor" href="#%eb%af%b8%ec%82%ac%ec%9a%a9-%ec%9d%b4%eb%af%b8%ec%a7%80%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 종료된 컨테이너 조회 및 삭제&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;crictl ps -a --state exited
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;crictl rm &lt;span class="k"&gt;$(&lt;/span&gt;crictl ps -a --state exited -q&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 미사용 이미지 정리&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;crictl rmi --prune
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ctr를 이용한 정리 (24시간 이상 미사용)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;ctr -n k8s.io images prune --all-unused --older-than 24h
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 스냅샷 정리&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;ctr -n k8s.io snapshots prune&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="애플리케이션-로그-로테이션-설정"&gt;
 애플리케이션 로그 로테이션 설정
 &lt;a class="heading-anchor" href="#%ec%95%a0%ed%94%8c%eb%a6%ac%ec%bc%80%ec%9d%b4%ec%85%98-%eb%a1%9c%ea%b7%b8-%eb%a1%9c%ed%85%8c%ec%9d%b4%ec%85%98-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;컨테이너 내부에서 로그가 쌓인다면 애플리케이션의 로그 로테이션을 설정합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Deployment에 컨테이너 로그 크기 제한 추가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# ...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ephemeral-storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2Gi&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 임시 스토리지 상한 설정&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-예방-kubelet-gc-및-containerd-gc-설정"&gt;
 🛡️ 예방: Kubelet GC 및 containerd GC 설정
 &lt;a class="heading-anchor" href="#-%ec%98%88%eb%b0%a9-kubelet-gc-%eb%b0%8f-containerd-gc-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="kubelet-이미지-gc-설정"&gt;
 Kubelet 이미지 GC 설정
 &lt;a class="heading-anchor" href="#kubelet-%ec%9d%b4%eb%af%b8%ec%a7%80-gc-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/var/lib/kubelet/config.yaml&lt;/code&gt;에 다음 항목을 추가합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;imageGCHighThresholdPercent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;85&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 85% 초과 시 GC 시작&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;imageGCLowThresholdPercent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 80%까지 정리&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="containerd-주기적-gc-설정"&gt;
 containerd 주기적 GC 설정
 &lt;a class="heading-anchor" href="#containerd-%ec%a3%bc%ea%b8%b0%ec%a0%81-gc-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/etc/containerd/config.toml&lt;/code&gt;에 GC 스케줄러를 설정합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;io.containerd.gc.v1.scheduler&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;pause_threshold&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.02&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;deletion_threshold&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;mutation_threshold&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;schedule_delay&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;0s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;startup_delay&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;100ms&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="디스크-사용량-모니터링"&gt;
 디스크 사용량 모니터링
 &lt;a class="heading-anchor" href="#%eb%94%94%ec%8a%a4%ed%81%ac-%ec%82%ac%ec%9a%a9%eb%9f%89-%eb%aa%a8%eb%8b%88%ed%84%b0%eb%a7%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Prometheus를 사용한다면 &lt;code&gt;node_filesystem_avail_bytes&lt;/code&gt; 메트릭에 알람을 설정하여 DiskPressure 이전에 조치를 취할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# PrometheusRule 예시&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NodeDiskPressureWarning&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; node_filesystem_avail_bytes{mountpoint=&amp;#34;/var/lib/containerd&amp;#34;} /
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; node_filesystem_size_bytes{mountpoint=&amp;#34;/var/lib/containerd&amp;#34;} &amp;lt; 0.15&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;5m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;containerd 디스크 여유 공간 15% 미만&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-스냅샷-폴더를-직접-rm--rf-해도-되나요"&gt;
 Q. 스냅샷 폴더를 직접 rm -rf 해도 되나요?
 &lt;a class="heading-anchor" href="#q-%ec%8a%a4%eb%83%85%ec%83%b7-%ed%8f%b4%eb%8d%94%eb%a5%bc-%ec%a7%81%ec%a0%91-rm--rf-%ed%95%b4%eb%8f%84-%eb%90%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;안 됩니다. containerd는 내부 bolt DB(&lt;code&gt;meta.db&lt;/code&gt;)에 스냅샷 메타데이터를 관리합니다. 파일만 삭제하면 DB와 불일치가 발생해 containerd가 오작동하거나 노드가 NotReady 상태가 될 수 있습니다. 반드시 &lt;code&gt;crictl rm&lt;/code&gt;, &lt;code&gt;ctr snapshots rm&lt;/code&gt; 등 런타임 도구를 사용하세요.&lt;/p&gt;
&lt;h3 id="q-mount--grep-으로-아무것도-안-나올-때는요"&gt;
 Q. mount | grep 으로 아무것도 안 나올 때는요?
 &lt;a class="heading-anchor" href="#q-mount--grep-%ec%9c%bc%eb%a1%9c-%ec%95%84%eb%ac%b4%ea%b2%83%eb%8f%84-%ec%95%88-%eb%82%98%ec%98%ac-%eb%95%8c%eb%8a%94%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;컨테이너가 이미 종료된 경우입니다. &lt;code&gt;crictl ps -a&lt;/code&gt;로 종료된 컨테이너까지 포함하여 확인하거나, &lt;code&gt;ctr -n k8s.io snapshots info &amp;lt;snapshot-key&amp;gt;&lt;/code&gt;로 스냅샷 메타데이터를 직접 조회해 보세요.&lt;/p&gt;
&lt;h3 id="q-ctr와-crictl-중-어떤-것을-써야-하나요"&gt;
 Q. ctr와 crictl 중 어떤 것을 써야 하나요?
 &lt;a class="heading-anchor" href="#q-ctr%ec%99%80-crictl-%ec%a4%91-%ec%96%b4%eb%96%a4-%ea%b2%83%ec%9d%84-%ec%8d%a8%ec%95%bc-%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Kubernetes 환경에서는 &lt;strong&gt;crictl&lt;/strong&gt;을 권장합니다. crictl은 CRI(Container Runtime Interface)를 통해 Kubernetes Pod·컨테이너 정보와 연동되므로, Pod 이름 등 상위 정보를 얻기 쉽습니다. ctr는 containerd 네이티브 CLI로, Kubernetes 메타데이터 없이 더 로우레벨 접근이 필요할 때 사용합니다.&lt;/p&gt;
&lt;h3 id="q-ephemeral-storage-제한을-걸면-pod가-evict되지-않나요"&gt;
 Q. ephemeral-storage 제한을 걸면 Pod가 Evict되지 않나요?
 &lt;a class="heading-anchor" href="#q-ephemeral-storage-%ec%a0%9c%ed%95%9c%ec%9d%84-%ea%b1%b8%eb%a9%b4-pod%ea%b0%80-evict%eb%90%98%ec%a7%80-%ec%95%8a%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;맞습니다. 설정한 상한을 초과하면 kubelet이 해당 Pod를 evict합니다. 이는 단일 Pod의 무제한 디스크 점유로 노드 전체가 DiskPressure에 빠지는 것을 막아주는 안전장치입니다. limits는 넉넉하게, requests는 실제 사용량 기준으로 설정하는 것을 권장합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📚 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/containerd/containerd/discussions/10053"&gt;Find who own overlayfs snapshots/NN - containerd/containerd Discussion #10053&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3tutorials.net/blog/is-it-possible-to-shrink-the-spaces-of-io-containerd-snapshotter-v1-overlayfs-folder-in-kubernetes/"&gt;How to Shrink the io.containerd.snapshotter.v1.overlayfs Folder in Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/tasks/debug/debug-cluster/crictl/"&gt;Debugging Kubernetes nodes with crictl - Kubernetes Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hexshift.medium.com/containerd-snapshotters-explained-overlayfs-native-and-more-a944c503beec"&gt;containerd Snapshotters Explained: Overlayfs, Native, and More&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jinha4ever/overlay-filesystem-and-its-use-in-container-runtime-693eba88a2a7"&gt;Overlay Filesystem and Its Use in Container Runtime&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes-sigs/kubespray/issues/10195"&gt;Large containerd Snapshot Directories and Cleanup Assistance - kubespray Issue #10195&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Docker] Docker Image Save &amp; Load, Export &amp; Import</title><link>https://kyungryeol-yoon.github.io/docker/docker-image-save-load-export-import/</link><pubDate>Sun, 02 May 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/docker/docker-image-save-load-export-import/</guid><description>&lt;ul&gt;
&lt;li&gt;Docker를 tar 파일로 저장하는 데는 save, export 두 가지 명령어가 있다.&lt;/li&gt;
&lt;li&gt;추출한 tar 파일을 Docker Image로 저장하는 데는 load, import 두 가지 명령어가 있다.&lt;/li&gt;
&lt;li&gt;save로 저장한 tar 파일은 load를 사용하고, export로 저장한 tar 파일은 import를 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="docker-save-docer-image--tar-file"&gt;
 Docker save (docer image → tar file)
 &lt;a class="heading-anchor" href="#docker-save-docer-image--tar-file" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;저장할 파일명을 지정하는 옵션은 -o 를 사용한다&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker save &lt;span class="o"&gt;[&lt;/span&gt;옵션&lt;span class="o"&gt;]&lt;/span&gt; &amp;lt;파일명&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt;Image명&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker save -o file_name.tar image_name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker save -o &lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;/test-api.tar test-api:latest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo docker save -o &lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;/mongo.tar mongo:4.2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo docker save -o &lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;/redis.tar redis:7.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;sudo docker save -o &lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;/mysql.tar mysql:8.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="docker-load-tar-file--docker-image"&gt;
 Docker load (tar file → docker image)
 &lt;a class="heading-anchor" href="#docker-load-tar-file--docker-image" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;tar파일로 만들어진 Image를 다시 docker image로 되돌리기 위해서는 docker load Command를 사용한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker load -i &lt;span class="o"&gt;[&lt;/span&gt;tar 파일명&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker load -i file_name.tar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker load -i test-api.tar &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo docker load -i mongo.tar &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo docker load -i mysql.tar &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo docker load -i redis.tar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="docker-export-docker-container--tar-file"&gt;
 Docker export (docker container → tar file)
 &lt;a class="heading-anchor" href="#docker-export-docker-container--tar-file" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;docker는 Image 뿐 아니라 container를 tar파일로 저장하는 명령어를 제공한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker &lt;span class="nb"&gt;export&lt;/span&gt; &amp;lt;Container Name or Container ID&amp;gt; &amp;gt; &lt;span class="o"&gt;[&lt;/span&gt;tar 파일명&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker &lt;span class="nb"&gt;export&lt;/span&gt; -o file_name.tar image_name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="docker-import-tar-file--docker-image"&gt;
 Docker import (tar file → docker image)
 &lt;a class="heading-anchor" href="#docker-import-tar-file--docker-image" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;export Command를 통해 만들어진 tar 파일을 다시 docker image로 생성하는 명령어이다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker import &amp;lt;파일 or URL&amp;gt; - &lt;span class="o"&gt;[&lt;/span&gt;image name&lt;span class="o"&gt;[&lt;/span&gt;:tag name&lt;span class="o"&gt;]]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker import file_name.tar image_name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;root 권한으로 실행하지 않을 경우, 액세스 권한이 없는 파일들이 포함되지 않는 문제가 발생할 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="export--import-와-save--load의-차이"&gt;
 Export &amp;amp; Import 와 Save &amp;amp; Load의 차이
 &lt;a class="heading-anchor" href="#export--import-%ec%99%80-save--load%ec%9d%98-%ec%b0%a8%ec%9d%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;docker export의 경우 Container를 동작하는데 필요한 모든 파일이 압축된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;즉, tar파일에 Container의 Root 파일시스템 전체가 들어있는 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;반면에 docker save는 Layer 구조까지 포함한 형태로 압축이 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;즉, 기반이 되는 Image가 같더라도 export와 save는 압축되는 파일 구조와 Directory가 다르다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;결론은 export를 통해 생성한 tar 파일은 import로, save로 생성한 파일은 load로 Image화 해야 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Docker-Compose] Install Gitlab(17.7.0)</title><link>https://kyungryeol-yoon.github.io/devops/gitlab/docker-compose-gitlab17.7.0/</link><pubDate>Sun, 11 Apr 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/gitlab/docker-compose-gitlab17.7.0/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/docker-install-compose(1.27.4)/"&gt;Docker-Compose 설치 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="gitlab-docker-이미지"&gt;
 GitLab Docker 이미지
 &lt;a class="heading-anchor" href="#gitlab-docker-%ec%9d%b4%eb%af%b8%ec%a7%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GitLab Docker Image는 단일 Container에서 필요한 모든 서비스를 실행하는 GitLab의 모놀리식(Monolithic) Image
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://hub.docker.com/r/gitlab/gitlab-ce/"&gt;GitLab CE Docker image&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hub.docker.com/r/gitlab/gitlab-ee/"&gt;GitLab EE Docker image&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="설치-directory-생성"&gt;
 설치 Directory 생성
 &lt;a class="heading-anchor" href="#%ec%84%a4%ec%b9%98-directory-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo mkdir -p /data/gitlab &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; /data/gitlab
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo mkdir data logs config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;data&lt;/code&gt; (&lt;code&gt;/var/opt/gitlab&lt;/code&gt;) : 애플리케이션 데이터 저장용&lt;/li&gt;
&lt;li&gt;&lt;code&gt;logs&lt;/code&gt; (&lt;code&gt;/var/log/gitlab&lt;/code&gt;) : 로그 저장용&lt;/li&gt;
&lt;li&gt;&lt;code&gt;config&lt;/code&gt; (&lt;code&gt;/etc/gitlab&lt;/code&gt;) : GitLab 구성 파일 저장용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="gitlab-directory의-소유권을-user로-변경"&gt;
 Gitlab Directory의 소유권을 $USER로 변경
 &lt;a class="heading-anchor" href="#gitlab-directory%ec%9d%98-%ec%86%8c%ec%9c%a0%ea%b6%8c%ec%9d%84-user%eb%a1%9c-%eb%b3%80%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo chown -R &lt;span class="nv"&gt;$USER&lt;/span&gt;:&lt;span class="nv"&gt;$USER&lt;/span&gt; /data/gitlab&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="권한을-변경"&gt;
 권한을 변경
 &lt;a class="heading-anchor" href="#%ea%b6%8c%ed%95%9c%ec%9d%84-%eb%b3%80%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo chmod -R &lt;span class="m"&gt;755&lt;/span&gt; /data/gitlab&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="docker-composeyml-or-docker-compose_gitlab-파일-준비"&gt;
 &lt;code&gt;docker-compose.yml&lt;/code&gt; or &lt;code&gt;docker-compose_gitlab&lt;/code&gt; 파일 준비
 &lt;a class="heading-anchor" href="#docker-composeyml-or-docker-compose_gitlab-%ed%8c%8c%ec%9d%bc-%ec%a4%80%eb%b9%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;GitLab 작업 Directory(예: &lt;code&gt;/data/gitlab/&lt;/code&gt;)에 &lt;code&gt;docker-compose.yml&lt;/code&gt; 파일을 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi docker-compose.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;hostname&lt;/code&gt;과 &lt;code&gt;external_url&lt;/code&gt;은 설치할 서버의 IP 또는 도메인으로 반드시 수정&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;3.9&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;gitlab&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;gitlab/gitlab-ce:17.7.0-ce.0&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;or &amp;#39;gitlab/gitlab-ee:17.7.0-ee.0&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gitlab&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;always&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;gitlab.local&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;GITLAB_OMNIBUS_CONFIG&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; external_url &amp;#39;http://192.168.0.54:80&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # gitlab_rails[&amp;#39;gitlab_shell_ssh_port&amp;#39;] = 8022
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # Add any other gitlab.rb configuration here, each on its own line&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;TZ&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Asia/Seoul&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s1"&gt;&amp;#39;80:80&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s1"&gt;&amp;#39;443:443&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s1"&gt;&amp;#39;10022:22&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s1"&gt;&amp;#39;./.gitlab/config:/etc/gitlab&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s1"&gt;&amp;#39;./.gitlab/logs:/var/log/gitlab&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s1"&gt;&amp;#39;./.gitlab/data:/var/opt/gitlab&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# networks:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# - gitlab_net&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# networks:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# gitlab_net:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# driver: bridge&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="gitlab-시작"&gt;
 GitLab 시작
 &lt;a class="heading-anchor" href="#gitlab-%ec%8b%9c%ec%9e%91" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;아래 명령어 실행 (작업 Directory에 파일이 있는지 확인)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker-compose up -d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker-compose -f docker-compose-gitlab.yml up -d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="gitlab-구동-로그를-확인"&gt;
 GitLab 구동 로그를 확인
 &lt;a class="heading-anchor" href="#gitlab-%ea%b5%ac%eb%8f%99-%eb%a1%9c%ea%b7%b8%eb%a5%bc-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker-compose logs -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="docker-container-목록-확인"&gt;
 Docker Container 목록 확인
 &lt;a class="heading-anchor" href="#docker-container-%eb%aa%a9%eb%a1%9d-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker-compose ps&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker ps -a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="gitlab-root-계정의-초기-패스워드를-확인"&gt;
 GitLab &lt;code&gt;root&lt;/code&gt; 계정의 초기 패스워드를 확인
 &lt;a class="heading-anchor" href="#gitlab-root-%ea%b3%84%ec%a0%95%ec%9d%98-%ec%b4%88%ea%b8%b0-%ed%8c%a8%ec%8a%a4%ec%9b%8c%eb%93%9c%eb%a5%bc-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; -it gitlab grep &lt;span class="s1"&gt;&amp;#39;Password:&amp;#39;&lt;/span&gt; /etc/gitlab/initial_root_password&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cat initial_root_password&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="root-관리자-암호-변경command"&gt;
 root 관리자 암호 변경(command)
 &lt;a class="heading-anchor" href="#root-%ea%b4%80%eb%a6%ac%ec%9e%90-%ec%95%94%ed%98%b8-%eb%b3%80%ea%b2%bdcommand" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo docker &lt;span class="nb"&gt;exec&lt;/span&gt; -ti gitlab /bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;root@gitlab:/# gitlab-rake &lt;span class="s2"&gt;&amp;#34;gitlab:password:reset&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;Enter username: root
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;Enter password: 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;Confirm password:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;Password successfully updated &lt;span class="k"&gt;for&lt;/span&gt; user with username root.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/docker-install-gitlab-runner/"&gt;Docker Gitlab Runner 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/kubernetes-install-gitlab-runner-using-helm/"&gt;Kubernetes Gitlab Runner 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Docker] Permission Denied 발생하는 경우</title><link>https://kyungryeol-yoon.github.io/docker/docker-permission-denied/</link><pubDate>Thu, 11 Mar 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/docker/docker-permission-denied/</guid><description>&lt;h2 id="docker-설치-후-varrundockersock의-permission-denied-발생하는-경우"&gt;
 docker 설치 후 /var/run/docker.sock의 permission denied 발생하는 경우
 &lt;a class="heading-anchor" href="#docker-%ec%84%a4%ec%b9%98-%ed%9b%84-varrundockersock%ec%9d%98-permission-denied-%eb%b0%9c%ec%83%9d%ed%95%98%eb%8a%94-%ea%b2%bd%ec%9a%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker ps -a
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;Got permission denied &lt;span class="k"&gt;while&lt;/span&gt; trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/json?all&lt;span class="o"&gt;=&lt;/span&gt;1: dial unix /var/run/docker.sock: connect: permission denied&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="해결"&gt;
 해결
 &lt;a class="heading-anchor" href="#%ed%95%b4%ea%b2%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/var/run/docker.sock&lt;/code&gt; 파일의 권한을 666으로 변경하여 그룹 내 다른 사용자도 접근 가능하게 변경&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo chmod &lt;span class="m"&gt;666&lt;/span&gt; /var/run/docker.sock&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;또는 chown 으로 group ownership 변경&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo chown root:docker /var/run/docker.sock&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] kubeadm으로 마스터 노드 고가용성(HA) 클러스터 구축하기(Docker)</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubernetes-high-availability-kubeadm-docker/</link><pubDate>Sat, 06 Mar 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubernetes-high-availability-kubeadm-docker/</guid><description>&lt;h2 id="-1-클러스터-구성-및-아키텍처"&gt;
 🏗️ 1. 클러스터 구성 및 아키텍처
 &lt;a class="heading-anchor" href="#-1-%ed%81%b4%eb%9f%ac%ec%8a%a4%ed%84%b0-%ea%b5%ac%ec%84%b1-%eb%b0%8f-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;본 가이드는 마스터 노드 안에 etcd를 함께 배포하는 &lt;strong&gt;Stacked etcd&lt;/strong&gt; 방식을 사용합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Load Balancer (VIP)&lt;/strong&gt;: HAProxy + Keepalived (대표 IP: &lt;code&gt;192.168.0.100&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Master Nodes&lt;/strong&gt;: 최소 3대 권장 (홀수 구성)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Worker Nodes&lt;/strong&gt;: 실제 서비스가 구동될 노드들&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-2-사전-준비-모든-노드-공통"&gt;
 ⚙️ 2. 사전 준비 (모든 노드 공통)
 &lt;a class="heading-anchor" href="#-2-%ec%82%ac%ec%a0%84-%ec%a4%80%eb%b9%84-%eb%aa%a8%eb%93%a0-%eb%85%b8%eb%93%9c-%ea%b3%b5%ed%86%b5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;모든 노드(마스터, 워커, 로드밸런서)에서 기본적인 시스템 설정을 진행합니다.&lt;/p&gt;
&lt;h3 id="21-swap-및-방화벽-설정-"&gt;
 2.1 Swap 및 방화벽 설정 🛑
 &lt;a class="heading-anchor" href="#21-swap-%eb%b0%8f-%eb%b0%a9%ed%99%94%eb%b2%bd-%ec%84%a4%ec%a0%95-" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Swap 비활성화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo swapoff -a
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo sed -i &lt;span class="s1"&gt;&amp;#39;/swap/s/^/#/&amp;#39;&lt;/span&gt; /etc/fstab
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 방화벽 해제 (학습용 환경 기준)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;sudo ufw disable&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="22-커널-모듈-및-네트워크-브리지-설정"&gt;
 2.2 커널 모듈 및 네트워크 브리지 설정
 &lt;a class="heading-anchor" href="#22-%ec%bb%a4%eb%84%90-%eb%aa%a8%eb%93%88-%eb%b0%8f-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac-%eb%b8%8c%eb%a6%ac%ec%a7%80-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF | sudo tee /etc/modules-load.d/k8s.conf
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;br_netfilter
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;sudo modprobe br_netfilter
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF | sudo tee /etc/sysctl.d/k8s.conf
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;net.bridge.bridge-nf-call-ip6tables = 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;net.bridge.bridge-nf-call-iptables = 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;net.ipv4.ip_forward = 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;sudo sysctl --system&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-3-docker-설치-및-cgroup-driver-설정"&gt;
 📦 3. Docker 설치 및 Cgroup Driver 설정
 &lt;a class="heading-anchor" href="#-3-docker-%ec%84%a4%ec%b9%98-%eb%b0%8f-cgroup-driver-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;쿠버네티스와 Docker의 자원 관리 방식(Cgroup)을 일치시키는 것이 매우 중요합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Docker 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt-get install -y docker.io
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 🚨 중요: Docker Cgroup Driver를 systemd로 변경&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# K8s 1.22 버전 이상부터는 systemd가 기본이자 권장사항입니다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF | sudo tee /etc/docker/daemon.json
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;exec-opts&amp;#34;: [&amp;#34;native.cgroupdriver=systemd&amp;#34;],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;log-driver&amp;#34;: &amp;#34;json-file&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;log-opts&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;max-size&amp;#34;: &amp;#34;100m&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;storage-driver&amp;#34;: &amp;#34;overlay2&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl restart docker&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-4-로드밸런서lb-구성-lb-노드"&gt;
 ⚖️ 4. 로드밸런서(LB) 구성 (LB 노드)
 &lt;a class="heading-anchor" href="#-4-%eb%a1%9c%eb%93%9c%eb%b0%b8%eb%9f%b0%ec%84%9clb-%ea%b5%ac%ec%84%b1-lb-%eb%85%b8%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;마스터 노드들의 API Server(6443 포트)로 트래픽을 분산해 줄 &lt;strong&gt;HAProxy&lt;/strong&gt;를 설정합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;/etc/haproxy/haproxy.cfg&lt;/code&gt; 설정:&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-haproxy" data-lang="haproxy"&gt;frontend k8s-api
 bind *:6443
 mode tcp
 default_backend k8s-api-nodes

backend k8s-api-nodes
 mode tcp
 balance roundrobin
 server master1 192.168.0.11:6443 check
 server master2 192.168.0.12:6443 check
 server master3 192.168.0.13:6443 check&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="-5-클러스터-초기화-첫-번째-마스터"&gt;
 🚩 5. 클러스터 초기화 (첫 번째 마스터)
 &lt;a class="heading-anchor" href="#-5-%ed%81%b4%eb%9f%ac%ec%8a%a4%ed%84%b0-%ec%b4%88%ea%b8%b0%ed%99%94-%ec%b2%ab-%eb%b2%88%ec%a7%b8-%eb%a7%88%ec%8a%a4%ed%84%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="-주의-vip-설정을-절대-빠뜨리지-마세요"&gt;
 ⚠️ [주의] VIP 설정을 절대 빠뜨리지 마세요!
 &lt;a class="heading-anchor" href="#-%ec%a3%bc%ec%9d%98-vip-%ec%84%a4%ec%a0%95%ec%9d%84-%ec%a0%88%eb%8c%80-%eb%b9%a0%eb%9c%a8%eb%a6%ac%ec%a7%80-%eb%a7%88%ec%84%b8%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;고가용성 클러스터의 핵심은 모든 노드가 &lt;strong&gt;로드밸런서의 VIP&lt;/strong&gt;를 바라보게 하는 것입니다. &lt;code&gt;--control-plane-endpoint&lt;/code&gt; 옵션을 &lt;strong&gt;빠뜨리면(누락하면)&lt;/strong&gt; HA 구성이 무의미해집니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 첫 번째 마스터에서 실행 (VIP 주소 사용)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm init &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; --control-plane-endpoint &lt;span class="s2"&gt;&amp;#34;192.168.0.100:6443&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; --upload-certs &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; --pod-network-cidr&lt;span class="o"&gt;=&lt;/span&gt;10.244.0.0/16&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;성공 시 화면에 나타나는 &lt;code&gt;kubeadm join ... --control-plane&lt;/code&gt; 명령어를 복사해 두세요. ✨&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-6-마스터-및-워커-노드-조인-join"&gt;
 🤝 6. 마스터 및 워커 노드 조인 (Join)
 &lt;a class="heading-anchor" href="#-6-%eb%a7%88%ec%8a%a4%ed%84%b0-%eb%b0%8f-%ec%9b%8c%ec%bb%a4-%eb%85%b8%eb%93%9c-%ec%a1%b0%ec%9d%b8-join" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="61-추가-마스터-노드-master-2-3"&gt;
 6.1 추가 마스터 노드 (Master 2, 3)
 &lt;a class="heading-anchor" href="#61-%ec%b6%94%ea%b0%80-%eb%a7%88%ec%8a%a4%ed%84%b0-%eb%85%b8%eb%93%9c-master-2-3" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;복사해둔 명령어에 &lt;code&gt;--control-plane&lt;/code&gt; 옵션이 포함되어 있는지 확인 후 실행합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm join 192.168.0.100:6443 --token &amp;lt;TOKEN&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; --discovery-token-ca-cert-hash sha256:&amp;lt;HASH&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; --control-plane --certificate-key &amp;lt;KEY&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="62-워커-노드-worker"&gt;
 6.2 워커 노드 (Worker)
 &lt;a class="heading-anchor" href="#62-%ec%9b%8c%ec%bb%a4-%eb%85%b8%eb%93%9c-worker" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;일반 조인 명령어를 실행합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm join 192.168.0.100:6443 --token &amp;lt;TOKEN&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; --discovery-token-ca-cert-hash sha256:&amp;lt;HASH&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-7-최종-상태-확인"&gt;
 ✅ 7. 최종 상태 확인
 &lt;a class="heading-anchor" href="#-7-%ec%b5%9c%ec%a2%85-%ec%83%81%ed%83%9c-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;모든 설정이 끝났습니다. 마스터 노드에서 전체 노드 상태를 확인합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get nodes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;STATUS&lt;/strong&gt;가 모두 &lt;code&gt;Ready&lt;/code&gt;라면, Docker 기반의 견고한 HA 클러스터 구축이 완료되었습니다! 🎉&lt;/p&gt;
&lt;h3 id="-요약-포인트"&gt;
 💡 요약 포인트:
 &lt;a class="heading-anchor" href="#-%ec%9a%94%ec%95%bd-%ed%8f%ac%ec%9d%b8%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Docker 설치 후 &lt;strong&gt;Systemd Cgroup Driver&lt;/strong&gt; 설정은 필수입니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kubeadm init&lt;/code&gt; 시 &lt;strong&gt;로드밸런서 VIP&lt;/strong&gt;를 &lt;strong&gt;빠뜨리지 말아야&lt;/strong&gt; 진정한 고가용성이 구현됩니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--upload-certs&lt;/code&gt; 옵션은 마스터 노드 간 인증서 공유를 아주 편하게 해줍니다.&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>[Docker-Compose] Install Docker-Compose(1.27.4)</title><link>https://kyungryeol-yoon.github.io/docker/install-docker-compose1.27.4/</link><pubDate>Tue, 02 Feb 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/docker/install-docker-compose1.27.4/</guid><description>&lt;h2 id="docker-compose-설치하기"&gt;
 Docker-Compose 설치하기
 &lt;a class="heading-anchor" href="#docker-compose-%ec%84%a4%ec%b9%98%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;curl 명령어를 통해 Docker-Compose를 설치
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo curl -L &lt;span class="s2"&gt;&amp;#34;https://github.com/docker/compose/releases/download/1.27.4/docker-compose-&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;uname -s&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;uname -m&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -o /usr/local/bin/docker-compose&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;다른 버전을 다운로드하고 싶을 경우, &lt;a href="https://github.com/docker/compose/releases"&gt;GitHub에서 버전 확인&lt;/a&gt; 후 다운로드
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="다운로드한-docker-compose-파일을-실행-가능하도록-다운로드한-경로에-권한을-부여"&gt;
 다운로드한 Docker-Compose 파일을 실행 가능하도록 다운로드한 경로에 권한을 부여
 &lt;a class="heading-anchor" href="#%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c%ed%95%9c-docker-compose-%ed%8c%8c%ec%9d%bc%ec%9d%84-%ec%8b%a4%ed%96%89-%ea%b0%80%eb%8a%a5%ed%95%98%eb%8f%84%eb%a1%9d-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c%ed%95%9c-%ea%b2%bd%eb%a1%9c%ec%97%90-%ea%b6%8c%ed%95%9c%ec%9d%84-%eb%b6%80%ec%97%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo chmod +x /usr/local/bin/docker-compose&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="심볼릭-링크-설정으로-path-경로를-아래와-같이-설정"&gt;
 심볼릭 링크 설정으로 path 경로를 아래와 같이 설정
 &lt;a class="heading-anchor" href="#%ec%8b%ac%eb%b3%bc%eb%a6%ad-%eb%a7%81%ed%81%ac-%ec%84%a4%ec%a0%95%ec%9c%bc%eb%a1%9c-path-%ea%b2%bd%eb%a1%9c%eb%a5%bc-%ec%95%84%eb%9e%98%ec%99%80-%ea%b0%99%ec%9d%b4-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="정상적으로-설치되었는지-확인"&gt;
 정상적으로 설치되었는지 확인
 &lt;a class="heading-anchor" href="#%ec%a0%95%ec%83%81%ec%a0%81%ec%9c%bc%eb%a1%9c-%ec%84%a4%ec%b9%98%eb%90%98%ec%97%88%eb%8a%94%ec%a7%80-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker-compose -v&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Docker] Dangling Image란? (Build 후 Repository:Tag 가 none 인 경우)</title><link>https://kyungryeol-yoon.github.io/docker/docker-dangling-image/</link><pubDate>Sat, 23 Jan 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/docker/docker-dangling-image/</guid><description>&lt;h2 id="dangling-images"&gt;
 Dangling Images
 &lt;a class="heading-anchor" href="#dangling-images" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Image를 사용중인 Container가 존재할 때 아래와 같이 docker rmi 명령어로 Image를 지우려 하면 다음과 같은 에러가 뜬다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker rmi &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;Error response from daemon: conflict: unable to remove repository reference &lt;span class="s2"&gt;&amp;#34;test&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;must force&lt;span class="o"&gt;)&lt;/span&gt; - container 8bd39093b5cf is using its referenced image 83f310aba04a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Image를 사용 중인 Container가 존재하므로 해당 Image를 삭제할 수 없다는 내용이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;보통의 경우 Container를 먼저 삭제한 후 Image를 삭제한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이 경우 Image Layer 파일까지 삭제되는데, Image를 사용중인 Container가 있는 상황에서 -f 옵션을 추가해 Image를 강제로 삭제하게 되면 Image Layer 파일을 실제로 삭제하지 않고 Image 이름만 삭제하게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이를 Dangling Image 라고 부른다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="docker-rmi--f-명령어로-image를-강제로-삭제"&gt;
 &lt;code&gt;docker rmi -f&lt;/code&gt; 명령어로 Image를 강제로 삭제
 &lt;a class="heading-anchor" href="#docker-rmi--f-%eb%aa%85%eb%a0%b9%ec%96%b4%eb%a1%9c-image%eb%a5%bc-%ea%b0%95%ec%a0%9c%eb%a1%9c-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker rmi -f &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;Untagged: test:latest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="docker-images-명령어로-image의-상태를-확인"&gt;
 &lt;code&gt;docker images&lt;/code&gt; 명령어로 Image의 상태를 확인
 &lt;a class="heading-anchor" href="#docker-images-%eb%aa%85%eb%a0%b9%ec%96%b4%eb%a1%9c-image%ec%9d%98-%ec%83%81%ed%83%9c%eb%a5%bc-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker images
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;REPOSITORY TAG IMAGE ID CREATED SIZE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&amp;lt;none&amp;gt; &amp;lt;none&amp;gt; 83f310aba04a &lt;span class="m"&gt;4&lt;/span&gt; hours ago 910MB&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;이처럼 Container가 사용 중인 Image를 강제로 삭제하면 Image의 이름이 &lt;none&gt;으로 변겅되며, 이를 Dangling Image라 부른다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dangling Image는 다음과 같은 명령어를 사용해 별도로 확인할 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker images -f &lt;span class="nv"&gt;dangling&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;REPOSITORY TAG IMAGE ID CREATED SIZE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&amp;lt;none&amp;gt; &amp;lt;none&amp;gt; 83f310aba04a &lt;span class="m"&gt;4&lt;/span&gt; hours ago 910MB&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="solution-1-docker-system-prune"&gt;
 Solution 1. docker system prune
 &lt;a class="heading-anchor" href="#solution-1-docker-system-prune" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;[OPTIONS] &lt;code&gt;--a&lt;/code&gt;, &lt;code&gt;-a&lt;/code&gt;	: dangling된 것 뿐만 아니라, 모든 사용하지않는 Container 종료 및 Image 삭제&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker system prune &lt;span class="o"&gt;[&lt;/span&gt;OPTIONS&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="solution-2-docker-image-prune"&gt;
 Solution 2. docker image prune
 &lt;a class="heading-anchor" href="#solution-2-docker-image-prune" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dangling Image 삭제&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker image prune&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="solution-3-dangling-images-전부-삭제"&gt;
 Solution 3. dangling images 전부 삭제
 &lt;a class="heading-anchor" href="#solution-3-dangling-images-%ec%a0%84%eb%b6%80-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker rmi &lt;span class="k"&gt;$(&lt;/span&gt;docker images --filter &lt;span class="s2"&gt;&amp;#34;dangling=true&amp;#34;&lt;/span&gt; -q --no-trunc&lt;span class="k"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker images
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;REPOSITORY TAG IMAGE ID CREATED SIZE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;gitea/gitea latest 203b931e8dab &lt;span class="m"&gt;6&lt;/span&gt; weeks ago 148MB
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;ubuntu 20.04 ba6acccedd29 &lt;span class="m"&gt;2&lt;/span&gt; months ago 72.8MB
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;mariadb 10.4.11 bc20d5f8d0fe &lt;span class="m"&gt;23&lt;/span&gt; months ago 355MB&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="solution-4-dangling-image에-repository-name-과-tag를-정한-후-삭제"&gt;
 Solution 4. dangling image에 Repository Name 과 Tag를 정한 후 삭제
 &lt;a class="heading-anchor" href="#solution-4-dangling-image%ec%97%90-repository-name-%ea%b3%bc-tag%eb%a5%bc-%ec%a0%95%ed%95%9c-%ed%9b%84-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker tag 83ac flaskapi:v0.1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker images
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;REPOSITORY TAG IMAGE ID CREATED SIZE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;flaskapi v0.1 83ac5b135a68 &lt;span class="m"&gt;2&lt;/span&gt; hours ago 105MB
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;gitea/gitea latest 203b931e8dab &lt;span class="m"&gt;6&lt;/span&gt; weeks ago 148MB
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;ubuntu 20.04 ba6acccedd29 &lt;span class="m"&gt;2&lt;/span&gt; months ago 72.8MB
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;mariadb 10.4.11 bc20d5f8d0fe &lt;span class="m"&gt;23&lt;/span&gt; months ago 355MB&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker rmi flaskapi:v0.1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="solution-5-repo와-tag가-인-image들-전부-삭제"&gt;
 Solution 5. Repo와 Tag가 &lt;none&gt;인 Image들 전부 삭제
 &lt;a class="heading-anchor" href="#solution-5-repo%ec%99%80-tag%ea%b0%80-%ec%9d%b8-image%eb%93%a4-%ec%a0%84%eb%b6%80-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker rmi &lt;span class="k"&gt;$(&lt;/span&gt;docker images -a&lt;span class="p"&gt;|&lt;/span&gt;grep &lt;span class="s2"&gt;&amp;#34;&amp;lt;none&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;awk &lt;span class="s1"&gt;&amp;#39;$1==&amp;#34;&amp;lt;none&amp;gt;&amp;#34; {print $3}&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Docker] Dockerfile 작성 및 명령어</title><link>https://kyungryeol-yoon.github.io/docker/dockerfile-format/</link><pubDate>Sun, 17 Jan 2021 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/docker/dockerfile-format/</guid><description>&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;FROM&lt;/strong&gt; : Base Image
&lt;ul&gt;
&lt;li&gt;어느 Image에서 시작할건지를 의미한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MAINTAINER&lt;/strong&gt; : Image를 생성한 개발자의 정보 (1.13.0 이후 사용 X)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LABEL&lt;/strong&gt; : Image에 메타데이터를 추가 (key-value 형태)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RUN&lt;/strong&gt; : 새로운 Layer에서 명령어를 실행하고, 새로운 Image를 생성한다.
&lt;ul&gt;
&lt;li&gt;RUN 명령을 실행할 때 마다 Layer가 생성되고 캐시된다.&lt;/li&gt;
&lt;li&gt;따라서 RUN 명령을 따로 실행하면 apt-get update는 다시 실행되지 않아서 최신 패키지를 설치할 수 없다.&lt;/li&gt;
&lt;li&gt;위 처럼 RUN 명령 하나에 apt-get update와 install을 함께 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WORKDIR&lt;/strong&gt; : 작업 Directory를 지정한다. 해당 Directory가 없으면 새로 생성한다.
&lt;ul&gt;
&lt;li&gt;작업 Directory를 지정하면 그 이후 명령어는 해당 Directory를 기준으로 동작한다.&lt;/li&gt;
&lt;li&gt;cd 명령어와 동일하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;EXPOSE&lt;/strong&gt; : Dockerfile의 빌드로 생성된 Image에서 열어줄 포트를 의미한다.
&lt;ul&gt;
&lt;li&gt;Host 머신과 Container의 포트 Mapping시에 사용된다.&lt;/li&gt;
&lt;li&gt;Container 생성 시 -p 옵션의 Container 포트 값으로 EXPOSE 값을 적어야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;USER&lt;/strong&gt; : Image를 어떤 계정에서 실행 하는지 지정
&lt;ul&gt;
&lt;li&gt;기본적으로 root에서 해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;COPY / ADD&lt;/strong&gt; : build 명령 중간에 Host의 파일 또는 폴더를 Image에 가져오는 것
&lt;ul&gt;
&lt;li&gt;ADD 명령문은 좀 더 파워풀한 COPY 명령문이라고 생각할 수 있다.&lt;/li&gt;
&lt;li&gt;ADD 명령문은 일반 파일 뿐만 아니라 압축 파일이나 네트워크 상의 파일도 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;이렇게 특수한 파일을 다루는 게 아니라면 COPY 명령문을 사용하는 것이 권장된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ENV&lt;/strong&gt; : Image에서 사용할 환경 변수 값을 지정한다.
&lt;ul&gt;
&lt;li&gt;path 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CMD / ENTRYPOINT&lt;/strong&gt; : Container를 생성 및 실행 할 때 실행할 명령어
&lt;ul&gt;
&lt;li&gt;보통 Container 내부에서 항상 돌아가야하는 서버를 띄울 때 사용한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CMD&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Container를 생성할 때만 실행됩니다. (&lt;code&gt;docker run&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Container 생성 시, 추가적인 명령어에 따라 설정한 명령어를 수정할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ENTRYPOINT&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Container를 시작할 때마다 실행됩니다. (&lt;code&gt;docker start&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Container 시작 시, 추가적인 명령어 존재 여부와 상관 없이 무조건 실행된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;명령어 형식&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CMD [&amp;quot;&amp;lt;Command&amp;gt;&amp;quot;, &amp;quot;&amp;lt;Parameter1&amp;gt;&amp;quot;, &amp;quot;&amp;lt;Parameter2&amp;gt;&amp;quot;]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CMD &amp;lt;Command&amp;gt; &amp;lt;Parameter1&amp;gt; &amp;lt;Parameter2&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ENTRYPOINT [&amp;quot;&amp;lt;Command&amp;gt;&amp;quot;, &amp;quot;&amp;lt;Parameter1&amp;gt;&amp;quot;, &amp;quot;&amp;lt;Parameter2&amp;gt;&amp;quot;]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ENTRYPOINT &amp;lt;Command&amp;gt; &amp;lt;Parameter1&amp;gt; &amp;lt;Parameter2&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[DDD Start 실전] 주문-결제 시스템 설계 및 테스트</title><link>https://kyungryeol-yoon.github.io/backend/architecture/ddd-start-order-payment/</link><pubDate>Sat, 12 Dec 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/architecture/ddd-start-order-payment/</guid><description>&lt;h1 id="-ddd-start-실전-주문-결제-시스템-예제"&gt;
 🚀 DDD Start 실전: 주문-결제 시스템 예제
 &lt;a class="heading-anchor" href="#-ddd-start-%ec%8b%a4%ec%a0%84-%ec%a3%bc%eb%ac%b8-%ea%b2%b0%ec%a0%9c-%ec%8b%9c%ec%8a%a4%ed%85%9c-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;이번 글에서는 &lt;strong&gt;DDD Start&lt;/strong&gt;를 기반으로 실제 &lt;strong&gt;주문(Order) - 결제(Payment) 시스템&lt;/strong&gt;을 설계하고,&lt;br&gt;
테스트 케이스까지 포함한 실전 예제를 다룹니다.&lt;br&gt;
DDD 입문자뿐만 아니라 실무 개발자에게도 바로 적용 가능한 가이드입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="1-단계별-ddd-start-요약"&gt;
 1️⃣ 단계별 DDD Start 요약
 &lt;a class="heading-anchor" href="#1-%eb%8b%a8%ea%b3%84%eb%b3%84-ddd-start-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;단계&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
					&lt;th&gt;예제 적용&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;🟢 도메인 언어 정리&lt;/td&gt;
					&lt;td&gt;개발자 + 도메인 전문가가 같은 용어 사용&lt;/td&gt;
					&lt;td&gt;Order, Customer, Product, Payment&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🟡 도메인 분리&lt;/td&gt;
					&lt;td&gt;핵심(Core) / 지원(Supporting) / 범용(Generic)&lt;/td&gt;
					&lt;td&gt;Core: Order, Supporting: Payment, Generic: Logging&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🔵 Bounded Context 정의&lt;/td&gt;
					&lt;td&gt;각 컨텍스트별 책임 정의&lt;/td&gt;
					&lt;td&gt;주문 Context, 결제 Context, 배송 Context&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🟣 모델링&lt;/td&gt;
					&lt;td&gt;엔티티, 값 객체, 도메인 서비스 설계&lt;/td&gt;
					&lt;td&gt;Order, OrderItem, PaymentService 등&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🟠 구현&lt;/td&gt;
					&lt;td&gt;도메인 중심 구조 기반 코드 작성&lt;/td&gt;
					&lt;td&gt;src/domain/&amp;hellip; 구조로 구현, 테스트 포함&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="2-도메인-모델링"&gt;
 2️⃣ 도메인 모델링
 &lt;a class="heading-anchor" href="#2-%eb%8f%84%eb%a9%94%ec%9d%b8-%eb%aa%a8%eb%8d%b8%eb%a7%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="21-order-엔티티"&gt;
 2.1 Order 엔티티
 &lt;a class="heading-anchor" href="#21-order-%ec%97%94%ed%8b%b0%ed%8b%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OrderId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OrderItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OrderStatus&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OrderStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PENDING&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;customer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OrderItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;confirm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IllegalStateException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;주문 아이템이 없습니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OrderStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CONFIRMED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OrderStatus&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getStatus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="22-값-객체value-object"&gt;
 2.2 값 객체(Value Object)
 &lt;a class="heading-anchor" href="#22-%ea%b0%92-%ea%b0%9d%ec%b2%b4value-object" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderItem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;OrderItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;product&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="23-도메인-서비스"&gt;
 2.3 도메인 서비스
 &lt;a class="heading-anchor" href="#23-%eb%8f%84%eb%a9%94%ec%9d%b8-%ec%84%9c%eb%b9%84%ec%8a%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentService&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PaymentResult&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PaymentMethod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getStatus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OrderStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CONFIRMED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IllegalStateException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;결제 전 주문만 결제 가능합니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PaymentResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="3-코드-구조-예시"&gt;
 3️⃣ 코드 구조 예시
 &lt;a class="heading-anchor" href="#3-%ec%bd%94%eb%93%9c-%ea%b5%ac%ec%a1%b0-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;src/
 ├── domain/
 │ ├── order/
 │ │ ├── Order.java
 │ │ ├── OrderItem.java
 │ │ └── OrderStatus.java
 │ ├── payment/
 │ │ ├── PaymentService.java
 │ │ └── PaymentResult.java
 │ └── customer/
 │ └── Customer.java
 ├── application/
 │ └── OrderApplicationService.java
 └── infrastructure/
 ├── repository/
 └── external/&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;📌 핵심: 도메인 중심 구조 유지, 테스트와 애플리케이션 로직은 분리&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h1 id="4-테스트-케이스-예제"&gt;
 4️⃣ 테스트 케이스 예제
 &lt;a class="heading-anchor" href="#4-%ed%85%8c%ec%8a%a4%ed%8a%b8-%ec%bc%80%ec%9d%b4%ec%8a%a4-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;org.junit.jupiter.api.Test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;org.junit.jupiter.api.Assertions.*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderTest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;주문_생성_및_확인&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;홍길동&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OrderId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;상품A&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;confirm&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CONFIRMED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getStatus&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;결제_실패_주문_미확인&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;홍길동&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OrderId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PaymentService&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;paymentService&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PaymentService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;assertThrows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IllegalStateException&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;paymentService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PaymentMethod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CARD&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;결제 전 주문만 결제 가능합니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="5-실무-팁"&gt;
 5️⃣ 실무 팁
 &lt;a class="heading-anchor" href="#5-%ec%8b%a4%eb%ac%b4-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;📝 &lt;strong&gt;작게 시작&lt;/strong&gt;: 핵심 도메인부터 Aggregate 정의&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;Bounded Context 유지&lt;/strong&gt;: Context 간 책임 명확히&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;Ubiquitous Language&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;/strong&gt;: 결제, 배송, 할인 등 기능은 후속 확장&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="6-요약"&gt;
 6️⃣ 요약
 &lt;a class="heading-anchor" href="#6-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DDD Start&lt;/strong&gt; = 도메인 주도 설계 시작 단계 프로세스&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;실전 적용&lt;/strong&gt;: 작은 핵심 도메인 모델링 → Bounded Context → 서비스 구현 → 테스트&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;목표&lt;/strong&gt;: 도메인 중심 설계로 확장 가능하고 유지보수 쉬운 코드 구조 확보&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 결론: DDD Start는 단순 설계 철학이 아니라,
&lt;strong&gt;실무에서 바로 적용 가능한 도메인 중심 설계 가이드&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[DDD Start] 도메인 주도 설계 입문과 실전 예제</title><link>https://kyungryeol-yoon.github.io/backend/architecture/ddd-start-guide/</link><pubDate>Mon, 07 Dec 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/architecture/ddd-start-guide/</guid><description>&lt;h1 id="-ddd-start-도메인-주도-설계-시작-가이드"&gt;
 🚀 DDD Start: 도메인 주도 설계 시작 가이드
 &lt;a class="heading-anchor" href="#-ddd-start-%eb%8f%84%eb%a9%94%ec%9d%b8-%ec%a3%bc%eb%8f%84-%ec%84%a4%ea%b3%84-%ec%8b%9c%ec%9e%91-%ea%b0%80%ec%9d%b4%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;DDD Start&lt;/strong&gt;는 도메인 주도 설계를 처음 도입할 때의 &lt;strong&gt;입문 단계와 실무 접근 방법&lt;/strong&gt;을 의미합니다.&lt;br&gt;
이 글에서는 단계별 흐름과 실제 예제를 통해 DDD를 어떻게 시작할 수 있는지 정리합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="1-ddd-start-단계-요약"&gt;
 1️⃣ DDD Start 단계 요약
 &lt;a class="heading-anchor" href="#1-ddd-start-%eb%8b%a8%ea%b3%84-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;단계&lt;/th&gt;
					&lt;th&gt;목적&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;🟢 도메인 언어 정리&lt;/td&gt;
					&lt;td&gt;공통 언어&lt;/td&gt;
					&lt;td&gt;개발자 + 도메인 전문가 + 기획자가 같은 언어 사용&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🟡 도메인 분리&lt;/td&gt;
					&lt;td&gt;책임 정의&lt;/td&gt;
					&lt;td&gt;핵심(Core), 지원(Supporting), 일반(Generic) 도메인 구분&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🔵 컨텍스트 정의&lt;/td&gt;
					&lt;td&gt;경계 설정&lt;/td&gt;
					&lt;td&gt;Bounded Context 정의, 각 영역의 Ubiquitous Language 유지&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🟣 모델링&lt;/td&gt;
					&lt;td&gt;객체/개념 추상화&lt;/td&gt;
					&lt;td&gt;엔티티, 값 객체, 도메인 서비스, 애그리거트 정의&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🟠 설계 &amp;amp; 구현&lt;/td&gt;
					&lt;td&gt;코드 구조화&lt;/td&gt;
					&lt;td&gt;도메인 주도 구조 기반으로 구현&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="2-예제-주문결제-시스템-ddd-start"&gt;
 2️⃣ 예제: 주문/결제 시스템 DDD Start
 &lt;a class="heading-anchor" href="#2-%ec%98%88%ec%a0%9c-%ec%a3%bc%eb%ac%b8%ea%b2%b0%ec%a0%9c-%ec%8b%9c%ec%8a%a4%ed%85%9c-ddd-start" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="21-비즈니스-언어-정리-ubiquitous-language"&gt;
 2.1 비즈니스 언어 정리 (Ubiquitous Language)
 &lt;a class="heading-anchor" href="#21-%eb%b9%84%ec%a6%88%eb%8b%88%ec%8a%a4-%ec%96%b8%ec%96%b4-%ec%a0%95%eb%a6%ac-ubiquitous-language" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;주문(Order), 결제(Payment), 상품(Product), 고객(Customer)&lt;/li&gt;
&lt;li&gt;주문 생성 → 결제 → 배송&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;모든 팀원이 같은 용어로 소통&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="22-도메인-분리"&gt;
 2.2 도메인 분리
 &lt;a class="heading-anchor" href="#22-%eb%8f%84%eb%a9%94%ec%9d%b8-%eb%b6%84%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Core Domain: 주문 관리(Order)
Supporting Domain: 결제(Payment)
Generic Domain: 공통 유틸, 로깅, 인증&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="23-bounded-context-정의"&gt;
 2.3 Bounded Context 정의
 &lt;a class="heading-anchor" href="#23-bounded-context-%ec%a0%95%ec%9d%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Context&lt;/th&gt;
					&lt;th&gt;담당 기능&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;주문 Context&lt;/td&gt;
					&lt;td&gt;주문 생성, 주문 상태 관리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;결제 Context&lt;/td&gt;
					&lt;td&gt;결제 처리, 결제 상태 확인&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;배송 Context&lt;/td&gt;
					&lt;td&gt;배송 등록, 배송 추적&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;각 Context마다 독립적 모델과 언어 유지&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="24-도메인-모델링"&gt;
 2.4 도메인 모델링
 &lt;a class="heading-anchor" href="#24-%eb%8f%84%eb%a9%94%ec%9d%b8-%eb%aa%a8%eb%8d%b8%eb%a7%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Order 엔티티&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OrderId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OrderItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OrderStatus&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;confirm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 값 객체(Value Object)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderItem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 도메인 서비스&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentService&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PaymentResult&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PaymentMethod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="25-설계--코드-구조-예시"&gt;
 2.5 설계 &amp;amp; 코드 구조 예시
 &lt;a class="heading-anchor" href="#25-%ec%84%a4%ea%b3%84--%ec%bd%94%eb%93%9c-%ea%b5%ac%ec%a1%b0-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;src/
 ├── domain/
 │ ├── order/
 │ │ ├── Order.java
 │ │ ├── OrderItem.java
 │ │ └── OrderStatus.java
 │ ├── payment/
 │ │ ├── PaymentService.java
 │ │ └── PaymentResult.java
 │ └── customer/
 │ └── Customer.java
 ├── application/
 │ └── OrderApplicationService.java
 └── infrastructure/
 ├── repository/
 └── external/&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;📌 DDD Start는 &lt;strong&gt;도메인 중심&lt;/strong&gt;으로 구조를 잡고, 서비스/레포지토리/외부 연동은 나중에 연결&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h1 id="3-실무-팁"&gt;
 3️⃣ 실무 팁
 &lt;a class="heading-anchor" href="#3-%ec%8b%a4%eb%ac%b4-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;📌 먼저 **모델링과 협력(책임 중심 설계)**에 집중&lt;/li&gt;
&lt;li&gt;📌 Context마다 &lt;strong&gt;Ubiquitous Language&lt;/strong&gt; 유지&lt;/li&gt;
&lt;li&gt;📌 단위 테스트 중심으로 개발&lt;/li&gt;
&lt;li&gt;📌 작은 Aggregate로 시작하고 점진적으로 확장&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="4-요약"&gt;
 4️⃣ 요약
 &lt;a class="heading-anchor" href="#4-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DDD Start = DDD 입문/실전 단계 가이드&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;핵심: &lt;strong&gt;언어 → 도메인 → 컨텍스트 → 모델링 → 코드 구조&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;실무 적용: 작은 핵심 도메인부터 시작, 점진적 확장, 테스트 기반 개발&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 결론: DDD Start는 단순한 설계 철학이 아니라, &lt;strong&gt;실전에서 도메인 중심 설계를 시작하는 명확한 가이드&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Docker] stdout/stderr 관리와 실무 활용 가이드</title><link>https://kyungryeol-yoon.github.io/docker/docker-logs-stdout-seo/</link><pubDate>Wed, 02 Dec 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/docker/docker-logs-stdout-seo/</guid><description>&lt;h2 id="-docker-로그-관리-stdout과-stderr-완벽-가이드"&gt;
 🐳 Docker 로그 관리: stdout과 stderr 완벽 가이드
 &lt;a class="heading-anchor" href="#-docker-%eb%a1%9c%ea%b7%b8-%ea%b4%80%eb%a6%ac-stdout%ea%b3%bc-stderr-%ec%99%84%eb%b2%bd-%ea%b0%80%ec%9d%b4%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Docker에서 컨테이너 로그는 **stdout (표준 출력)**과 **stderr (표준 에러)**를 통해 수집됩니다.&lt;br&gt;
이 글에서는 Docker 로그 개념부터 실무 활용, 중앙화 로그 시스템 연결까지 &lt;strong&gt;실무 중심 가이드&lt;/strong&gt;를 제공합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-docker-로그란-stdout-vs-stderr"&gt;
 1️⃣ Docker 로그란? stdout vs stderr
 &lt;a class="heading-anchor" href="#1-docker-%eb%a1%9c%ea%b7%b8%eb%9e%80-stdout-vs-stderr" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;구분&lt;/th&gt;
					&lt;th&gt;의미&lt;/th&gt;
					&lt;th&gt;활용 예시&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;🟢 stdout&lt;/td&gt;
					&lt;td&gt;정상적인 프로그램 출력&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;&amp;quot;Server started on port 8080&amp;quot;&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🔴 stderr&lt;/td&gt;
					&lt;td&gt;에러 및 경고 메시지&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;&amp;quot;Failed to connect to DB&amp;quot;&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 Docker는 컨테이너가 출력하는 stdout/stderr를 로그로 수집하며, 이를 통해 &lt;strong&gt;애플리케이션 상태와 장애&lt;/strong&gt;를 모니터링할 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="2-docker-로그-확인-방법"&gt;
 2️⃣ Docker 로그 확인 방법
 &lt;a class="heading-anchor" href="#2-docker-%eb%a1%9c%ea%b7%b8-%ed%99%95%ec%9d%b8-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="21-기본-로그-조회"&gt;
 2.1 기본 로그 조회
 &lt;a class="heading-anchor" href="#21-%ea%b8%b0%eb%b3%b8-%eb%a1%9c%ea%b7%b8-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker logs &amp;lt;컨테이너 이름 또는 ID&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;stdout + stderr 합쳐서 출력&lt;/li&gt;
&lt;li&gt;예시:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Server started on port 8080
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;Failed to connect to Redis&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="22-실시간-로그-모니터링"&gt;
 2.2 실시간 로그 모니터링
 &lt;a class="heading-anchor" href="#22-%ec%8b%a4%ec%8b%9c%ea%b0%84-%eb%a1%9c%ea%b7%b8-%eb%aa%a8%eb%8b%88%ed%84%b0%eb%a7%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker logs -f &amp;lt;컨테이너 이름&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt; 옵션으로 로그 실시간 스트리밍&lt;/li&gt;
&lt;li&gt;개발 및 디버깅 단계에서 유용&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="23-로그-타임스탬프-표시"&gt;
 2.3 로그 타임스탬프 표시
 &lt;a class="heading-anchor" href="#23-%eb%a1%9c%ea%b7%b8-%ed%83%80%ec%9e%84%ec%8a%a4%ed%83%ac%ed%94%84-%ed%91%9c%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker logs -t &amp;lt;컨테이너 이름&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;로그 앞에 시간 정보 표시&lt;/li&gt;
&lt;li&gt;예:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;2026-03-02T12:34:56.789Z Server started on port 8080&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="3-docker-로그-드라이버-이해"&gt;
 3️⃣ Docker 로그 드라이버 이해
 &lt;a class="heading-anchor" href="#3-docker-%eb%a1%9c%ea%b7%b8-%eb%93%9c%eb%9d%bc%ec%9d%b4%eb%b2%84-%ec%9d%b4%ed%95%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Docker는 로그 저장과 전송을 **로그 드라이버(Log Driver)**로 관리합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;드라이버&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
					&lt;th&gt;사용 사례&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;json-file&lt;/td&gt;
					&lt;td&gt;기본 저장&lt;/td&gt;
					&lt;td&gt;로컬 개발 환경&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;syslog&lt;/td&gt;
					&lt;td&gt;시스템 로그&lt;/td&gt;
					&lt;td&gt;서버 로그 중앙 관리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;fluentd&lt;/td&gt;
					&lt;td&gt;외부 수집&lt;/td&gt;
					&lt;td&gt;로그 분석, 모니터링&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;gelf / Loki&lt;/td&gt;
					&lt;td&gt;ELK, Grafana 연동&lt;/td&gt;
					&lt;td&gt;중앙화 로그 &amp;amp; 모니터링&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 실무에서는 중앙화된 로그 시스템으로 stdout/stderr를 수집하면 &lt;strong&gt;모니터링, 알람, 장애 대응&lt;/strong&gt;이 편리합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="4-stdoutstderr-활용-사례"&gt;
 4️⃣ stdout/stderr 활용 사례
 &lt;a class="heading-anchor" href="#4-stdoutstderr-%ed%99%9c%ec%9a%a9-%ec%82%ac%eb%a1%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="41-개발-단계-"&gt;
 4.1 개발 단계 🛠
 &lt;a class="heading-anchor" href="#41-%ea%b0%9c%eb%b0%9c-%eb%8b%a8%ea%b3%84-" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker logs -f&lt;/code&gt;로 실시간 로그 확인&lt;/li&gt;
&lt;li&gt;디버깅 및 서버 상태 추적&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="42-배포-단계-"&gt;
 4.2 배포 단계 🚀
 &lt;a class="heading-anchor" href="#42-%eb%b0%b0%ed%8f%ac-%eb%8b%a8%ea%b3%84-" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;stdout/stderr를 &lt;strong&gt;중앙 로그 시스템&lt;/strong&gt;으로 수집&lt;/li&gt;
&lt;li&gt;ELK Stack → Kibana, Grafana → 시각화&lt;/li&gt;
&lt;li&gt;경고/에러는 알림 시스템과 연동&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="43-장애-대응-"&gt;
 4.3 장애 대응 ⚠️
 &lt;a class="heading-anchor" href="#43-%ec%9e%a5%ec%95%a0-%eb%8c%80%ec%9d%91-" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;stderr 로그만 필터링&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker logs &amp;lt;컨테이너 이름&amp;gt; 2&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="s2"&gt;&amp;#34;ERROR&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;특정 서비스/컨테이너 문제를 빠르게 추적 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="5-실무-팁-효율적인-docker-로그-관리"&gt;
 5️⃣ 실무 팁: 효율적인 Docker 로그 관리
 &lt;a class="heading-anchor" href="#5-%ec%8b%a4%eb%ac%b4-%ed%8c%81-%ed%9a%a8%ec%9c%a8%ec%a0%81%ec%9d%b8-docker-%eb%a1%9c%ea%b7%b8-%ea%b4%80%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;📌 프로그램 내 print 대신 로깅 라이브러리 활용&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python: &lt;code&gt;logging&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Java: &lt;code&gt;logback&lt;/code&gt;, &lt;code&gt;log4j&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Node.js: &lt;code&gt;winston&lt;/code&gt;, &lt;code&gt;pino&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📌 로그 레벨 설정: INFO, WARN, ERROR → stderr와 stdout 구분&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📌 로그 파일보다 stdout/stderr → Docker, Kubernetes 친화적&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📌 중앙화 로그 → 장애 대응과 트래픽 분석에 최적화&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="6-docker-로그-구조-한-눈에-보기"&gt;
 6️⃣ Docker 로그 구조: 한 눈에 보기
 &lt;a class="heading-anchor" href="#6-docker-%eb%a1%9c%ea%b7%b8-%ea%b5%ac%ec%a1%b0-%ed%95%9c-%eb%88%88%ec%97%90-%eb%b3%b4%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;[컨테이너 프로그램]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; stdout / stderr
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;[Docker 데몬]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;[로그 드라이버 (json-file, fluentd, syslog 등)]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;[외부 로깅 시스템 / 터미널]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;📝 핵심: stdout/stderr는 &lt;strong&gt;표준화된 로그 채널&lt;/strong&gt;이며, 어디든 연결할 수 있는 유연한 통로입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="7-요약-docker-로그-관리-핵심-포인트"&gt;
 7️⃣ 요약: Docker 로그 관리 핵심 포인트
 &lt;a class="heading-anchor" href="#7-%ec%9a%94%ec%95%bd-docker-%eb%a1%9c%ea%b7%b8-%ea%b4%80%eb%a6%ac-%ed%95%b5%ec%8b%ac-%ed%8f%ac%ec%9d%b8%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Docker 로그 = stdout + stderr&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker logs&lt;/code&gt;로 기본 확인 가능&lt;/li&gt;
&lt;li&gt;실시간 스트리밍 &lt;code&gt;-f&lt;/code&gt; 활용&lt;/li&gt;
&lt;li&gt;stderr = 장애 대응, stdout = 정상 상태 모니터링&lt;/li&gt;
&lt;li&gt;중앙화 로그 시스템 연동 → 실무 운영 효율 극대화&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;실무 TIP&lt;/strong&gt;: 로그를 잘 관리하면 개발, 배포, 모니터링, 장애 대응 모두 빠르고 안전해집니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="8-추가-학습-링크"&gt;
 8️⃣ 추가 학습 링크
 &lt;a class="heading-anchor" href="#8-%ec%b6%94%ea%b0%80-%ed%95%99%ec%8a%b5-%eb%a7%81%ed%81%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/config/containers/logging/"&gt;Docker 공식 로그 관리 문서&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.elastic.co/what-is/elk-stack"&gt;ELK Stack 로깅 가이드&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/cluster-administration/logging/"&gt;Kubernetes 로그와 stdout/stderr 활용&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Clean Code] 현실적인 관점에서 바라본 클린 코드</title><link>https://kyungryeol-yoon.github.io/cs/sw-theory/clean-code-realistic-perspective/</link><pubDate>Mon, 02 Nov 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/cs/sw-theory/clean-code-realistic-perspective/</guid><description>&lt;h2 id="-clean-code에-대한-현실적인-고찰"&gt;
 🧹 Clean Code에 대한 현실적인 고찰
 &lt;a class="heading-anchor" href="#-clean-code%ec%97%90-%eb%8c%80%ed%95%9c-%ed%98%84%ec%8b%a4%ec%a0%81%ec%9d%b8-%ea%b3%a0%ec%b0%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;개발자라면 한 번쯤 **클린 코드(Clean Code)**에 대해 고민해봤을 것이다.&lt;br&gt;
그리고 대부분 이런 질문으로 이어진다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;🤔 “이게 진짜 좋은 코드인가, 아니면 그냥 내가 보기 좋은 코드인가?”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;클린 코드는 단순히 &lt;strong&gt;잘 동작하는 코드&lt;/strong&gt;가 아니다.&lt;br&gt;
그렇다고 &lt;strong&gt;디자인 패턴이 많이 적용된 코드&lt;/strong&gt;도 아니다.&lt;/p&gt;
&lt;p&gt;이 글에서는 실무 경험을 기준으로 다음 관점에서 클린 코드를 정리해본다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;👨‍💻 개발자 관점에서의 클린 코드 정의&lt;/li&gt;
&lt;li&gt;🏗 백엔드 기준 클린 코드&lt;/li&gt;
&lt;li&gt;🎨 프론트엔드 기준 클린 코드&lt;/li&gt;
&lt;li&gt;🚀 스타트업 vs 🏢 대기업의 차이&lt;/li&gt;
&lt;li&gt;🧠 시니어 개발자의 관점&lt;/li&gt;
&lt;li&gt;⚠️ 클린 코드 집착이 독이 되는 순간&lt;/li&gt;
&lt;li&gt;👀 코드 리뷰에서 실제로 보는 기준&lt;/li&gt;
&lt;li&gt;🏛 아키텍처와 클린 코드의 관계&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="1-개발자-관점에서-본-클린-코드의-핵심"&gt;
 1️⃣ 개발자 관점에서 본 클린 코드의 핵심
 &lt;a class="heading-anchor" href="#1-%ea%b0%9c%eb%b0%9c%ec%9e%90-%ea%b4%80%ec%a0%90%ec%97%90%ec%84%9c-%eb%b3%b8-%ed%81%b4%eb%a6%b0-%ec%bd%94%eb%93%9c%ec%9d%98-%ed%95%b5%ec%8b%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1--가독성은-속도다"&gt;
 1) 📖 가독성은 속도다
 &lt;a class="heading-anchor" href="#1--%ea%b0%80%eb%8f%85%ec%84%b1%ec%9d%80-%ec%86%8d%eb%8f%84%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;가독성은 “보기 좋음”이 아니라&lt;br&gt;
&lt;strong&gt;이해하는 데 걸리는 시간&lt;/strong&gt;이다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;elapsedDays&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이 변수는 주석이 필요 없다.
읽는 순간 의미가 전달된다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;✅ 좋은 코드는 설명하지 않는다. 이해된다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="2--의도가-드러나는-코드"&gt;
 2) 🎯 의도가 드러나는 코드
 &lt;a class="heading-anchor" href="#2--%ec%9d%98%eb%8f%84%ea%b0%80-%eb%93%9c%eb%9f%ac%eb%82%98%eb%8a%94-%ec%bd%94%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;코드를 읽는 사람이 추측을 시작하는 순간,
그 코드는 이미 비용을 발생시키고 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasPermission&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ADMIN&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;왜 이 조건이 필요한지 명확하다.
추론이 아니라 &lt;strong&gt;확신&lt;/strong&gt;을 준다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="3--작은-함수가-중요한-이유"&gt;
 3) ✂️ 작은 함수가 중요한 이유
 &lt;a class="heading-anchor" href="#3--%ec%9e%91%ec%9d%80-%ed%95%a8%ec%88%98%ea%b0%80-%ec%a4%91%ec%9a%94%ed%95%9c-%ec%9d%b4%ec%9c%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;“한 함수는 한 가지 일만 한다”는 원칙은
이상론이 아니라 &lt;strong&gt;유지보수 전략&lt;/strong&gt;이다.&lt;/p&gt;
&lt;p&gt;함수가 작으면:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🔍 테스트가 쉬워지고&lt;/li&gt;
&lt;li&gt;♻️ 재사용이 가능하며&lt;/li&gt;
&lt;li&gt;🧩 수정 범위가 줄어든다&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;핵심은 길이가 아니라 &lt;strong&gt;책임의 개수&lt;/strong&gt;다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="4--dry는-리스크-관리다"&gt;
 4) 🔁 DRY는 리스크 관리다
 &lt;a class="heading-anchor" href="#4--dry%eb%8a%94-%eb%a6%ac%ec%8a%a4%ed%81%ac-%ea%b4%80%eb%a6%ac%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;중복 코드는 단순히 귀찮은 문제가 아니다.
버그 확률을 증가시키는 구조적 위험이다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;같은 로직이 3곳에 있다면
수정할 때 3번 실수할 기회를 얻게 된다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="5--테스트-가능성은-설계-품질의-지표다"&gt;
 5) 🧪 테스트 가능성은 설계 품질의 지표다
 &lt;a class="heading-anchor" href="#5--%ed%85%8c%ec%8a%a4%ed%8a%b8-%ea%b0%80%eb%8a%a5%ec%84%b1%ec%9d%80-%ec%84%a4%ea%b3%84-%ed%92%88%ec%a7%88%ec%9d%98-%ec%a7%80%ed%91%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;테스트가 어려운 코드는 보통:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;강하게 결합되어 있고&lt;/li&gt;
&lt;li&gt;의존성이 많으며&lt;/li&gt;
&lt;li&gt;사이드 이펙트가 숨겨져 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;테스트는 결과 검증이 아니라
&lt;strong&gt;구조의 건강 상태를 보여주는 신호&lt;/strong&gt;다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="-한-줄-정의"&gt;
 🧾 한 줄 정의
 &lt;a class="heading-anchor" href="#-%ed%95%9c-%ec%a4%84-%ec%a0%95%ec%9d%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 클린 코드는 “읽는 시간은 짧고, 수정 비용은 낮은 코드”다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="2-백엔드-기준-클린-코드-"&gt;
 2️⃣ 백엔드 기준 클린 코드 🏗
 &lt;a class="heading-anchor" href="#2-%eb%b0%b1%ec%97%94%eb%93%9c-%ea%b8%b0%ec%a4%80-%ed%81%b4%eb%a6%b0-%ec%bd%94%eb%93%9c-" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;백엔드는 시간이 지날수록 복잡도가 쌓인다.
그래서 핵심은 &lt;strong&gt;안정성과 변경 대응력&lt;/strong&gt;이다.&lt;/p&gt;
&lt;h3 id="1--계층은-책임을-분리하기-위한-장치"&gt;
 1) 🧱 계층은 책임을 분리하기 위한 장치
 &lt;a class="heading-anchor" href="#1--%ea%b3%84%ec%b8%b5%ec%9d%80-%ec%b1%85%ec%9e%84%ec%9d%84-%eb%b6%84%eb%a6%ac%ed%95%98%ea%b8%b0-%ec%9c%84%ed%95%9c-%ec%9e%a5%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Controller → Service → Domain → Repository&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;계층 구조의 목적은 멋있어 보이기 위함이 아니다.
&lt;strong&gt;변경 영향 범위를 줄이기 위함&lt;/strong&gt;이다.&lt;/p&gt;
&lt;p&gt;Controller에 비즈니스 로직이 들어가는 순간
API 수정이 도메인 변경으로 번진다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="2--도메인-중심-설계"&gt;
 2) 🧩 도메인 중심 설계
 &lt;a class="heading-anchor" href="#2--%eb%8f%84%eb%a9%94%ec%9d%b8-%ec%a4%91%ec%8b%ac-%ec%84%a4%ea%b3%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;activate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;행위는 읽는 순간 이해된다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;무엇을&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;의미하는가&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;숫자는 기억해야 하지만,
행위는 의도를 드러낸다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="3--예외-처리의-일관성"&gt;
 3) 🚨 예외 처리의 일관성
 &lt;a class="heading-anchor" href="#3--%ec%98%88%ec%99%b8-%ec%b2%98%eb%a6%ac%ec%9d%98-%ec%9d%bc%ea%b4%80%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;실무에서 가장 많이 망가지는 부분이 예외 처리다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;어떤 예외는 롤백되고&lt;/li&gt;
&lt;li&gt;어떤 예외는 삼켜지고&lt;/li&gt;
&lt;li&gt;어떤 예외는 로그만 남는다&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;일관성이 없는 예외 정책은
시스템을 예측 불가능하게 만든다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="-백엔드-한-줄-정의"&gt;
 🧾 백엔드 한 줄 정의
 &lt;a class="heading-anchor" href="#-%eb%b0%b1%ec%97%94%eb%93%9c-%ed%95%9c-%ec%a4%84-%ec%a0%95%ec%9d%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;요구사항이 바뀌어도 구조를 뒤엎지 않아도 되는 코드&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="3-프론트엔드-기준-클린-코드-"&gt;
 3️⃣ 프론트엔드 기준 클린 코드 🎨
 &lt;a class="heading-anchor" href="#3-%ed%94%84%eb%a1%a0%ed%8a%b8%ec%97%94%eb%93%9c-%ea%b8%b0%ec%a4%80-%ed%81%b4%eb%a6%b0-%ec%bd%94%eb%93%9c-" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;프론트엔드는 로직보다 &lt;strong&gt;상태 흐름 제어&lt;/strong&gt;가 더 중요하다.&lt;/p&gt;
&lt;h3 id="1--상태의-출처가-명확한가"&gt;
 1) 🔄 상태의 출처가 명확한가
 &lt;a class="heading-anchor" href="#1--%ec%83%81%ed%83%9c%ec%9d%98-%ec%b6%9c%ec%b2%98%ea%b0%80-%eb%aa%85%ed%99%95%ed%95%9c%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;전역 상태인가?&lt;/li&gt;
&lt;li&gt;지역 상태인가?&lt;/li&gt;
&lt;li&gt;서버 상태인가?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 경계가 흐려지는 순간
디버깅 난이도가 급격히 상승한다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="2--ui와-로직-분리"&gt;
 2) 🧩 UI와 로직 분리
 &lt;a class="heading-anchor" href="#2--ui%ec%99%80-%eb%a1%9c%ec%a7%81-%eb%b6%84%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;UI Component
↓
Hook / Logic
↓
API Layer&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;로직이 JSX 안에 섞이기 시작하면
컴포넌트는 빠르게 비대해진다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="3--조건문-지옥-경계"&gt;
 3) 🚫 조건문 지옥 경계
 &lt;a class="heading-anchor" href="#3--%ec%a1%b0%ea%b1%b4%eb%ac%b8-%ec%a7%80%ec%98%a5-%ea%b2%bd%ea%b3%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;삼항 연산자가 중첩되는 순간
이미 리팩토링 시점이다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;프론트엔드 클린 코드는
“렌더 흐름이 예측 가능한가”로 판단된다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="-프론트엔드-한-줄-정의"&gt;
 🧾 프론트엔드 한 줄 정의
 &lt;a class="heading-anchor" href="#-%ed%94%84%eb%a1%a0%ed%8a%b8%ec%97%94%eb%93%9c-%ed%95%9c-%ec%a4%84-%ec%a0%95%ec%9d%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;상태 흐름을 추적하기 쉬운 코드&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="4--스타트업-vs--대기업"&gt;
 4️⃣ 🚀 스타트업 vs 🏢 대기업
 &lt;a class="heading-anchor" href="#4--%ec%8a%a4%ed%83%80%ed%8a%b8%ec%97%85-vs--%eb%8c%80%ea%b8%b0%ec%97%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="-스타트업"&gt;
 🚀 스타트업
 &lt;a class="heading-anchor" href="#-%ec%8a%a4%ed%83%80%ed%8a%b8%ec%97%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;속도 = 생존&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;과한 추상화는 독&lt;/li&gt;
&lt;li&gt;미래 확장은 가정&lt;/li&gt;
&lt;li&gt;지금 필요한 구조만 설계&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;살아남는 게 먼저다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="-대기업"&gt;
 🏢 대기업
 &lt;a class="heading-anchor" href="#-%eb%8c%80%ea%b8%b0%ec%97%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;안정성 = 신뢰&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;표준화된 아키텍처&lt;/li&gt;
&lt;li&gt;문서화&lt;/li&gt;
&lt;li&gt;높은 테스트 커버리지&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;사람은 바뀌어도 시스템은 유지돼야 한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="-차이-요약"&gt;
 📊 차이 요약
 &lt;a class="heading-anchor" href="#-%ec%b0%a8%ec%9d%b4-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;구분&lt;/th&gt;
					&lt;th&gt;스타트업&lt;/th&gt;
					&lt;th&gt;대기업&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;목표&lt;/td&gt;
					&lt;td&gt;빠른 시장 검증&lt;/td&gt;
					&lt;td&gt;장기 안정성&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;설계&lt;/td&gt;
					&lt;td&gt;최소 설계&lt;/td&gt;
					&lt;td&gt;선 설계&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;테스트&lt;/td&gt;
					&lt;td&gt;핵심 위주&lt;/td&gt;
					&lt;td&gt;광범위&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="5--시니어-개발자의-시각"&gt;
 5️⃣ 🧠 시니어 개발자의 시각
 &lt;a class="heading-anchor" href="#5--%ec%8b%9c%eb%8b%88%ec%96%b4-%ea%b0%9c%eb%b0%9c%ec%9e%90%ec%9d%98-%ec%8b%9c%ea%b0%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;초급은 “예쁜 코드”를 보고,
중급은 “패턴이 적용된 코드”를 본다.
시니어는 이렇게 묻는다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;❓ “이 코드를 팀이 유지할 수 있는가?”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="핵심-기준"&gt;
 핵심 기준
 &lt;a class="heading-anchor" href="#%ed%95%b5%ec%8b%ac-%ea%b8%b0%ec%a4%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;🔄 변경에 강한가?&lt;/li&gt;
&lt;li&gt;📏 일관성이 있는가?&lt;/li&gt;
&lt;li&gt;🤝 팀 전체 생산성을 높이는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;팀 컨벤션 &amp;gt; 개인 취향&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="6--클린-코드-집착이-독이-되는-순간"&gt;
 6️⃣ ⚠️ 클린 코드 집착이 독이 되는 순간
 &lt;a class="heading-anchor" href="#6--%ed%81%b4%eb%a6%b0-%ec%bd%94%eb%93%9c-%ec%a7%91%ec%b0%a9%ec%9d%b4-%eb%8f%85%ec%9d%b4-%eb%90%98%eb%8a%94-%ec%88%9c%ea%b0%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1-과도한-추상화"&gt;
 1) 과도한 추상화
 &lt;a class="heading-anchor" href="#1-%ea%b3%bc%eb%8f%84%ed%95%9c-%ec%b6%94%ec%83%81%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;인터페이스 남발&lt;/li&gt;
&lt;li&gt;미래 확장 가정&lt;/li&gt;
&lt;li&gt;의미 없는 레이어 분리&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;확장 가능성은 가정이고, 복잡성은 현실이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="2-리팩토링이-목적이-될-때"&gt;
 2) 리팩토링이 목적이 될 때
 &lt;a class="heading-anchor" href="#2-%eb%a6%ac%ed%8c%a9%ed%86%a0%eb%a7%81%ec%9d%b4-%eb%aa%a9%ec%a0%81%ec%9d%b4-%eb%90%a0-%eb%95%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;일정 지연&lt;/li&gt;
&lt;li&gt;팀 갈등&lt;/li&gt;
&lt;li&gt;기능 개발 중단&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;클린 코드는 수단이다.
목적이 되는 순간 위험하다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="7--코드-리뷰에서-보는-기준"&gt;
 7️⃣ 👀 코드 리뷰에서 보는 기준
 &lt;a class="heading-anchor" href="#7--%ec%bd%94%eb%93%9c-%eb%a6%ac%eb%b7%b0%ec%97%90%ec%84%9c-%eb%b3%b4%eb%8a%94-%ea%b8%b0%ec%a4%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;리뷰에서 가장 중요하게 보는 것:&lt;/p&gt;
&lt;h3 id="-1-30초-안에-이해되는가"&gt;
 ⏱ 1) 30초 안에 이해되는가?
 &lt;a class="heading-anchor" href="#-1-30%ec%b4%88-%ec%95%88%ec%97%90-%ec%9d%b4%ed%95%b4%eb%90%98%eb%8a%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;설명이 필요하다면 구조가 복잡한 것이다.&lt;/p&gt;
&lt;h3 id="-2-변경-범위가-예측-가능한가"&gt;
 🔍 2) 변경 범위가 예측 가능한가?
 &lt;a class="heading-anchor" href="#-2-%eb%b3%80%ea%b2%bd-%eb%b2%94%ec%9c%84%ea%b0%80-%ec%98%88%ec%b8%a1-%ea%b0%80%eb%8a%a5%ed%95%9c%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;사이드 이펙트가 숨겨져 있지 않은가?&lt;/p&gt;
&lt;h3 id="-3-일관성이-있는가"&gt;
 📐 3) 일관성이 있는가?
 &lt;a class="heading-anchor" href="#-3-%ec%9d%bc%ea%b4%80%ec%84%b1%ec%9d%b4-%ec%9e%88%eb%8a%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;완벽한 코드보다 일관된 코드가 더 중요하다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="8--아키텍처와-클린-코드의-관계"&gt;
 8️⃣ 🏛 아키텍처와 클린 코드의 관계
 &lt;a class="heading-anchor" href="#8--%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98%ec%99%80-%ed%81%b4%eb%a6%b0-%ec%bd%94%eb%93%9c%ec%9d%98-%ea%b4%80%ea%b3%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;수준&lt;/th&gt;
					&lt;th&gt;의미&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;클린 코드&lt;/td&gt;
					&lt;td&gt;함수/클래스 단위 품질&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;설계&lt;/td&gt;
					&lt;td&gt;모듈 간 관계&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;아키텍처&lt;/td&gt;
					&lt;td&gt;시스템 전체 구조&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;🧹 클린 코드는 미시적 품질&lt;/li&gt;
&lt;li&gt;🏛 아키텍처는 거시적 안정성&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;클린 코드는 변경 비용을 낮추는 기술
아키텍처는 변경 충격을 제한하는 전략&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;둘은 대체 관계가 아니라 &lt;strong&gt;보완 관계&lt;/strong&gt;다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-마무리"&gt;
 🏁 마무리
 &lt;a class="heading-anchor" href="#-%eb%a7%88%eb%ac%b4%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;클린 코드는 예쁜 코드가 아니다.
패턴이 많은 코드도 아니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;✨ 팀이 이해할 수 있고
🔒 변경에 안전하며
🚀 비즈니스 속도를 방해하지 않는 코드&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;결국 균형의 문제다.&lt;/p&gt;
&lt;p&gt;좋은 개발자는
이상과 현실 사이에서&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;언제 단순하게 갈지&lt;/li&gt;
&lt;li&gt;언제 구조를 잡을지&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;판단할 수 있는 사람이다.&lt;/p&gt;</description></item><item><title>[Docker] Docker Multi Stage란?</title><link>https://kyungryeol-yoon.github.io/docker/docker-multi-stage/</link><pubDate>Tue, 13 Oct 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/docker/docker-multi-stage/</guid><description>&lt;h2 id="docker-multi-stage란"&gt;
 Docker Multi Stage란?
 &lt;a class="heading-anchor" href="#docker-multi-stage%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Container Image를 만들면서 Build 등에는 필요하지만 최종 Container Image에는 필요 없는 환경을 제거할 수 있도록 단계를 나누어서 기반 Image를 만드는 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="background"&gt;
 Background
 &lt;a class="heading-anchor" href="#background" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Docker가 등장한 이후 Docker Image를 작게 만들기 위한 노력들이 있었다.
&lt;ul&gt;
&lt;li&gt;Image가 작으면 작을 수록 Build, 배포 시간이 짧아 지기 때문이이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;각각의 Instruction들은 Dockerfile 하나의 Layer로 추가가 되기 때문에 여러가지 최적화가 필요했다.&lt;/li&gt;
&lt;li&gt;Docker Image를 가볍게 만들기 위해 나온 방법이 Multi Stage 방식이이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="multi-stage-build-방식이-나오기-전에"&gt;
 Multi Stage build 방식이 나오기 전에
 &lt;a class="heading-anchor" href="#multi-stage-build-%eb%b0%a9%ec%8b%9d%ec%9d%b4-%eb%82%98%ec%98%a4%ea%b8%b0-%ec%a0%84%ec%97%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;builder-pattern을 활용했다.
&lt;ul&gt;
&lt;li&gt;하나의 Dockerfile이 아닌 두 가지의 Dockerfile을 유지하는 것이이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Dockerfile.build&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;여러 명령어를 실행하는 데 분리하지 않고 &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; &lt;code&gt;\&lt;/code&gt;를 통해 하나의 Layer에서 처리할 수 있다.&lt;/li&gt;
&lt;li&gt;Build를 위한 Image이이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;golang:1.7.3&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/go/src/github.com/alexellis/href-counter&lt;/span&gt;/&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; app.go .&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; go get -d -v golang.org/x/net/html &lt;span class="se"&gt;\ &lt;/span&gt;-&amp;gt; 하나의 Layer에서 명령어를 처리하기 위한 최적화&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;CGO_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nv"&gt;GOOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;linux go build -a -installsuffix cgo -o app .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Dockerfile
&lt;ul&gt;
&lt;li&gt;어플리케이션을 실행하기 위한 Dockerfile&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;alpine:latest&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; apk --no-cache add ca-certificates&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/root&lt;/span&gt;/&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; app .&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CMD&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./app&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;build.sh
&lt;ul&gt;
&lt;li&gt;Multi stage를 지원하기 전에는 이렇게 따로 스크립트를 작성해야 했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/sh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; Building alexellis2/href-counter:build
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# build image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;docker build --build-arg &lt;span class="nv"&gt;https_proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$https_proxy&lt;/span&gt; --build-arg &lt;span class="nv"&gt;http_proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$http_proxy&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; -t alexellis2/href-counter:build . -f Dockerfile.build
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;docker container create --name extract alexellis2/href-counter:build
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;docker container cp extract:/go/src/github.com/alexellis/href-counter/app ./app
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;docker container rm -f extract
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; Building alexellis2/href-counter:latest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# run app&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;docker build --no-cache -t alexellis2/href-counter:latest .
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;rm ./app&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="multi-stage가-등장하면서"&gt;
 Multi Stage가 등장하면서
 &lt;a class="heading-anchor" href="#multi-stage%ea%b0%80-%eb%93%b1%ec%9e%a5%ed%95%98%eb%a9%b4%ec%84%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;하나의 Dockerfile로 Build Image와 실행 Image를 분리할 수 있게 되어 훨씬 간편하게 Image를 줄일 수 있게 되었다.
&lt;ul&gt;
&lt;li&gt;뿐만 아니라 배포 Image의 용량이 줄어 Build 시간이 감소하게 되었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;golang:1.7.3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/go/src/github.com/alexellis/href-counter&lt;/span&gt;/&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; go get -d -v golang.org/x/net/html&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; app.go .&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; &lt;span class="nv"&gt;CGO_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nv"&gt;GOOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;linux go build -a -installsuffix cgo -o app .&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;alpine:latest&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; apk --no-cache add ca-certificates&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/root&lt;/span&gt;/&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; --from&lt;span class="o"&gt;=&lt;/span&gt;builder /go/src/github.com/alexellis/href-counter/app .&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CMD&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./app&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] kubeadm init 시 bridge-nf-call-iptables 에러 해결</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubernetes-init-error-br-netfilter/</link><pubDate>Wed, 19 Aug 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/kubernetes-init-error-br-netfilter/</guid><description>&lt;h2 id="-1-문제-상황-the-error"&gt;
 🚨 1. 문제 상황 (The Error)
 &lt;a class="heading-anchor" href="#-1-%eb%ac%b8%ec%a0%9c-%ec%83%81%ed%99%a9-the-error" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;kubeadm init&lt;/code&gt; 명령어를 실행하면 시스템의 사전 상태를 점검(Pre-flight check)하는데, 이때 아래와 같은 치명적인 에러(Fatal Error)를 마주하게 됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;init&lt;span class="o"&gt;]&lt;/span&gt; Using Kubernetes version: v1.2x.x
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;preflight&lt;span class="o"&gt;]&lt;/span&gt; Running pre-flight checks
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;error execution phase preflight: &lt;span class="o"&gt;[&lt;/span&gt;preflight&lt;span class="o"&gt;]&lt;/span&gt; Some fatal errors occurred:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables&lt;span class="o"&gt;]&lt;/span&gt;: /proc/sys/net/bridge/bridge-nf-call-iptables does not exist&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;직역하자면 &lt;code&gt;/proc/sys/net/bridge/bridge-nf-call-iptables&lt;/code&gt;라는 파일이 존재하지 않는다는 뜻입니다. 이 파일이 없으면 쿠버네티스의 파드(Pod) 간 네트워크 트래픽을 iptables가 제어할 수 없게 됩니다. 🛑&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-2-원인-분석-root-cause"&gt;
 💡 2. 원인 분석 (Root Cause)
 &lt;a class="heading-anchor" href="#-2-%ec%9b%90%ec%9d%b8-%eb%b6%84%ec%84%9d-root-cause" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;이 문제는 리눅스 커널의 &lt;strong&gt;&lt;code&gt;br_netfilter&lt;/code&gt;&lt;/strong&gt; 모듈이 활성화되지 않았기 때문에 발생합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;br_netfilter&lt;/strong&gt;: 브리지 네트워크 인터페이스를 통과하는 패킷을 iptables(Netfilter)가 처리할 수 있게 해주는 커널 모듈입니다.&lt;/li&gt;
&lt;li&gt;이 모듈이 로드되지 않으면 &lt;code&gt;/proc/sys/net/bridge/&lt;/code&gt; 경로 자체가 생성되지 않으므로, 아무리 설정값을 넣으려 해도 &amp;ldquo;No such file or directory&amp;rdquo; 에러가 뜨는 것입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-3-해결-방법-the-solution"&gt;
 ✅ 3. 해결 방법 (The Solution)
 &lt;a class="heading-anchor" href="#-3-%ed%95%b4%ea%b2%b0-%eb%b0%a9%eb%b2%95-the-solution" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="step-31-커널-모듈-강제-로드"&gt;
 Step 3.1: 커널 모듈 강제 로드
 &lt;a class="heading-anchor" href="#step-31-%ec%bb%a4%eb%84%90-%eb%aa%a8%eb%93%88-%ea%b0%95%ec%a0%9c-%eb%a1%9c%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;먼저, &lt;code&gt;modprobe&lt;/code&gt; 명령어를 사용하여 즉시 모듈을 활성화합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# br_netfilter 모듈 로드&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo modprobe br_netfilter
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 모듈이 잘 올라왔는지 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;lsmod &lt;span class="p"&gt;|&lt;/span&gt; grep br_netfilter&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="step-32-커널-파라미터-활성화"&gt;
 Step 3.2: 커널 파라미터 활성화
 &lt;a class="heading-anchor" href="#step-32-%ec%bb%a4%eb%84%90-%ed%8c%8c%eb%9d%bc%eb%af%b8%ed%84%b0-%ed%99%9c%ec%84%b1%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;이제 파일 경로가 생겼으니, 필요한 설정값을 1(True)로 변경해 줍니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# bridge-nf-call-iptables 활성화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /proc/sys/net/bridge/bridge-nf-call-iptables
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# bridge-nf-call-ip6tables 활성화 (IPv6용)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;sudo &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /proc/sys/net/bridge/bridge-nf-call-ip6tables&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-4-재부팅-시에도-자동-적용하기-영구-설정"&gt;
 🔄 4. 재부팅 시에도 자동 적용하기 (영구 설정)
 &lt;a class="heading-anchor" href="#-4-%ec%9e%ac%eb%b6%80%ed%8c%85-%ec%8b%9c%ec%97%90%eb%8f%84-%ec%9e%90%eb%8f%99-%ec%a0%81%ec%9a%a9%ed%95%98%ea%b8%b0-%ec%98%81%ea%b5%ac-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;위의 과정만으로는 서버를 재부팅하면 다시 에러가 발생할 수 있습니다. 영구적으로 설정을 유지하려면 아래 작업을 꼭 추가해 주세요. 🌟&lt;/p&gt;
&lt;h3 id="41-모듈-자동-로드-설정"&gt;
 4.1 모듈 자동 로드 설정
 &lt;a class="heading-anchor" href="#41-%eb%aa%a8%eb%93%88-%ec%9e%90%eb%8f%99-%eb%a1%9c%eb%93%9c-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF | sudo tee /etc/modules-load.d/k8s.conf
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;br_netfilter
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="42-시스템-설정-파일에-등록"&gt;
 4.2 시스템 설정 파일에 등록
 &lt;a class="heading-anchor" href="#42-%ec%8b%9c%ec%8a%a4%ed%85%9c-%ec%84%a4%ec%a0%95-%ed%8c%8c%ec%9d%bc%ec%97%90-%eb%93%b1%eb%a1%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF | sudo tee /etc/sysctl.d/k8s.conf
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;net.bridge.bridge-nf-call-iptables = 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;net.bridge.bridge-nf-call-ip6tables = 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;net.ipv4.ip_forward = 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 설정 즉시 적용&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;sudo sysctl --system&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-5-결과-확인"&gt;
 🏁 5. 결과 확인
 &lt;a class="heading-anchor" href="#-5-%ea%b2%b0%ea%b3%bc-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;모든 설정을 마친 후 다시 &lt;code&gt;kubeadm init&lt;/code&gt;을 실행하면, 네트워크 관련 에러 없이 정상적으로 클러스터 초기화가 진행되는 것을 보실 수 있습니다! 🎉&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo kubeadm init --pod-network-cidr&lt;span class="o"&gt;=&lt;/span&gt;10.244.0.0/16&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Backend &amp; Web 경력직(3~5) 면접 정리</title><link>https://kyungryeol-yoon.github.io/cs/interview/backend-career-interview/</link><pubDate>Thu, 30 Jul 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/cs/interview/backend-career-interview/</guid><description>&lt;h3 id="java-testtdd-관련-어디까지-구성해보았는가보통-프로젝트-하나를-혼자서-담당하였다면-test-구문-짜는게-엄청-오래-걸리고-힘들다-혼자서-어디까지-커버하였는가"&gt;
 Java Test(TDD 관련) 어디까지 구성해보았는가?(보통 프로젝트 하나를 혼자서 담당하였다면 test 구문 짜는게 엄청 오래 걸리고 힘들다. 혼자서 어디까지 커버하였는가?)
 &lt;a class="heading-anchor" href="#java-testtdd-%ea%b4%80%eb%a0%a8-%ec%96%b4%eb%94%94%ea%b9%8c%ec%a7%80-%ea%b5%ac%ec%84%b1%ed%95%b4%eb%b3%b4%ec%95%98%eb%8a%94%ea%b0%80%eb%b3%b4%ed%86%b5-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ed%95%98%eb%82%98%eb%a5%bc-%ed%98%bc%ec%9e%90%ec%84%9c-%eb%8b%b4%eb%8b%b9%ed%95%98%ec%98%80%eb%8b%a4%eb%a9%b4-test-%ea%b5%ac%eb%ac%b8-%ec%a7%9c%eb%8a%94%ea%b2%8c-%ec%97%84%ec%b2%ad-%ec%98%a4%eb%9e%98-%ea%b1%b8%eb%a6%ac%ea%b3%a0-%ed%9e%98%eb%93%a4%eb%8b%a4-%ed%98%bc%ec%9e%90%ec%84%9c-%ec%96%b4%eb%94%94%ea%b9%8c%ec%a7%80-%ec%bb%a4%eb%b2%84%ed%95%98%ec%98%80%eb%8a%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;간단 메소드 테스트만 거치고 배포함. 매우 어려운 일인거 같다. 회사마다, 조직마다, 팀마다 전부 다를 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="데이터베이스에-데이터모델-복잡도는-어디까지-해보았는가외래키-각-테이블-엮임이-어느정도까지-되어-있는가"&gt;
 데이터베이스에 데이터모델 복잡도는 어디까지 해보았는가?(외래키, 각 테이블 엮임이 어느정도까지 되어 있는가?)
 &lt;a class="heading-anchor" href="#%eb%8d%b0%ec%9d%b4%ed%84%b0%eb%b2%a0%ec%9d%b4%ec%8a%a4%ec%97%90-%eb%8d%b0%ec%9d%b4%ed%84%b0%eb%aa%a8%eb%8d%b8-%eb%b3%b5%ec%9e%a1%eb%8f%84%eb%8a%94-%ec%96%b4%eb%94%94%ea%b9%8c%ec%a7%80-%ed%95%b4%eb%b3%b4%ec%95%98%eb%8a%94%ea%b0%80%ec%99%b8%eb%9e%98%ed%82%a4-%ea%b0%81-%ed%85%8c%ec%9d%b4%eb%b8%94-%ec%97%ae%ec%9e%84%ec%9d%b4-%ec%96%b4%eb%8a%90%ec%a0%95%eb%8f%84%ea%b9%8c%ec%a7%80-%eb%90%98%ec%96%b4-%ec%9e%88%eb%8a%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;DB 사용하고 있는 테이블만해도 이미 100개가 넘어가는데&amp;hellip; 물론 서로 연관도 많이 되어 있는 상태이기도 하고, 이걸 간단히 설명을 해보라는 것이&amp;hellip; 말하다 보니 꼬이기도 하고 ㅠㅠ 이건 솔직히 설명을 어떻게 효과적으로 해야할지 모르겠다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="스스로-특별한-기술을-만든적이-있는가이런-기능은-만들기-어렵다는-자체-기술이-있는가"&gt;
 스스로 특별한 기술을 만든적이 있는가?(이런 기능은 만들기 어렵다는 자체 기술이 있는가?)
 &lt;a class="heading-anchor" href="#%ec%8a%a4%ec%8a%a4%eb%a1%9c-%ed%8a%b9%eb%b3%84%ed%95%9c-%ea%b8%b0%ec%88%a0%ec%9d%84-%eb%a7%8c%eb%93%a0%ec%a0%81%ec%9d%b4-%ec%9e%88%eb%8a%94%ea%b0%80%ec%9d%b4%eb%9f%b0-%ea%b8%b0%eb%8a%a5%ec%9d%80-%eb%a7%8c%eb%93%a4%ea%b8%b0-%ec%96%b4%eb%a0%b5%eb%8b%a4%eb%8a%94-%ec%9e%90%ec%b2%b4-%ea%b8%b0%ec%88%a0%ec%9d%b4-%ec%9e%88%eb%8a%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;어떠한 서비스 같은 기능들은 만들었지만 그 기술이 과연 특별하다?! 잘 모르겠다. 근데 그 누가 만들지도 못하는 기술을 만들 정도의 실력이였으면&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="백엔드-개발자로서-설계는-어디까지-해보았는가"&gt;
 백엔드 개발자로서 설계는 어디까지 해보았는가?
 &lt;a class="heading-anchor" href="#%eb%b0%b1%ec%97%94%eb%93%9c-%ea%b0%9c%eb%b0%9c%ec%9e%90%eb%a1%9c%ec%84%9c-%ec%84%a4%ea%b3%84%eb%8a%94-%ec%96%b4%eb%94%94%ea%b9%8c%ec%a7%80-%ed%95%b4%eb%b3%b4%ec%95%98%eb%8a%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;MSA 설계 관련 질문 같은데&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="서버-이중화-삼중화는-어디까지-해보았는가오토-스케일러-인-아웃-관련하여도-어디까지-짜보았는가"&gt;
 서버 이중화 삼중화는 어디까지 해보았는가?(오토 스케일러 인 아웃 관련하여도 어디까지 짜보았는가?)
 &lt;a class="heading-anchor" href="#%ec%84%9c%eb%b2%84-%ec%9d%b4%ec%a4%91%ed%99%94-%ec%82%bc%ec%a4%91%ed%99%94%eb%8a%94-%ec%96%b4%eb%94%94%ea%b9%8c%ec%a7%80-%ed%95%b4%eb%b3%b4%ec%95%98%eb%8a%94%ea%b0%80%ec%98%a4%ed%86%a0-%ec%8a%a4%ec%bc%80%ec%9d%bc%eb%9f%ac-%ec%9d%b8-%ec%95%84%ec%9b%83-%ea%b4%80%eb%a0%a8%ed%95%98%ec%97%ac%eb%8f%84-%ec%96%b4%eb%94%94%ea%b9%8c%ec%a7%80-%ec%a7%9c%eb%b3%b4%ec%95%98%eb%8a%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;더 공부해야겠다&amp;hellip; 사용도 해보고&amp;hellip; 알아보기도 하고&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="리눅스-크론탭이-가끔-시간이-겹치거나-한-메소드가-꺼지지-않는-현상이-있는데-이럴-경우-어떻게-대처하였는가"&gt;
 리눅스 크론탭이 가끔 시간이 겹치거나 한 메소드가 꺼지지 않는 현상이 있는데 이럴 경우 어떻게 대처하였는가?
 &lt;a class="heading-anchor" href="#%eb%a6%ac%eb%88%85%ec%8a%a4-%ed%81%ac%eb%a1%a0%ed%83%ad%ec%9d%b4-%ea%b0%80%eb%81%94-%ec%8b%9c%ea%b0%84%ec%9d%b4-%ea%b2%b9%ec%b9%98%ea%b1%b0%eb%82%98-%ed%95%9c-%eb%a9%94%ec%86%8c%eb%93%9c%ea%b0%80-%ea%ba%bc%ec%a7%80%ec%a7%80-%ec%95%8a%eb%8a%94-%ed%98%84%ec%83%81%ec%9d%b4-%ec%9e%88%eb%8a%94%eb%8d%b0-%ec%9d%b4%eb%9f%b4-%ea%b2%bd%ec%9a%b0-%ec%96%b4%eb%96%bb%ea%b2%8c-%eb%8c%80%ec%b2%98%ed%95%98%ec%98%80%eb%8a%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;이런 현상은 보통 Kill 명령어를 써서 사용하였지만&amp;hellip; 면접관은 아니란다&amp;hellip; 리눅스 더 공부해야겠다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="톰캣-또는-프로젝트-메모리-관리는-어떻게-하였고-고객에게-배포하기-전에-테스트-또는-메모리-파악은-어디까지-어떻게-하였는가api를-수백개-수천개-날리는데-어떠한-프로그램을-썻는가-앵그리버드"&gt;
 톰캣 또는 프로젝트 메모리 관리는 어떻게 하였고, 고객에게 배포하기 전에 테스트 또는 메모리 파악은 어디까지 어떻게 하였는가?(api를 수백개 수천개 날리는데 어떠한 프로그램을 썻는가? 앵그리버드?)
 &lt;a class="heading-anchor" href="#%ed%86%b0%ec%ba%a3-%eb%98%90%eb%8a%94-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%eb%a9%94%eb%aa%a8%eb%a6%ac-%ea%b4%80%eb%a6%ac%eb%8a%94-%ec%96%b4%eb%96%bb%ea%b2%8c-%ed%95%98%ec%98%80%ea%b3%a0-%ea%b3%a0%ea%b0%9d%ec%97%90%ea%b2%8c-%eb%b0%b0%ed%8f%ac%ed%95%98%ea%b8%b0-%ec%a0%84%ec%97%90-%ed%85%8c%ec%8a%a4%ed%8a%b8-%eb%98%90%eb%8a%94-%eb%a9%94%eb%aa%a8%eb%a6%ac-%ed%8c%8c%ec%95%85%ec%9d%80-%ec%96%b4%eb%94%94%ea%b9%8c%ec%a7%80-%ec%96%b4%eb%96%bb%ea%b2%8c-%ed%95%98%ec%98%80%eb%8a%94%ea%b0%80api%eb%a5%bc-%ec%88%98%eb%b0%b1%ea%b0%9c-%ec%88%98%ec%b2%9c%ea%b0%9c-%eb%82%a0%eb%a6%ac%eb%8a%94%eb%8d%b0-%ec%96%b4%eb%96%a0%ed%95%9c-%ed%94%84%eb%a1%9c%ea%b7%b8%eb%9e%a8%ec%9d%84-%ec%8d%bb%eb%8a%94%ea%b0%80-%ec%95%b5%ea%b7%b8%eb%a6%ac%eb%b2%84%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;모르겟다&amp;hellip;PostMan으로 api 메모리 테스트정도까지 해보았지만&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="코드-리뷰는-어디까지-해보았는가"&gt;
 코드 리뷰는 어디까지 해보았는가?
 &lt;a class="heading-anchor" href="#%ec%bd%94%eb%93%9c-%eb%a6%ac%eb%b7%b0%eb%8a%94-%ec%96%b4%eb%94%94%ea%b9%8c%ec%a7%80-%ed%95%b4%eb%b3%b4%ec%95%98%eb%8a%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;솔직히 (핑계일수도 있지만) 회사에서 코드리뷰가 없다&amp;hellip; 스터디 같은 걸 해서 사람들이랑 해보지만 솔직히 실력도 다 비슷한데 누구의 소스를 보고 이게 더 낫다라는 말을 하기가&amp;hellip; 흠 그래서 요즘은 코딩테스트를 해보고 난 뒤 다른 사람들이 짜놓은 다양한걸 보려고 한다.(개인적으로 구글이라던가 큰 기업에 open api 소스를 보고 분석하는 것도 나름 도움이 되는거 같다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="자바-콜렉션-종류-각각-설명"&gt;
 자바 콜렉션 종류 각각 설명
 &lt;a class="heading-anchor" href="#%ec%9e%90%eb%b0%94-%ec%bd%9c%eb%a0%89%ec%85%98-%ec%a2%85%eb%a5%98-%ea%b0%81%ea%b0%81-%ec%84%a4%eb%aa%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;외우기보다는 직접 더 활용해봐야겠다. 요즘 코딩테스트 준비하는데 생각보다 자바8에 콜렉션이 정말 많다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="자바8부터-해쉬맵-여러-기능들이-생겻는데-생긴-이유기원에-대해서"&gt;
 자바8부터 해쉬맵 여러 기능들이 생겻는데 생긴 이유(기원에 대해서)
 &lt;a class="heading-anchor" href="#%ec%9e%90%eb%b0%948%eb%b6%80%ed%84%b0-%ed%95%b4%ec%89%ac%eb%a7%b5-%ec%97%ac%eb%9f%ac-%ea%b8%b0%eb%8a%a5%eb%93%a4%ec%9d%b4-%ec%83%9d%ea%b2%bb%eb%8a%94%eb%8d%b0-%ec%83%9d%ea%b8%b4-%ec%9d%b4%ec%9c%a0%ea%b8%b0%ec%9b%90%ec%97%90-%eb%8c%80%ed%95%b4%ec%84%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;간결한 코드 작성을 위해서 나온 줄 알았는데&amp;hellip;아니란다&amp;hellip; 구글링을 해도 안나온다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="스프링-aop-생긴-이유가-잇는데-설명인터페이스를-꼭-만들어야-하는데-이유-설명"&gt;
 스프링 aop 생긴 이유가 잇는데 설명(인터페이스를 꼭 만들어야 하는데 이유 설명)
 &lt;a class="heading-anchor" href="#%ec%8a%a4%ed%94%84%eb%a7%81-aop-%ec%83%9d%ea%b8%b4-%ec%9d%b4%ec%9c%a0%ea%b0%80-%ec%9e%87%eb%8a%94%eb%8d%b0-%ec%84%a4%eb%aa%85%ec%9d%b8%ed%84%b0%ed%8e%98%ec%9d%b4%ec%8a%a4%eb%a5%bc-%ea%bc%ad-%eb%a7%8c%eb%93%a4%ec%96%b4%ec%95%bc-%ed%95%98%eb%8a%94%eb%8d%b0-%ec%9d%b4%ec%9c%a0-%ec%84%a4%eb%aa%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;사용만 하였지 구체적인 이유를 더 찾아보아야겠다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="파이썬-케라스를-이용해서-학습-모델을-어떻게-만들었나설명을-햇는데-계속-아니라고-함"&gt;
 파이썬 케라스를 이용해서 학습 모델을 어떻게 만들었나?(설명을 햇는데 계속 아니라고 함)
 &lt;a class="heading-anchor" href="#%ed%8c%8c%ec%9d%b4%ec%8d%ac-%ec%bc%80%eb%9d%bc%ec%8a%a4%eb%a5%bc-%ec%9d%b4%ec%9a%a9%ed%95%b4%ec%84%9c-%ed%95%99%ec%8a%b5-%eb%aa%a8%eb%8d%b8%ec%9d%84-%ec%96%b4%eb%96%bb%ea%b2%8c-%eb%a7%8c%eb%93%a4%ec%97%88%eb%82%98%ec%84%a4%eb%aa%85%ec%9d%84-%ed%96%87%eb%8a%94%eb%8d%b0-%ea%b3%84%ec%86%8d-%ec%95%84%eb%8b%88%eb%9d%bc%ea%b3%a0-%ed%95%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;이 부분에 대해서는 조금 더 찾아봐야 할 거 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="스프링에-가장-큰-강점은-무엇인가파이썬-장고는-겁나-쉽다고-한다"&gt;
 스프링에 가장 큰 강점은 무엇인가?(파이썬 장고는 겁나 쉽다고 한다&amp;hellip;)
 &lt;a class="heading-anchor" href="#%ec%8a%a4%ed%94%84%eb%a7%81%ec%97%90-%ea%b0%80%ec%9e%a5-%ed%81%b0-%ea%b0%95%ec%a0%90%ec%9d%80-%eb%ac%b4%ec%97%87%ec%9d%b8%ea%b0%80%ed%8c%8c%ec%9d%b4%ec%8d%ac-%ec%9e%a5%ea%b3%a0%eb%8a%94-%ea%b2%81%eb%82%98-%ec%89%bd%eb%8b%a4%ea%b3%a0-%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;프레임워크의 장점을 설명하였고, 스프링만의 기능들? AOP라던가&amp;hellip; 무튼 면접관이 맘에 들어하지 않는거 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="jpa-n1-문제가-터지는데-이건-어떻게-해결하였는가난-경험이-없다고-햇는데-그럴수-없다고-함"&gt;
 jpa n+1 문제가 터지는데 이건 어떻게 해결하였는가?(난 경험이 없다고 햇는데 그럴수 없다고 함)
 &lt;a class="heading-anchor" href="#jpa-n1-%eb%ac%b8%ec%a0%9c%ea%b0%80-%ed%84%b0%ec%a7%80%eb%8a%94%eb%8d%b0-%ec%9d%b4%ea%b1%b4-%ec%96%b4%eb%96%bb%ea%b2%8c-%ed%95%b4%ea%b2%b0%ed%95%98%ec%98%80%eb%8a%94%ea%b0%80%eb%82%9c-%ea%b2%bd%ed%97%98%ec%9d%b4-%ec%97%86%eb%8b%a4%ea%b3%a0-%ed%96%87%eb%8a%94%eb%8d%b0-%ea%b7%b8%eb%9f%b4%ec%88%98-%ec%97%86%eb%8b%a4%ea%b3%a0-%ed%95%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;몇몇 해결방안이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mybtis에서-여러-테이블을-호출할때-어떻게-하였는가"&gt;
 MyBtis에서 여러 테이블을 호출할때 어떻게 하였는가?
 &lt;a class="heading-anchor" href="#mybtis%ec%97%90%ec%84%9c-%ec%97%ac%eb%9f%ac-%ed%85%8c%ec%9d%b4%eb%b8%94%ec%9d%84-%ed%98%b8%ec%b6%9c%ed%95%a0%eb%95%8c-%ec%96%b4%eb%96%bb%ea%b2%8c-%ed%95%98%ec%98%80%eb%8a%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;흠 설명을 하였지만 뭔가 아니라고 한다. 더 찾아보고 내가 쓰지 못한? 알지도 못한 부분이 있는거 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="옵셔널-얼마나-써보았고-자세하게-설명해달라"&gt;
 옵셔널 얼마나 써보았고 자세하게 설명해달라
 &lt;a class="heading-anchor" href="#%ec%98%b5%ec%85%94%eb%84%90-%ec%96%bc%eb%a7%88%eb%82%98-%ec%8d%a8%eb%b3%b4%ec%95%98%ea%b3%a0-%ec%9e%90%ec%84%b8%ed%95%98%ea%b2%8c-%ec%84%a4%eb%aa%85%ed%95%b4%eb%8b%ac%eb%9d%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;생각보다 자바의 콜렉션을 많이 활용안하고 주구장창 코드를 짯던거 같다. 이 부분도 많이 활용해보아야겠다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="추가적인-질문들사실-이해가-전혀-가지-않는-질문들"&gt;
 추가적인 질문들(사실 이해가 전혀 가지 않는 질문들&amp;hellip;)
 &lt;a class="heading-anchor" href="#%ec%b6%94%ea%b0%80%ec%a0%81%ec%9d%b8-%ec%a7%88%eb%ac%b8%eb%93%a4%ec%82%ac%ec%8b%a4-%ec%9d%b4%ed%95%b4%ea%b0%80-%ec%a0%84%ed%98%80-%ea%b0%80%ec%a7%80-%ec%95%8a%eb%8a%94-%ec%a7%88%eb%ac%b8%eb%93%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;자바의 스트림?스트리밍? 무슨 단어였는데 알아듣지 못하였다. 찾아봐야겠다. (ArrayList 설명 중에 나온거라 찾아보니 List 관련 Stream이였다&amp;hellip; 솔직히 사용해본적 거의 없다&amp;hellip; 이것도 코딩테스트하다 안거&amp;hellip; ㅠㅠ)&lt;/li&gt;
&lt;li&gt;자바의 해쉬맵의 여러 기능들이 AOP가 생긴 이유가 같다고 하였던가? 흠 이 부분도 질문 자체를 이해하기 어려웠다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] kubectl neat</title><link>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-kube-neat/</link><pubDate>Mon, 22 Jun 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-kube-neat/</guid><description>&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-o yaml&lt;/code&gt; 로 기존 리소스를 저장하면 아래와 같은 불필요한 정보도 추가되어 저장된다.
&lt;ol&gt;
&lt;li&gt;생성 타임스탬프 또는 일부 내부 ID와 같은 메타데이터&lt;/li&gt;
&lt;li&gt;누락된 속성을 기본값으로 채우기&lt;/li&gt;
&lt;li&gt;서비스 계정 토큰과 같은 승인 컨트롤러가 생성한 추가 시스템 속성&lt;/li&gt;
&lt;li&gt;상태 정보&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;k neat를 사용하여 정리된 yaml 을 얻을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="install-krew-first"&gt;
 Install krew first
 &lt;a class="heading-anchor" href="#install-krew-first" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Krew는 kubectl plugin을 쉽게 사용할 수 있게 해주는 도구입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Install krew 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes-sigs/krew"&gt;https://github.com/kubernetes-sigs/krew&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;(
 set -x; cd &amp;#34;$(mktemp -d)&amp;#34; &amp;amp;&amp;amp;
 OS=&amp;#34;$(uname | tr &amp;#39;[:upper:]&amp;#39; &amp;#39;[:lower:]&amp;#39;)&amp;#34; &amp;amp;&amp;amp;
 ARCH=&amp;#34;$(uname -m | sed -e &amp;#39;s/x86_64/amd64/&amp;#39; -e &amp;#39;s/\(arm\)\(64\)\?.*/\1\2/&amp;#39; -e &amp;#39;s/aarch64$/arm64/&amp;#39;)&amp;#34; &amp;amp;&amp;amp;
 KREW=&amp;#34;krew-${OS}_${ARCH}&amp;#34; &amp;amp;&amp;amp;
 curl -fsSLO &amp;#34;https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz&amp;#34; &amp;amp;&amp;amp;
 tar zxvf &amp;#34;${KREW}.tar.gz&amp;#34; &amp;amp;&amp;amp;
 ./&amp;#34;${KREW}&amp;#34; install krew
)&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="add-env-to-bashrc-or-zshrc"&gt;
 Add Env to bashrc or zshrc
 &lt;a class="heading-anchor" href="#add-env-to-bashrc-or-zshrc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;KREW_ROOT&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="p"&gt;/.krew&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="기본-구조"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl krew &lt;span class="o"&gt;[&lt;/span&gt;Command&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="install-neat-with-krew"&gt;
 Install neat with krew
 &lt;a class="heading-anchor" href="#install-neat-with-krew" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl krew install neat&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;kubectl-neat에 대한 설정 방법은 &lt;a href="https://github.com/itaysk/kubectl-neat"&gt;설치 문서&lt;/a&gt;를 참고
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="기본-구조-1"&gt;
 기본 구조
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;끝에 &lt;code&gt;k neat&lt;/code&gt;를 붙여준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pod &lt;span class="o"&gt;[&lt;/span&gt;pod-name&lt;span class="o"&gt;]&lt;/span&gt; -o yaml &lt;span class="p"&gt;|&lt;/span&gt; k neat&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Linux] 우분투(Ubuntu) 크롬(Chrome) 설치 및 다운로드</title><link>https://kyungryeol-yoon.github.io/linux/package/linux-install-chrome/</link><pubDate>Mon, 11 May 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/package/linux-install-chrome/</guid><description>&lt;h2 id="우분투ubuntu에서-크롬chrome-설치-및-다운로드"&gt;
 우분투(Ubuntu)에서 크롬(Chrome) 설치 및 다운로드
 &lt;a class="heading-anchor" href="#%ec%9a%b0%eb%b6%84%ed%88%acubuntu%ec%97%90%ec%84%9c-%ed%81%ac%eb%a1%acchrome-%ec%84%a4%ec%b9%98-%eb%b0%8f-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="단축키-ctrl--alt--t를-눌러-터미널창을-띄운-뒤-아래-명령어를-입력하여-크롬-브라우저-패키지-설치용-인증키를-받는다"&gt;
 단축키 Ctrl + Alt + T를 눌러 터미널창을 띄운 뒤 아래 명령어를 입력하여 크롬 브라우저 패키지 설치용 인증키를 받는다.
 &lt;a class="heading-anchor" href="#%eb%8b%a8%ec%b6%95%ed%82%a4-ctrl--alt--t%eb%a5%bc-%eb%88%8c%eb%9f%ac-%ed%84%b0%eb%af%b8%eb%84%90%ec%b0%bd%ec%9d%84-%eb%9d%84%ec%9a%b4-%eb%92%a4-%ec%95%84%eb%9e%98-%eb%aa%85%eb%a0%b9%ec%96%b4%eb%a5%bc-%ec%9e%85%eb%a0%a5%ed%95%98%ec%97%ac-%ed%81%ac%eb%a1%ac-%eb%b8%8c%eb%9d%bc%ec%9a%b0%ec%a0%80-%ed%8c%a8%ed%82%a4%ec%a7%80-%ec%84%a4%ec%b9%98%ec%9a%a9-%ec%9d%b8%ec%a6%9d%ed%82%a4%eb%a5%bc-%eb%b0%9b%eb%8a%94%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub &lt;span class="p"&gt;|&lt;/span&gt; sudo apt-key add -&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="크롬chrome-웹-브라우저-패키지를-다운로드-받을-ppa를-sourceslistd에-추가"&gt;
 크롬(Chrome) 웹 브라우저 패키지를 다운로드 받을 PPA를 sources.list.d에 추가
 &lt;a class="heading-anchor" href="#%ed%81%ac%eb%a1%acchrome-%ec%9b%b9-%eb%b8%8c%eb%9d%bc%ec%9a%b0%ec%a0%80-%ed%8c%a8%ed%82%a4%ec%a7%80%eb%a5%bc-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c-%eb%b0%9b%ec%9d%84-ppa%eb%a5%bc-sourceslistd%ec%97%90-%ec%b6%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo sh -c &lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /etc/apt/sources.list.d/google.list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="패키지-리스트를-업데이트"&gt;
 패키지 리스트를 업데이트
 &lt;a class="heading-anchor" href="#%ed%8c%a8%ed%82%a4%ec%a7%80-%eb%a6%ac%ec%8a%a4%ed%8a%b8%eb%a5%bc-%ec%97%85%eb%8d%b0%ec%9d%b4%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get update&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="크롬chrome을-설치"&gt;
 크롬(Chrome)을 설치
 &lt;a class="heading-anchor" href="#%ed%81%ac%eb%a1%acchrome%ec%9d%84-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get install google-chrome-stable&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="크롬chrome-설치를-위해-생성했던-파일을-제거"&gt;
 크롬(Chrome) 설치를 위해 생성했던 파일을 제거
 &lt;a class="heading-anchor" href="#%ed%81%ac%eb%a1%acchrome-%ec%84%a4%ec%b9%98%eb%a5%bc-%ec%9c%84%ed%95%b4-%ec%83%9d%ec%84%b1%ed%96%88%eb%8d%98-%ed%8c%8c%ec%9d%bc%ec%9d%84-%ec%a0%9c%ea%b1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ls /etc/apt/sources.list.d/google*
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo rm -rf /etc/apt/sources.list.d/google.list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] kubetail</title><link>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-kubetail/</link><pubDate>Wed, 15 Apr 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-kubetail/</guid><description>&lt;ul&gt;
&lt;li&gt;여러 POD의 로그를 동시에 조회하는 기능&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kubectl logs -f&lt;/code&gt;를 실행하는 것과 동일하지만 여러 Pod에 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="install-ubuntu"&gt;
 Install Ubuntu
 &lt;a class="heading-anchor" href="#install-ubuntu" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt install kubetail&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="install-mac-os"&gt;
 Install Mac OS
 &lt;a class="heading-anchor" href="#install-mac-os" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew tap johanhaleby/kubetail &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; brew install kubetail&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;kubetail에 대한 설정 방법은 &lt;a href="https://github.com/johanhaleby/kubetail"&gt;설치 문서&lt;/a&gt;를 참고하시기 바랍니다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="how-to-use"&gt;
 How to use
 &lt;a class="heading-anchor" href="#how-to-use" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="container-or-multiple-containers"&gt;
 Container or Multiple Containers
 &lt;a class="heading-anchor" href="#container-or-multiple-containers" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubetail app2 -c container1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubetail app2 -c container1 -c container2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="multiple-appspods"&gt;
 Multiple Apps(pods)
 &lt;a class="heading-anchor" href="#multiple-appspods" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubetail app1,app2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="deployment-or-daemonset"&gt;
 Deployment or DaemonSet
 &lt;a class="heading-anchor" href="#deployment-or-daemonset" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubetail &lt;span class="s2"&gt;&amp;#34;coredns-556f6dffc4-*&amp;#34;&lt;/span&gt; -n kube-system
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;Will tail &lt;span class="m"&gt;2&lt;/span&gt; logs...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;coredns-556f6dffc4-bd2mr
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;coredns-556f6dffc4-hbvdt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="label-selector"&gt;
 Label selector.
 &lt;a class="heading-anchor" href="#label-selector" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubetail --selector &lt;span class="nv"&gt;service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my-service --since 10m
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;kubetail --selector &lt;span class="nv"&gt;release&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;p-jm-han&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="regex"&gt;
 Regex
 &lt;a class="heading-anchor" href="#regex" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;kubetail &lt;span class="s2"&gt;&amp;#34;^app1|.*my-demo.*&amp;#34;&lt;/span&gt; --regex
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;kubetail &lt;span class="s1"&gt;&amp;#39;.*loki-read-*|.*loki-write-*&amp;#39;&lt;/span&gt; -n monitoring --regex
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;Using regex &lt;span class="s1"&gt;&amp;#39;.*loki-read-*|.*loki-write-*&amp;#39;&lt;/span&gt; to match pods
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;Will tail &lt;span class="m"&gt;6&lt;/span&gt; logs...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;loki-read-0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;loki-read-1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;loki-read-2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;loki-write-0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;loki-write-1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;loki-write-2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[명령어] &lt;code&gt;--help&lt;/code&gt;를 입력하면 더 다양한 옵션들을 찾을 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Docker] Network - no route to host 오류 원인과 해결 방법</title><link>https://kyungryeol-yoon.github.io/docker/docker-network-no-route-to-host/</link><pubDate>Mon, 02 Mar 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/docker/docker-network-no-route-to-host/</guid><description>&lt;h2 id="docker-container-no-route-to-host-오류-원인과-해결-방법"&gt;
 Docker Container &amp;ldquo;No Route to Host&amp;rdquo; 오류 원인과 해결 방법
 &lt;a class="heading-anchor" href="#docker-container-no-route-to-host-%ec%98%a4%eb%a5%98-%ec%9b%90%ec%9d%b8%ea%b3%bc-%ed%95%b4%ea%b2%b0-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Docker 환경에서 컨테이너 실행 중 다음과 같은 오류를 만날 때가 있다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;no route to host&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이 오류는 애플리케이션 문제가 아니라 &lt;strong&gt;네트워크 레벨(L3/L4) 문제&lt;/strong&gt;이다.&lt;br&gt;
즉, &lt;strong&gt;컨테이너에서 대상 서버까지 네트워크 경로를 찾을 수 없을 때&lt;/strong&gt; 발생한다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-언제-발생할까"&gt;
 📌 언제 발생할까?
 &lt;a class="heading-anchor" href="#-%ec%96%b8%ec%a0%9c-%eb%b0%9c%ec%83%9d%ed%95%a0%ea%b9%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;다음과 같은 상황에서 주로 발생한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너 → 외부 서버 접속&lt;/li&gt;
&lt;li&gt;컨테이너 → 호스트 서버 접속&lt;/li&gt;
&lt;li&gt;컨테이너 → 다른 컨테이너 접속&lt;/li&gt;
&lt;li&gt;방화벽에 의해 차단된 경우&lt;/li&gt;
&lt;li&gt;잘못된 IP 또는 포트로 접근한 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-대표적인-원인"&gt;
 📌 대표적인 원인
 &lt;a class="heading-anchor" href="#-%eb%8c%80%ed%91%9c%ec%a0%81%ec%9d%b8-%ec%9b%90%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1-대상-서버가-꺼져-있는-경우"&gt;
 1️⃣ 대상 서버가 꺼져 있는 경우
 &lt;a class="heading-anchor" href="#1-%eb%8c%80%ec%83%81-%ec%84%9c%eb%b2%84%ea%b0%80-%ea%ba%bc%ec%a0%b8-%ec%9e%88%eb%8a%94-%ea%b2%bd%ec%9a%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;접속하려는 서버가 실행 중이 아니라면 네트워크 경로를 찾을 수 없다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ping 대상IP&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="2-localhost를-잘못-사용한-경우-가장-흔함"&gt;
 2️⃣ localhost를 잘못 사용한 경우 (가장 흔함)
 &lt;a class="heading-anchor" href="#2-localhost%eb%a5%bc-%ec%9e%98%eb%aa%bb-%ec%82%ac%ec%9a%a9%ed%95%9c-%ea%b2%bd%ec%9a%b0-%ea%b0%80%ec%9e%a5-%ed%9d%94%ed%95%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;컨테이너 내부에서:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;localhost = 컨테이너 자기 자신&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;따라서 아래 요청은 실패한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl http://localhost:8080&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-해결-방법"&gt;
 ✅ 해결 방법
 &lt;a class="heading-anchor" href="#-%ed%95%b4%ea%b2%b0-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="mac--windows"&gt;
 Mac / Windows
 &lt;a class="heading-anchor" href="#mac--windows" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;host.docker.internal&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="linux"&gt;
 Linux
 &lt;a class="heading-anchor" href="#linux" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;172.17.0.1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;또는&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker run --network host ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="3-docker-네트워크-분리-문제"&gt;
 3️⃣ Docker 네트워크 분리 문제
 &lt;a class="heading-anchor" href="#3-docker-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac-%eb%b6%84%eb%a6%ac-%eb%ac%b8%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;서로 다른 Docker 네트워크에 연결된 컨테이너끼리는 통신할 수 없다.&lt;/p&gt;
&lt;p&gt;확인 방법:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker network ls
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;docker network inspect 네트워크명&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="4-방화벽-문제-매우-흔함"&gt;
 4️⃣ 방화벽 문제 (매우 흔함)
 &lt;a class="heading-anchor" href="#4-%eb%b0%a9%ed%99%94%eb%b2%bd-%eb%ac%b8%ec%a0%9c-%eb%a7%a4%ec%9a%b0-%ed%9d%94%ed%95%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;다음과 같은 보안 설정이 원인일 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Linux: &lt;code&gt;ufw&lt;/code&gt;, &lt;code&gt;firewalld&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;클라우드 환경: Security Group&lt;/li&gt;
&lt;li&gt;서버 레벨: &lt;code&gt;iptables&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;확인:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo ufw status&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="5-서버가-127001-로만-바인딩된-경우"&gt;
 5️⃣ 서버가 127.0.0.1 로만 바인딩된 경우
 &lt;a class="heading-anchor" href="#5-%ec%84%9c%eb%b2%84%ea%b0%80-127001-%eb%a1%9c%eb%a7%8c-%eb%b0%94%ec%9d%b8%eb%94%a9%eb%90%9c-%ea%b2%bd%ec%9a%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;예시:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;127.0.0.1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이 경우 외부에서 접근할 수 없다.&lt;/p&gt;
&lt;h3 id="-올바른-설정"&gt;
 ✅ 올바른 설정
 &lt;a class="heading-anchor" href="#-%ec%98%ac%eb%b0%94%eb%a5%b8-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;0.0.0.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-비슷한-오류와-차이점"&gt;
 📌 비슷한 오류와 차이점
 &lt;a class="heading-anchor" href="#-%eb%b9%84%ec%8a%b7%ed%95%9c-%ec%98%a4%eb%a5%98%ec%99%80-%ec%b0%a8%ec%9d%b4%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;오류&lt;/th&gt;
					&lt;th&gt;의미&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;connection refused&lt;/td&gt;
					&lt;td&gt;서버는 존재하지만 포트가 열려 있지 않음&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;timeout&lt;/td&gt;
					&lt;td&gt;응답 없음 (방화벽 가능성 높음)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;no route to host&lt;/td&gt;
					&lt;td&gt;네트워크 경로 자체가 없음&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-빠른-체크-리스트"&gt;
 📌 빠른 체크 리스트
 &lt;a class="heading-anchor" href="#-%eb%b9%a0%eb%a5%b8-%ec%b2%b4%ed%81%ac-%eb%a6%ac%ec%8a%a4%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1-컨테이너-내부에서-확인"&gt;
 1️⃣ 컨테이너 내부에서 확인
 &lt;a class="heading-anchor" href="#1-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%eb%82%b4%eb%b6%80%ec%97%90%ec%84%9c-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ping 대상IP
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;curl 대상IP:포트&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="2-호스트에서-포트-확인"&gt;
 2️⃣ 호스트에서 포트 확인
 &lt;a class="heading-anchor" href="#2-%ed%98%b8%ec%8a%a4%ed%8a%b8%ec%97%90%ec%84%9c-%ed%8f%ac%ed%8a%b8-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;netstat -tulnp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="-가장-흔한-원인-요약"&gt;
 📌 가장 흔한 원인 요약
 &lt;a class="heading-anchor" href="#-%ea%b0%80%ec%9e%a5-%ed%9d%94%ed%95%9c-%ec%9b%90%ec%9d%b8-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;localhost 잘못 사용&lt;/li&gt;
&lt;li&gt;서버가 0.0.0.0 으로 바인딩되지 않음&lt;/li&gt;
&lt;li&gt;방화벽 차단&lt;/li&gt;
&lt;li&gt;서로 다른 Docker 네트워크 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-마무리"&gt;
 ✨ 마무리
 &lt;a class="heading-anchor" href="#-%eb%a7%88%eb%ac%b4%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;no route to host&lt;/code&gt; 오류는 대부분 네트워크 설정 문제다.
애플리케이션 코드를 의심하기 전에 다음을 순서대로 점검해보자.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;IP가 맞는지&lt;/li&gt;
&lt;li&gt;포트가 열려 있는지&lt;/li&gt;
&lt;li&gt;네트워크가 연결되어 있는지&lt;/li&gt;
&lt;li&gt;방화벽이 막고 있지 않은지&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;기본적인 네트워크 흐름을 이해하고 접근하면 대부분 빠르게 해결할 수 있다.&lt;/p&gt;</description></item><item><title>[Kubernetes] RBAC</title><link>https://kyungryeol-yoon.github.io/kubernetes/security/kubernetes-rbac/</link><pubDate>Sat, 01 Feb 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/security/kubernetes-rbac/</guid><description>&lt;ul&gt;
&lt;li&gt;RBAC (Role-based Access Control)는 쿠버네티스 환경에서 Node 또는 네트워크 리소스 등 여러가지 접근 권한에 대한 Role 관리하는 작업 요소 이다.&lt;/li&gt;
&lt;li&gt;RBAC는 rbac.authorization.k8s.io API를 사용하며, K8s 1.8 이상부터 RBAC Mode가 Stable 한다.&lt;/li&gt;
&lt;li&gt;또한, RBAC 활성화를 위한 &amp;ndash;authorization-mode=RBAC 설정이 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="role--clusterrle"&gt;
 Role &amp;amp; ClusterRle
 &lt;a class="heading-anchor" href="#role--clusterrle" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Role : Default 라는 Namespace에 모든 Pod의 읽기권한(get, watch, list)을 설정하고 pod-read 라고 정의한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Role&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespaces&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod-read&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;// &amp;#34;&amp;#34; 는 Core API Group 을 나타냄.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;watch&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;list&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ClusterRole : Cluster 의 Secret 정보에 대한 읽기 권한을 설정하고 secret-read 라고 정의함. (Node, Endpoint, Namespace, Service 등 모든 권한 설정)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ClusterRole은 namespace 영역이 아니기 때문에 생략된다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRole&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;secret-read&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;secrets&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;watch&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;list&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Sample (admin-manager.yaml)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;admin-manager&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kube-system&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="rolebinding--clusterrolebinding"&gt;
 RoleBinding &amp;amp; ClusterRoleBinding
 &lt;a class="heading-anchor" href="#rolebinding--clusterrolebinding" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;RoleBinding 은 User, Team 단위의 권한 부여 기능이며, ClusterRoleBinding은 클러스터 단위의 권한 부여 기능을 나타낸다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;RoleBinding : Reference 라는 User 에게 Pod-read 권한 설정. 즉, Reference 라는 User는 Namespace가 Default인 모든 Pod을 읽기가 가능하다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;RoleBinding&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;read-pods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;subjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;User&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;reference&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;roleRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Role // Role &amp;amp; ClusterRole 적용.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod-reader // 바인딩할 Role &amp;amp; ClusterRole 이름과 일치해야 함.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;ClusterRoleBinding : ManagerGroup 에게 Secret-Read 권한 설정. 즉, Manager-Group 의 모든 사용자가 모든 Namespace에서 Secret 을 읽을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRoleBinding&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;read-secrets-global&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;subjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Group&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;manager-group&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;roleRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRole // Role &amp;amp; ClusterRole 적용&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;secret-read // 바인딩할 Role &amp;amp; ClusterRole 이름과 일치해야 함.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Sample (admin-rolebinding.yaml)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRoleBinding&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;admin-manager&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;subjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;admin-manager&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespcae&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kube-system&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;roleRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRole&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cluster-admin&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="k8s-api-호출-권한"&gt;
 K8s API 호출 권한
 &lt;a class="heading-anchor" href="#k8s-api-%ed%98%b8%ec%b6%9c-%ea%b6%8c%ed%95%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;K8s api 호출시 RBAC role 에 의한 접근 불가 오류 메세지 출력되면 K8s api 호출 error example - kryoon에서 pod에 대한 정보를 요청할 때 RBAC role에 막혔다&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;GET /api/v1/namespaces/&lt;span class="o"&gt;{&lt;/span&gt;namespace&lt;span class="o"&gt;}&lt;/span&gt;/pods/&lt;span class="o"&gt;{&lt;/span&gt;name&lt;span class="o"&gt;}&lt;/span&gt;/log
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;WARNING: Failed to count the &lt;span class="c1"&gt;# of live instances on Kubernetes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;io.fabric8.kubernetes.client.KubernetesClientException: Failure executing: GET
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;at: https://kubernetes.default/api/v1/namespaces/kryoon/pods.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;Message: Forbidden!Configured service account doesn&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;t have access.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;Service account may have been revoked. pods is forbidden:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;User &lt;span class="s2"&gt;&amp;#34;system:serviceaccount:kryoon:default&amp;#34;&lt;/span&gt; cannot list pods in the namespace &lt;span class="s2"&gt;&amp;#34;kryoon&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;Unknown user &lt;span class="s2"&gt;&amp;#34;system:serviceaccount:kryoon:default&amp;#34;&lt;/span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;아래와 같이 pod(resource), log(subresource of pods)에 대한 권한을 추가해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Role&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod-and-pod-logs-reader&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods/log&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;list&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Deploy MySQL</title><link>https://kyungryeol-yoon.github.io/database/mysql/kubernetes-deploy-mysql/</link><pubDate>Thu, 30 Jan 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/mysql/kubernetes-deploy-mysql/</guid><description>&lt;ul&gt;
&lt;li&gt;컨테이너 이미지가 존재한다는 가정하에 가능하다.&lt;/li&gt;
&lt;li&gt;만약 이미지가 없다면 Docker Hub에서 들고온다.
(&lt;a href="https://hub.docker.com/search?image_filter=official&amp;amp;type=image"&gt;https://hub.docker.com/search?image_filter=official&amp;amp;type=image&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Docker Hub의 공식적인 이미지가 아닌 것은 직접 만들어야 하며, 그 이미지를 Docker Hub에 올릴 수 있다.
(물론 전체 공개이며, 개인적으로 사용하고 싶다면 Private를 구매해야 한다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="kubectl-create-or-run"&gt;
 kubectl create or run
 &lt;a class="heading-anchor" href="#kubectl-create-or-run" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;run을 통해 이미지와 replicas 등 스펙들을 설정할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl run mysql-test --image&lt;span class="o"&gt;=&lt;/span&gt;mysql:5.7.8 --port&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3306&lt;/span&gt; --replicas&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; --env&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;MYSQL_ROOT_PASSWORD=testpw&amp;#34;&lt;/span&gt; --env&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;MYSQL_DATABASE=testdb&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="kubectl-apply"&gt;
 kubectl apply
 &lt;a class="heading-anchor" href="#kubectl-apply" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f mysql-test.yaml mysql-test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="yaml을-통한-명령어"&gt;
 yaml을 통한 명령어
 &lt;a class="heading-anchor" href="#yaml%ec%9d%84-%ed%86%b5%ed%95%9c-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;yaml을 통해 세부적으로 작성하기 편하며,
혹시나 pod에 대한 속성을 수정할 일이 있다면, 이전에는 어떻게 구성하였는지 확인하기 위해 yaml파일을 폴더 별로 관리를 추천한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql-test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3306&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# for versions before 1.9.0 use apps/v1beta2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql-test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Recreate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kube-node-1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql:5.7.8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql-test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Use secret in real usage&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;testpw&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3306&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql-test&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Error] kubectl error - did you specify the right host or port?</title><link>https://kyungryeol-yoon.github.io/kubernetes/troubleshooting/kubectl-error-connection-to-server/</link><pubDate>Wed, 29 Jan 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/troubleshooting/kubectl-error-connection-to-server/</guid><description>&lt;h2 id="the-connection-to-the-server-localhost8080-was-refused-오류-해결법"&gt;
 The connection to the server localhost:8080 was refused 오류 해결법
 &lt;a class="heading-anchor" href="#the-connection-to-the-server-localhost8080-was-refused-%ec%98%a4%eb%a5%98-%ed%95%b4%ea%b2%b0%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;kubectl 명령어를 입력하면 다음 오류 메시지가 발생하는 경우가 있습니다.
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;The connection to the server localhost:8080 was refused - did you specify the right host or port?&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="이-문제는-다음-명령어를-입력하면-해결이-됩니다"&gt;
 이 문제는 다음 명령어를 입력하면 해결이 됩니다.
 &lt;a class="heading-anchor" href="#%ec%9d%b4-%eb%ac%b8%ec%a0%9c%eb%8a%94-%eb%8b%a4%ec%9d%8c-%eb%aa%85%eb%a0%b9%ec%96%b4%eb%a5%bc-%ec%9e%85%eb%a0%a5%ed%95%98%eb%a9%b4-%ed%95%b4%ea%b2%b0%ec%9d%b4-%eb%90%a9%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mkdir -p &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo cp -i /etc/kubernetes/admin.conf &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo chown &lt;span class="k"&gt;$(&lt;/span&gt;id -u&lt;span class="k"&gt;)&lt;/span&gt;:&lt;span class="k"&gt;$(&lt;/span&gt;id -g&lt;span class="k"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;위에서 admin.conf 파일은 kubeadm init 명령어를 수행했을 때 생성됩니다.&lt;/li&gt;
&lt;li&gt;즉, master 노드에서만 kubectl 명령어를 사용할 수 있으며, 다른 노드에서 kubectl 명령어를 사용하고 싶을 때는 master 노드에서 생성한 admin.conf 파일을 복사해오면 일반 노드에서도 kubectl 명령어를 사용할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="unable-to-connect-to-the-server-x509-오류-해결법"&gt;
 Unable to connect to the server: x509 오류 해결법
 &lt;a class="heading-anchor" href="#unable-to-connect-to-the-server-x509-%ec%98%a4%eb%a5%98-%ed%95%b4%ea%b2%b0%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Unable to connect to the server: x509: certificate signed by unknown authority &lt;span class="o"&gt;(&lt;/span&gt;possibly because of &lt;span class="s2"&gt;&amp;#34;crypto/rsa: verification error&amp;#34;&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; trying to verify candidate authority certificate &lt;span class="s2"&gt;&amp;#34;kubernetes&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="이-문제는-다음-명령어를-입력하면-해결이-됩니다-1"&gt;
 이 문제는 다음 명령어를 입력하면 해결이 됩니다.
 &lt;a class="heading-anchor" href="#%ec%9d%b4-%eb%ac%b8%ec%a0%9c%eb%8a%94-%eb%8b%a4%ec%9d%8c-%eb%aa%85%eb%a0%b9%ec%96%b4%eb%a5%bc-%ec%9e%85%eb%a0%a5%ed%95%98%eb%a9%b4-%ed%95%b4%ea%b2%b0%ec%9d%b4-%eb%90%a9%eb%8b%88%eb%8b%a4-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/etc/kubernetes/admin.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Install Kubernetes(v1.11.0) on CentOS</title><link>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-kubernetesv1.11.0-on-centos/</link><pubDate>Tue, 28 Jan 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/cluster/install-kubernetesv1.11.0-on-centos/</guid><description>&lt;h2 id="configure-the-master-node"&gt;
 Configure the master node
 &lt;a class="heading-anchor" href="#configure-the-master-node" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Preparation
Run the following commands to pass bridged IP traffic to iptables chains&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ yum update -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ modprobe br_netfilter
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF &amp;gt; /etc/sysctl.d/k8s.conf
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;net.bridge.bridge-nf-call-ip6tables = 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;net.bridge.bridge-nf-call-iptables = 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ sysctl --system&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;2a) Allow the necessary ports trough the firewall when you’re working in an unsafe environment or in production&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;firewall-cmd --zone&lt;span class="o"&gt;=&lt;/span&gt;public --add-port&lt;span class="o"&gt;=&lt;/span&gt;6443/tcp --permanent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;firewall-cmd --zone&lt;span class="o"&gt;=&lt;/span&gt;public --add-port&lt;span class="o"&gt;=&lt;/span&gt;80/tcp --permanent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;firewall-cmd --zone&lt;span class="o"&gt;=&lt;/span&gt;public --add-port&lt;span class="o"&gt;=&lt;/span&gt;443/tcp --permanent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;firewall-cmd --zone&lt;span class="o"&gt;=&lt;/span&gt;public --add-port&lt;span class="o"&gt;=&lt;/span&gt;18080/tcp --permanent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;firewall-cmd --zone&lt;span class="o"&gt;=&lt;/span&gt;public --add-port&lt;span class="o"&gt;=&lt;/span&gt;10254/tcp --permanent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;firewall-cmd --reload&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;2b) If you’re just testing this in a safe lab environment you can disable the firewall.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ systemctl stop firewalld &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; systemctl disable firewalld&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Check if selinux is Enabled with the following command&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ sestatus&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If the current mode is enforcing then you need to change the mode to permissive or disabled.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ sed -i --follow-symlinks &lt;span class="s1"&gt;&amp;#39;s/SELINUX=enforcing/SELINUX=permissive/g&amp;#39;&lt;/span&gt; /etc/sysconfig/selinux
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ setenforce &lt;span class="m"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Kubernetes doesn’t want to use swap so it can offer the best performance, so we have to disable it.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ swapoff -a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ vi /etc/fstab
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#/dev/mapper/centos-swap swap swap defaults 0 0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;6a) Add the kubernetes repository to yum&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ cat &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF &amp;gt; /etc/yum.repos.d/kubernetes.repo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;[kubernetes]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;name=Kubernetes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;enabled=1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;gpgcheck=1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;repo_gpgcheck=1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;6b) Add the official docker repo to yum&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ yum install -y yum-utils device-mapper-persistent-data lvm2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Installation
Install kubeadm and docker&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ yum install -y ebtables ethtool docker-ce kubelet kubeadm kubectl&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Start docker and enable it at boot&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ systemctl start docker &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; docker&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Start kubelet and enable it at boot&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ systemctl start kubelet &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; kubelet&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Initialize kubernetes. Be aware, for some pod network implementations you might need to add a specific ‘–pod-network-cidr=’ setting. Please check &lt;a href="https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network"&gt;https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network&lt;/a&gt; before continuing.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ kubeadm init --pod-network-cidr&lt;span class="o"&gt;=&lt;/span&gt;10.244.0.0/16
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;I0715 12:50:01.543998 &lt;span class="m"&gt;1958&lt;/span&gt; feature_gate.go:230&lt;span class="o"&gt;]&lt;/span&gt; feature gates: &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;map&lt;span class="o"&gt;[]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;init&lt;span class="o"&gt;]&lt;/span&gt; using Kubernetes version: v1.11.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;preflight&lt;span class="o"&gt;]&lt;/span&gt; running pre-flight checks
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;I0715 12:50:01.577212 &lt;span class="m"&gt;1958&lt;/span&gt; kernel_validator.go:81&lt;span class="o"&gt;]&lt;/span&gt; Validating kernel version
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;I0715 12:50:01.577289 &lt;span class="m"&gt;1958&lt;/span&gt; kernel_validator.go:96&lt;span class="o"&gt;]&lt;/span&gt; Validating kernel config
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;preflight/images&lt;span class="o"&gt;]&lt;/span&gt; Pulling images required &lt;span class="k"&gt;for&lt;/span&gt; setting up a Kubernetes cluster
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;preflight/images&lt;span class="o"&gt;]&lt;/span&gt; This might take a minute or two, depending on the speed of your internet connection
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;preflight/images&lt;span class="o"&gt;]&lt;/span&gt; You can also perform this action in beforehand using &lt;span class="s1"&gt;&amp;#39;kubeadm config images pull&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;kubelet&lt;span class="o"&gt;]&lt;/span&gt; Writing kubelet environment file with flags to file &lt;span class="s2"&gt;&amp;#34;/var/lib/kubelet/kubeadm-flags.env&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;kubelet&lt;span class="o"&gt;]&lt;/span&gt; Writing kubelet configuration to file &lt;span class="s2"&gt;&amp;#34;/var/lib/kubelet/config.yaml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;preflight&lt;span class="o"&gt;]&lt;/span&gt; Activating the kubelet service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;certificates&lt;span class="o"&gt;]&lt;/span&gt; Generated ca certificate and key.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;certificates&lt;span class="o"&gt;]&lt;/span&gt; Generated apiserver certificate and key.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;certificates&lt;span class="o"&gt;]&lt;/span&gt; apiserver serving cert is signed &lt;span class="k"&gt;for&lt;/span&gt; DNS names &lt;span class="o"&gt;[&lt;/span&gt;test-vm1.home.lcl kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local&lt;span class="o"&gt;]&lt;/span&gt; and IPs &lt;span class="o"&gt;[&lt;/span&gt;10.96.0.1 192.168.1.221&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;certificates&lt;span class="o"&gt;]&lt;/span&gt; Generated apiserver-kubelet-client certificate and key.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;certificates&lt;span class="o"&gt;]&lt;/span&gt; Generated sa key and public key.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;certificates&lt;span class="o"&gt;]&lt;/span&gt; Generated front-proxy-ca certificate and key.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;certificates&lt;span class="o"&gt;]&lt;/span&gt; Generated front-proxy-client certificate and key.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;certificates&lt;span class="o"&gt;]&lt;/span&gt; Generated etcd/ca certificate and key.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;certificates&lt;span class="o"&gt;]&lt;/span&gt; Generated etcd/server certificate and key.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;certificates&lt;span class="o"&gt;]&lt;/span&gt; etcd/server serving cert is signed &lt;span class="k"&gt;for&lt;/span&gt; DNS names &lt;span class="o"&gt;[&lt;/span&gt;test-vm1.home.lcl localhost&lt;span class="o"&gt;]&lt;/span&gt; and IPs &lt;span class="o"&gt;[&lt;/span&gt;127.0.0.1 ::1&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;certificates&lt;span class="o"&gt;]&lt;/span&gt; Generated etcd/peer certificate and key.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;certificates&lt;span class="o"&gt;]&lt;/span&gt; etcd/peer serving cert is signed &lt;span class="k"&gt;for&lt;/span&gt; DNS names &lt;span class="o"&gt;[&lt;/span&gt;test-vm1.home.lcl localhost&lt;span class="o"&gt;]&lt;/span&gt; and IPs &lt;span class="o"&gt;[&lt;/span&gt;192.168.1.221 127.0.0.1 ::1&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;certificates&lt;span class="o"&gt;]&lt;/span&gt; Generated etcd/healthcheck-client certificate and key.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;certificates&lt;span class="o"&gt;]&lt;/span&gt; Generated apiserver-etcd-client certificate and key.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;certificates&lt;span class="o"&gt;]&lt;/span&gt; valid certificates and keys now exist in &lt;span class="s2"&gt;&amp;#34;/etc/kubernetes/pki&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;kubeconfig&lt;span class="o"&gt;]&lt;/span&gt; Wrote KubeConfig file to disk: &lt;span class="s2"&gt;&amp;#34;/etc/kubernetes/admin.conf&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;kubeconfig&lt;span class="o"&gt;]&lt;/span&gt; Wrote KubeConfig file to disk: &lt;span class="s2"&gt;&amp;#34;/etc/kubernetes/kubelet.conf&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;kubeconfig&lt;span class="o"&gt;]&lt;/span&gt; Wrote KubeConfig file to disk: &lt;span class="s2"&gt;&amp;#34;/etc/kubernetes/controller-manager.conf&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;kubeconfig&lt;span class="o"&gt;]&lt;/span&gt; Wrote KubeConfig file to disk: &lt;span class="s2"&gt;&amp;#34;/etc/kubernetes/scheduler.conf&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;controlplane&lt;span class="o"&gt;]&lt;/span&gt; wrote Static Pod manifest &lt;span class="k"&gt;for&lt;/span&gt; component kube-apiserver to &lt;span class="s2"&gt;&amp;#34;/etc/kubernetes/manifests/kube-apiserver.yaml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;controlplane&lt;span class="o"&gt;]&lt;/span&gt; wrote Static Pod manifest &lt;span class="k"&gt;for&lt;/span&gt; component kube-controller-manager to &lt;span class="s2"&gt;&amp;#34;/etc/kubernetes/manifests/kube-controller-manager.yaml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;controlplane&lt;span class="o"&gt;]&lt;/span&gt; wrote Static Pod manifest &lt;span class="k"&gt;for&lt;/span&gt; component kube-scheduler to &lt;span class="s2"&gt;&amp;#34;/etc/kubernetes/manifests/kube-scheduler.yaml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;etcd&lt;span class="o"&gt;]&lt;/span&gt; Wrote Static Pod manifest &lt;span class="k"&gt;for&lt;/span&gt; a &lt;span class="nb"&gt;local&lt;/span&gt; etcd instance to &lt;span class="s2"&gt;&amp;#34;/etc/kubernetes/manifests/etcd.yaml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;init&lt;span class="o"&gt;]&lt;/span&gt; waiting &lt;span class="k"&gt;for&lt;/span&gt; the kubelet to boot up the control plane as Static Pods from directory &lt;span class="s2"&gt;&amp;#34;/etc/kubernetes/manifests&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;init&lt;span class="o"&gt;]&lt;/span&gt; this might take a minute or longer &lt;span class="k"&gt;if&lt;/span&gt; the control plane images have to be pulled
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;apiclient&lt;span class="o"&gt;]&lt;/span&gt; All control plane components are healthy after 43.502080 seconds
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;uploadconfig&lt;span class="o"&gt;]&lt;/span&gt; storing the configuration used in ConfigMap &lt;span class="s2"&gt;&amp;#34;kubeadm-config&amp;#34;&lt;/span&gt; in the &lt;span class="s2"&gt;&amp;#34;kube-system&amp;#34;&lt;/span&gt; Namespace
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;kubelet&lt;span class="o"&gt;]&lt;/span&gt; Creating a ConfigMap &lt;span class="s2"&gt;&amp;#34;kubelet-config-1.11&amp;#34;&lt;/span&gt; in namespace kube-system with the configuration &lt;span class="k"&gt;for&lt;/span&gt; the kubelets in the cluster
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;markmaster&lt;span class="o"&gt;]&lt;/span&gt; Marking the node test-vm1.home.lcl as master by adding the label &lt;span class="s2"&gt;&amp;#34;node-role.kubernetes.io/master=&amp;#39;&amp;#39;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;markmaster&lt;span class="o"&gt;]&lt;/span&gt; Marking the node test-vm1.home.lcl as master by adding the taints &lt;span class="o"&gt;[&lt;/span&gt;node-role.kubernetes.io/master:NoSchedule&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;patchnode&lt;span class="o"&gt;]&lt;/span&gt; Uploading the CRI Socket information &lt;span class="s2"&gt;&amp;#34;/var/run/dockershim.sock&amp;#34;&lt;/span&gt; to the Node API object &lt;span class="s2"&gt;&amp;#34;test-vm1.home.lcl&amp;#34;&lt;/span&gt; as an annotation
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;bootstraptoken&lt;span class="o"&gt;]&lt;/span&gt; using token: e8yb38.htt4pz8dmxq77jha
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;bootstraptoken&lt;span class="o"&gt;]&lt;/span&gt; configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order &lt;span class="k"&gt;for&lt;/span&gt; nodes to get long term certificate credentials
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;bootstraptoken&lt;span class="o"&gt;]&lt;/span&gt; configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;bootstraptoken&lt;span class="o"&gt;]&lt;/span&gt; configured RBAC rules to allow certificate rotation &lt;span class="k"&gt;for&lt;/span&gt; all node client certificates in the cluster
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;bootstraptoken&lt;span class="o"&gt;]&lt;/span&gt; creating the &lt;span class="s2"&gt;&amp;#34;cluster-info&amp;#34;&lt;/span&gt; ConfigMap in the &lt;span class="s2"&gt;&amp;#34;kube-public&amp;#34;&lt;/span&gt; namespace
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;addons&lt;span class="o"&gt;]&lt;/span&gt; Applied essential addon: CoreDNS
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;addons&lt;span class="o"&gt;]&lt;/span&gt; Applied essential addon: kube-proxy
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;Your Kubernetes master has initialized successfully!
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;To start using your cluster, you need to run the following as a regular user:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt; mkdir -p &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;57&lt;/span&gt;&lt;span class="cl"&gt; sudo cp -i /etc/kubernetes/admin.conf &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;58&lt;/span&gt;&lt;span class="cl"&gt; sudo chown &lt;span class="k"&gt;$(&lt;/span&gt;id -u&lt;span class="k"&gt;)&lt;/span&gt;:&lt;span class="k"&gt;$(&lt;/span&gt;id -g&lt;span class="k"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;59&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;60&lt;/span&gt;&lt;span class="cl"&gt;You should now deploy a pod network to the cluster.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;61&lt;/span&gt;&lt;span class="cl"&gt;Run &lt;span class="s2"&gt;&amp;#34;kubectl apply -f [podnetwork].yaml&amp;#34;&lt;/span&gt; with one of the options listed at:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;62&lt;/span&gt;&lt;span class="cl"&gt; https://kubernetes.io/docs/concepts/cluster-administration/addons/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;63&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;64&lt;/span&gt;&lt;span class="cl"&gt;You can now join any number of machines by running the following on each node
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;65&lt;/span&gt;&lt;span class="cl"&gt;as root:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;66&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;67&lt;/span&gt;&lt;span class="cl"&gt; kubeadm join 192.168.1.221:6443 --token e8yb38.hqq4pz9dmlq77jha --discovery-token-ca-cert-hash sha256:50b01f19d8060ba593a009d134912d62b95ca80fdbe76f3995c8ba6c4a92c705&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Create admin user&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ groupadd -g &lt;span class="m"&gt;1000&lt;/span&gt; k8sadm
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ useradd -u &lt;span class="m"&gt;1000&lt;/span&gt; -g k8sadm -G wheel k8sadm
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ passwd k8sadm
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;Changing password &lt;span class="k"&gt;for&lt;/span&gt; user k8sadm.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;New password:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;Retype new password:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;passwd: all authentication tokens updated successfully.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ su - k8sadm
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;k8sadm@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ mkdir -p &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;k8sadm@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ sudo cp -i /etc/kubernetes/admin.conf &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;k8sadm@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ sudo chown &lt;span class="k"&gt;$(&lt;/span&gt;id -u&lt;span class="k"&gt;)&lt;/span&gt;:&lt;span class="k"&gt;$(&lt;/span&gt;id -g&lt;span class="k"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Configure the pod network&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;k8sadm@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ kubectl get nodes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;NAME STATUS ROLES AGE VERSION
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;test-vm1.home.lcl NotReady master 2m v1.11.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;k8sadm@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;k8sadm@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ kubectl get nodes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;NAME STATUS ROLES AGE VERSION
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;test-vm1.home.lcl Ready master 3m v1.11.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;k8sadm@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ kubectl get pods --all-namespaces
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;NAMESPACE NAME READY STATUS RESTARTS AGE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;kube-system coredns-78fcdf6894-g7rg4 1/1 Running &lt;span class="m"&gt;0&lt;/span&gt; 2h
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;kube-system coredns-78fcdf6894-vr4xm 1/1 Running &lt;span class="m"&gt;0&lt;/span&gt; 2h
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;kube-system etcd-test-vm1.home.lcl 1/1 Running &lt;span class="m"&gt;1&lt;/span&gt; 2h
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;kube-system kube-apiserver-test-vm1.home.lcl 1/1 Running &lt;span class="m"&gt;1&lt;/span&gt; 2h
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;kube-system kube-controller-manager-test-vm1.home.lcl 1/1 Running &lt;span class="m"&gt;1&lt;/span&gt; 2h
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;kube-system kube-proxy-524ql 1/1 Running &lt;span class="m"&gt;1&lt;/span&gt; 2h
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;kube-system kube-scheduler-test-vm1.home.lcl 1/1 Running &lt;span class="m"&gt;1&lt;/span&gt; 2h
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;kube-system kube-flannel-ds-45d87 1/1 Running &lt;span class="m"&gt;1&lt;/span&gt; 2h
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;kube-system kube-flannel-ds-bqh8j 1/1 Running &lt;span class="m"&gt;1&lt;/span&gt; 2h
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;kube-system kube-flannel-ds-dfldc 1/1 Running &lt;span class="m"&gt;1&lt;/span&gt; 2h&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="configure-the-worker-nodes"&gt;
 Configure the worker nodes
 &lt;a class="heading-anchor" href="#configure-the-worker-nodes" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Repeat steps 1 to 6 on all worker nodes&lt;/p&gt;
&lt;p&gt;Install docker and kubeadm&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm2 ~&lt;span class="o"&gt;]&lt;/span&gt;$ yum install -y kubeadm docker-ce kubelet
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm3 ~&lt;span class="o"&gt;]&lt;/span&gt;$ yum install -y kubeadm docker-ce kubelet&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Start docker and enable it at boot&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm2 ~&lt;span class="o"&gt;]&lt;/span&gt;$ systemctl start docker &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm3 ~&lt;span class="o"&gt;]&lt;/span&gt;$ systemctl start docker &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; docker&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Start kubelet and enable it at boot&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm2 ~&lt;span class="o"&gt;]&lt;/span&gt;$ systemctl start kubelet &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; kubelet
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm3 ~&lt;span class="o"&gt;]&lt;/span&gt;$ systemctl start kubelet &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; kubelet&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Join the workers to the master
use the command kubeadm returned in step 10&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm2 ~&lt;span class="o"&gt;]&lt;/span&gt;$ kubeadm join 192.168.1.221:6443 --token e8yb38.hqq4pz9dmlq77jha --discovery-token-ca-cert-hash sha256:50b01f19d8060ba593a009d134912d62b95ca80fdbe76f3995c8ba6c4a92c705
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@test-vm3 ~&lt;span class="o"&gt;]&lt;/span&gt;$ kubeadm join 192.168.1.221:6443 --token e8yb38.hqq4pz9dmlq77jha --discovery-token-ca-cert-hash sha256:50b01f19d8060ba593a009d134912d62b95ca80fdbe76f3995c8ba6c4a92c705&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;verify the status
after a little while you will see&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;k8sadm@test-vm1 ~&lt;span class="o"&gt;]&lt;/span&gt;$ kubectl get nodes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;NAME STATUS ROLES AGE VERSION
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;test-vm1.home.lcl Ready master 26m v1.11.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;test-vm2.home.lcl Ready &amp;lt;none&amp;gt; 1m v1.11.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;test-vm3.home.lcl Ready &amp;lt;none&amp;gt; 1m v1.11.1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Kubernetes] Pod Security Policy 완벽 가이드 (PSP, 보안 정책 관리)</title><link>https://kyungryeol-yoon.github.io/kubernetes/security/kubernetes-pod-security-policy-guide/</link><pubDate>Sat, 11 Jan 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/security/kubernetes-pod-security-policy-guide/</guid><description>&lt;h2 id="-kubernetes-pod-security-policy-psp"&gt;
 ☸️ Kubernetes Pod Security Policy (PSP)
 &lt;a class="heading-anchor" href="#-kubernetes-pod-security-policy-psp" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes에서 컨테이너 보안을 강화하려면 &lt;strong&gt;Pod의 실행 방식 자체를 제한&lt;/strong&gt;할 필요가 있습니다.&lt;/p&gt;
&lt;p&gt;예를 들어 다음과 같은 정책이 필요할 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너는 &lt;strong&gt;root 권한 사용 금지&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;privileged 컨테이너 실행 금지&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;host network 사용 금지&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이러한 &lt;strong&gt;Pod 보안 정책을 정의하는 기능&lt;/strong&gt;이 바로 &lt;strong&gt;Pod Security Policy (PSP)&lt;/strong&gt; 입니다.&lt;/p&gt;
&lt;p&gt;Security Context가 &lt;strong&gt;Pod 내부 설정&lt;/strong&gt;이라면&lt;br&gt;
PSP는 &lt;strong&gt;클러스터 수준에서 강제하는 보안 정책&lt;/strong&gt;이라고 이해하면 됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="kubernetes-보안-구조"&gt;
 Kubernetes 보안 구조
 &lt;a class="heading-anchor" href="#kubernetes-%eb%b3%b4%ec%95%88-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

User --&amp;gt; APIserver

APIserver --&amp;gt; PSP

PSP --&amp;gt; PodSpec

PodSpec --&amp;gt; SecurityContext

SecurityContext --&amp;gt; Container&lt;/pre&gt;
&lt;p&gt;Pod 생성 과정&lt;/p&gt;
&lt;p&gt;1️⃣ 사용자가 Pod 생성 요청
2️⃣ API Server가 PSP 정책 확인
3️⃣ Pod 설정이 정책을 만족하면 생성
4️⃣ 정책 위반 시 생성 실패&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="security-context-vs-psp"&gt;
 Security Context vs PSP
 &lt;a class="heading-anchor" href="#security-context-vs-psp" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;Security Context&lt;/th&gt;
					&lt;th&gt;Pod Security Policy&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;적용 범위&lt;/td&gt;
					&lt;td&gt;Pod / Container&lt;/td&gt;
					&lt;td&gt;Cluster&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;역할&lt;/td&gt;
					&lt;td&gt;Pod 보안 설정&lt;/td&gt;
					&lt;td&gt;보안 정책 강제&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;설정 위치&lt;/td&gt;
					&lt;td&gt;Pod YAML&lt;/td&gt;
					&lt;td&gt;Cluster Resource&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;목적&lt;/td&gt;
					&lt;td&gt;실행 권한 설정&lt;/td&gt;
					&lt;td&gt;정책 통제&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;즉&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Security Context → Pod 설정&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PSP → 정책 enforcement&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="pod-security-policy-동작-방식"&gt;
 Pod Security Policy 동작 방식
 &lt;a class="heading-anchor" href="#pod-security-policy-%eb%8f%99%ec%9e%91-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

User --&amp;gt; PodRequest

PodRequest --&amp;gt; APIserver

APIserver --&amp;gt; PSPCheck

PSPCheck --&amp;gt;|Allowed| PodCreated
PSPCheck --&amp;gt;|Denied| PodRejected&lt;/pre&gt;
&lt;p&gt;Pod 생성 시&lt;/p&gt;
&lt;p&gt;✔ PSP 정책을 만족하면 생성
❌ 정책 위반 시 생성 실패&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="psp에서-제어-가능한-보안-항목"&gt;
 PSP에서 제어 가능한 보안 항목
 &lt;a class="heading-anchor" href="#psp%ec%97%90%ec%84%9c-%ec%a0%9c%ec%96%b4-%ea%b0%80%eb%8a%a5%ed%95%9c-%eb%b3%b4%ec%95%88-%ed%95%ad%eb%aa%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Pod Security Policy는 다양한 보안 항목을 제어할 수 있습니다.&lt;/p&gt;
&lt;p&gt;대표적인 정책&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;정책&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;privileged&lt;/td&gt;
					&lt;td&gt;privileged container 허용 여부&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;hostNetwork&lt;/td&gt;
					&lt;td&gt;host 네트워크 사용&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;hostPID&lt;/td&gt;
					&lt;td&gt;host PID namespace 사용&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;hostIPC&lt;/td&gt;
					&lt;td&gt;host IPC 사용&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;runAsUser&lt;/td&gt;
					&lt;td&gt;컨테이너 사용자&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;fsGroup&lt;/td&gt;
					&lt;td&gt;파일 시스템 그룹&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;volumes&lt;/td&gt;
					&lt;td&gt;볼륨 타입&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;capabilities&lt;/td&gt;
					&lt;td&gt;Linux capability&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="pod-security-policy-예제"&gt;
 Pod Security Policy 예제
 &lt;a class="heading-anchor" href="#pod-security-policy-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;root 사용자 실행을 금지하는 PSP 예제입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;policy/v1beta1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PodSecurityPolicy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nonroot-psp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;MustRunAsNonRoot&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;seLinux&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;RunAsAny&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;supplementalGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;RunAsAny&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fsGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;RunAsAny&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s1"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이 정책의 핵심&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;runAsUser: MustRunAsNonRoot&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;즉&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;컨테이너가 root로 실행되는 것을 금지합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="psp-적용-구조"&gt;
 PSP 적용 구조
 &lt;a class="heading-anchor" href="#psp-%ec%a0%81%ec%9a%a9-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;PSP는 &lt;strong&gt;RBAC을 통해 사용자에게 연결해야 합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

PSP --&amp;gt; ClusterRole

ClusterRole --&amp;gt; ClusterRoleBinding

ClusterRoleBinding --&amp;gt; ServiceAccount

ServiceAccount --&amp;gt; Pod&lt;/pre&gt;
&lt;p&gt;즉 흐름은&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;PSP
 → ClusterRole
 → ClusterRoleBinding
 → ServiceAccount
 → Pod&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="serviceaccount-생성"&gt;
 ServiceAccount 생성
 &lt;a class="heading-anchor" href="#serviceaccount-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nonroot-sa&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="clusterrole-생성"&gt;
 ClusterRole 생성
 &lt;a class="heading-anchor" href="#clusterrole-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;PSP를 사용할 수 있는 권한을 정의합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRole&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nonroot-clusterrole&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;policy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;podsecuritypolicies&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resourceNames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nonroot-psp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;use&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="clusterrolebinding-생성"&gt;
 ClusterRoleBinding 생성
 &lt;a class="heading-anchor" href="#clusterrolebinding-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;서비스 계정과 ClusterRole을 연결합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRoleBinding&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nonroot-clusterrole-binding&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;subjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nonroot-sa&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;roleRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRole&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nonroot-clusterrole&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="deployment-적용-예제"&gt;
 Deployment 적용 예제
 &lt;a class="heading-anchor" href="#deployment-%ec%a0%81%ec%9a%a9-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;이제 PSP 정책을 사용하는 Deployment를 생성합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nonroot-deploy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nonroot&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nonroot&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serviceAccountName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nonroot-sa&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1001&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fsGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2001&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;example/app:v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;여기서 중요한 설정&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;runAsUser: 1001&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;PSP 정책에서 요구한 &lt;strong&gt;non-root 실행 조건&lt;/strong&gt;을 만족합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="정책-위반-테스트"&gt;
 정책 위반 테스트
 &lt;a class="heading-anchor" href="#%ec%a0%95%ec%b1%85-%ec%9c%84%eb%b0%98-%ed%85%8c%ec%8a%a4%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;만약 다음과 같이 &lt;strong&gt;root 사용자로 실행되는 Pod&lt;/strong&gt;를 생성하면&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;root-app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;example/app:v1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pod 생성 시 다음과 같은 결과가 발생합니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Pod 생성 실패
PSP 정책 위반&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;즉 &lt;strong&gt;보안 정책이 강제로 적용됩니다.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="psp-활성화"&gt;
 PSP 활성화
 &lt;a class="heading-anchor" href="#psp-%ed%99%9c%ec%84%b1%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;PSP는 기본적으로 비활성화되어 있으며
&lt;strong&gt;Admission Controller&lt;/strong&gt;를 통해 활성화해야 합니다.&lt;/p&gt;
&lt;p&gt;예: Minikube&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;minikube start &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;--extra-config&lt;span class="o"&gt;=&lt;/span&gt;apiserver.enable-admission-plugins&lt;span class="o"&gt;=&lt;/span&gt;PodSecurityPolicy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="운영-환경-best-practice"&gt;
 운영 환경 Best Practice
 &lt;a class="heading-anchor" href="#%ec%9a%b4%ec%98%81-%ed%99%98%ea%b2%bd-best-practice" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;실무에서는 다음과 같은 정책을 많이 사용합니다.&lt;/p&gt;
&lt;h3 id="1-root-실행-금지"&gt;
 1️⃣ Root 실행 금지
 &lt;a class="heading-anchor" href="#1-root-%ec%8b%a4%ed%96%89-%ea%b8%88%ec%a7%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;MustRunAsNonRoot&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h3 id="2-privileged-container-금지"&gt;
 2️⃣ Privileged Container 금지
 &lt;a class="heading-anchor" href="#2-privileged-container-%ea%b8%88%ec%a7%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;privileged: false&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h3 id="3-host-network-차단"&gt;
 3️⃣ Host Network 차단
 &lt;a class="heading-anchor" href="#3-host-network-%ec%b0%a8%eb%8b%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hostNetwork: false&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h3 id="4-volume-타입-제한"&gt;
 4️⃣ Volume 타입 제한
 &lt;a class="heading-anchor" href="#4-volume-%ed%83%80%ec%9e%85-%ec%a0%9c%ed%95%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hostPath 사용 제한&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="kubernetes-보안-아키텍처"&gt;
 Kubernetes 보안 아키텍처
 &lt;a class="heading-anchor" href="#kubernetes-%eb%b3%b4%ec%95%88-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

Developer --&amp;gt; CI/CD

CI/CD --&amp;gt; KubernetesAPI

KubernetesAPI --&amp;gt; PSP

PSP --&amp;gt; Pod

Pod --&amp;gt; Container&lt;/pre&gt;
&lt;p&gt;PSP는 &lt;strong&gt;클러스터 레벨 보안 게이트 역할&lt;/strong&gt;을 합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="정리"&gt;
 정리
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes 보안 구조&lt;/p&gt;
&lt;h3 id="security-context"&gt;
 Security Context
 &lt;a class="heading-anchor" href="#security-context" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pod 실행 권한 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="pod-security-policy"&gt;
 Pod Security Policy
 &lt;a class="heading-anchor" href="#pod-security-policy" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;클러스터 보안 정책&lt;/li&gt;
&lt;li&gt;Pod 생성 정책 검사&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="rbac"&gt;
 RBAC
 &lt;a class="heading-anchor" href="#rbac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;PSP 사용 권한 제어&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;즉&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SecurityContext → 설정
PSP → 정책
RBAC → 접근 제어&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Kubernetes] Security Context 완벽 가이드 (runAsUser, privileged, capabilities)</title><link>https://kyungryeol-yoon.github.io/kubernetes/security/kubernetes-security-context-guide/</link><pubDate>Wed, 08 Jan 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/security/kubernetes-security-context-guide/</guid><description>&lt;h2 id="-kubernetes-security-context"&gt;
 ☸️ Kubernetes Security Context
 &lt;a class="heading-anchor" href="#-kubernetes-security-context" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes에서 컨테이너는 기본적으로 &lt;strong&gt;root 권한으로 실행됩니다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;이 경우 다음과 같은 보안 문제가 발생할 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너 취약점 발생 시 시스템 장악 가능&lt;/li&gt;
&lt;li&gt;호스트 커널 접근 위험&lt;/li&gt;
&lt;li&gt;파일 권한 문제&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이를 제어하기 위한 기능이 &lt;strong&gt;Security Context&lt;/strong&gt; 입니다.&lt;/p&gt;
&lt;p&gt;Security Context는 &lt;strong&gt;Pod 또는 Container 수준에서 보안 설정을 정의&lt;/strong&gt;할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="security-context-architecture"&gt;
 Security Context Architecture
 &lt;a class="heading-anchor" href="#security-context-architecture" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod]

B[Security Context]

C[Container]

D[Process User]

E[Kernel Access]

B --&amp;gt; C
C --&amp;gt; D
C --&amp;gt; E&lt;/pre&gt;
&lt;p&gt;Security Context는 다음을 제어합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;사용자 UID / GID&lt;/li&gt;
&lt;li&gt;파일 권한&lt;/li&gt;
&lt;li&gt;Linux Capability&lt;/li&gt;
&lt;li&gt;Privileged 모드&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="컨테이너-기본-권한-문제"&gt;
 컨테이너 기본 권한 문제
 &lt;a class="heading-anchor" href="#%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%ea%b8%b0%eb%b3%b8-%ea%b6%8c%ed%95%9c-%eb%ac%b8%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;기본적으로 컨테이너는 &lt;strong&gt;root 권한으로 실행됩니다.&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

Container --&amp;gt; RootProcess
RootProcess --&amp;gt; SystemAccess&lt;/pre&gt;
&lt;p&gt;이 경우 컨테이너 취약점이 발생하면&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파일 시스템 접근&lt;/li&gt;
&lt;li&gt;네트워크 설정 변경&lt;/li&gt;
&lt;li&gt;커널 기능 접근&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;등이 가능해집니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="runasuser"&gt;
 runAsUser
 &lt;a class="heading-anchor" href="#runasuser" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;runAsUser&lt;/code&gt;는 &lt;strong&gt;컨테이너 프로세스의 UID를 지정&lt;/strong&gt;합니다.&lt;/p&gt;
&lt;p&gt;예&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;runas-demo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fsGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;node:18&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이 설정은&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너 프로세스를 &lt;strong&gt;UID 1000 사용자로 실행&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;파일 권한도 해당 사용자로 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="security-context-적용-범위"&gt;
 Security Context 적용 범위
 &lt;a class="heading-anchor" href="#security-context-%ec%a0%81%ec%9a%a9-%eb%b2%94%ec%9c%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Security Context는 두 가지 범위에서 적용할 수 있습니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;적용 위치&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Pod&lt;/td&gt;
					&lt;td&gt;모든 컨테이너에 적용&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Container&lt;/td&gt;
					&lt;td&gt;특정 컨테이너만 적용&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="pod-level"&gt;
 Pod Level
 &lt;a class="heading-anchor" href="#pod-level" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fsGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pod 전체에 적용됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="container-level"&gt;
 Container Level
 &lt;a class="heading-anchor" href="#container-level" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;특정 컨테이너에만 적용됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="fsgroup"&gt;
 fsGroup
 &lt;a class="heading-anchor" href="#fsgroup" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;fsGroup&lt;/code&gt;은 &lt;strong&gt;Volume 파일 권한 그룹을 지정&lt;/strong&gt;합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

Volume --&amp;gt; fsGroup
fsGroup --&amp;gt; Container&lt;/pre&gt;
&lt;p&gt;예&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fsGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Volume에 생성되는 파일은 해당 그룹으로 설정됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="privileged-mode"&gt;
 Privileged Mode
 &lt;a class="heading-anchor" href="#privileged-mode" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;일부 애플리케이션은 &lt;strong&gt;호스트 커널 기능 접근이 필요합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;예&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NFS mount&lt;/li&gt;
&lt;li&gt;Network monitoring&lt;/li&gt;
&lt;li&gt;Device access&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 경우 &lt;strong&gt;Privileged Mode&lt;/strong&gt;를 사용할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;privileged&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

Container --&amp;gt; KernelAccess
KernelAccess --&amp;gt; HostSystem&lt;/pre&gt;
&lt;p&gt;하지만 privileged 모드는&lt;/p&gt;
&lt;p&gt;⚠️ &lt;strong&gt;보안 위험이 매우 큽니다&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;가능하면 사용하지 않는 것이 좋습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="linux-capabilities"&gt;
 Linux Capabilities
 &lt;a class="heading-anchor" href="#linux-capabilities" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Privileged 모드 대신 &lt;strong&gt;Linux Capability&lt;/strong&gt;를 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;Linux Capability는 &lt;strong&gt;필요한 권한만 선택적으로 부여&lt;/strong&gt;합니다.&lt;/p&gt;
&lt;p&gt;예&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;capabilities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;add&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;NET_ADMIN&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;SYS_TIME&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

Container --&amp;gt; Capability

Capability --&amp;gt; NET_ADMIN
Capability --&amp;gt; SYS_TIME&lt;/pre&gt;
&lt;p&gt;대표 Capability&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Capability&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;NET_ADMIN&lt;/td&gt;
					&lt;td&gt;네트워크 설정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;SYS_TIME&lt;/td&gt;
					&lt;td&gt;시스템 시간 변경&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;SYS_ADMIN&lt;/td&gt;
					&lt;td&gt;시스템 관리&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="security-context-실무-구조"&gt;
 Security Context 실무 구조
 &lt;a class="heading-anchor" href="#security-context-%ec%8b%a4%eb%ac%b4-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;실제 운영 환경에서는 다음과 같이 설정합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

Pod --&amp;gt; Container

Container --&amp;gt; NonRootUser

Container --&amp;gt; LimitedCapability

Container -.X.-&amp;gt; Privileged&lt;/pre&gt;
&lt;p&gt;보안 권장 사항&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;root 실행 금지&lt;/li&gt;
&lt;li&gt;capability 최소화&lt;/li&gt;
&lt;li&gt;privileged 사용 최소화&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="best-practice"&gt;
 Best Practice
 &lt;a class="heading-anchor" href="#best-practice" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;운영 환경에서 권장되는 보안 설정&lt;/p&gt;
&lt;h3 id="1-non-root-container"&gt;
 1️⃣ Non-root Container
 &lt;a class="heading-anchor" href="#1-non-root-container" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="2-privileged-금지"&gt;
 2️⃣ Privileged 금지
 &lt;a class="heading-anchor" href="#2-privileged-%ea%b8%88%ec%a7%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;가능하면 privileged 사용하지 않기&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="3-capability-최소화"&gt;
 3️⃣ Capability 최소화
 &lt;a class="heading-anchor" href="#3-capability-%ec%b5%9c%ec%86%8c%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;필요한 capability만 추가&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="4-pod-security-정책-적용"&gt;
 4️⃣ Pod Security 정책 적용
 &lt;a class="heading-anchor" href="#4-pod-security-%ec%a0%95%ec%b1%85-%ec%a0%81%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;PodSecurity&lt;/li&gt;
&lt;li&gt;OPA Gatekeeper&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="정리"&gt;
 정리
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Security Context는 Kubernetes 컨테이너 보안을 위한 핵심 기능입니다.&lt;/p&gt;
&lt;p&gt;주요 기능&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;runAsUser → 컨테이너 사용자 지정&lt;/li&gt;
&lt;li&gt;fsGroup → 파일 권한 설정&lt;/li&gt;
&lt;li&gt;privileged → 커널 권한&lt;/li&gt;
&lt;li&gt;capabilities → 최소 권한 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;운영 환경에서는&lt;/p&gt;
&lt;p&gt;✔ root 사용 금지
✔ privileged 최소화
✔ capability 최소화&lt;/p&gt;
&lt;p&gt;전략이 중요합니다.&lt;/p&gt;</description></item><item><title>[Kubernetes] Network Security 완벽 정리 (NetworkPolicy, Pod Network)</title><link>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-network-security-guide/</link><pubDate>Sun, 05 Jan 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-network-security-guide/</guid><description>&lt;h2 id="-kubernetes-network-security"&gt;
 ☸️ Kubernetes Network Security
 &lt;a class="heading-anchor" href="#-kubernetes-network-security" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes 클러스터에서는 기본적으로 &lt;strong&gt;모든 Pod가 서로 통신할 수 있습니다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;즉 아무 설정이 없다면&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Pod ↔ Pod
Pod ↔ Service
Pod ↔ Node&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;모든 네트워크가 허용됩니다.&lt;/p&gt;
&lt;p&gt;하지만 실제 운영 환경에서는 &lt;strong&gt;보안 문제&lt;/strong&gt;가 발생할 수 있습니다.&lt;/p&gt;
&lt;p&gt;예&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;내부 서비스 접근 제한 필요&lt;/li&gt;
&lt;li&gt;특정 Namespace 통신 차단&lt;/li&gt;
&lt;li&gt;데이터베이스 접근 제한&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 문제를 해결하기 위해 &lt;strong&gt;NetworkPolicy&lt;/strong&gt;를 사용합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="kubernetes-네트워크-구조"&gt;
 Kubernetes 네트워크 구조
 &lt;a class="heading-anchor" href="#kubernetes-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes는 기본적으로 &lt;strong&gt;Flat Network 구조&lt;/strong&gt;를 사용합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod A]

B[Pod B]

C[Pod C]

D[Service]

A --&amp;gt; B
A --&amp;gt; C
B --&amp;gt; C
C --&amp;gt; D&lt;/pre&gt;
&lt;p&gt;특징&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod 간 직접 통신 가능&lt;/li&gt;
&lt;li&gt;NAT 없이 IP 통신&lt;/li&gt;
&lt;li&gt;모든 Pod가 서로 접근 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="networkpolicy란"&gt;
 NetworkPolicy란?
 &lt;a class="heading-anchor" href="#networkpolicy%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;NetworkPolicy는 &lt;strong&gt;Pod 간 네트워크 통신을 제어하는 정책&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;주요 기능&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;특정 Pod만 접근 허용&lt;/li&gt;
&lt;li&gt;특정 Namespace 허용&lt;/li&gt;
&lt;li&gt;특정 Port 허용&lt;/li&gt;
&lt;li&gt;Ingress / Egress 제어&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="networkpolicy-구조"&gt;
 NetworkPolicy 구조
 &lt;a class="heading-anchor" href="#networkpolicy-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod]

B[NetworkPolicy]

C[Allowed Pod]

D[Blocked Pod]

C --&amp;gt; A
D -. blocked .-&amp;gt; A
A --&amp;gt; B&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="ingress-policy"&gt;
 Ingress Policy
 &lt;a class="heading-anchor" href="#ingress-policy" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Ingress Policy는 &lt;strong&gt;Pod로 들어오는 트래픽&lt;/strong&gt;을 제어합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Client Pod]

B[Target Pod]

C[NetworkPolicy]

A --&amp;gt; C
C --&amp;gt; B&lt;/pre&gt;
&lt;hr&gt;
&lt;h3 id="ingress-policy-예시"&gt;
 Ingress Policy 예시
 &lt;a class="heading-anchor" href="#ingress-policy-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;networking.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NetworkPolicy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;allow-nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;policyTypes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;Ingress&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ingress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;podSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;frontend&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;설명&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;nginx Pod로 들어오는 트래픽 허용&lt;/li&gt;
&lt;li&gt;frontend Pod만 접근 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="egress-policy"&gt;
 Egress Policy
 &lt;a class="heading-anchor" href="#egress-policy" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Egress Policy는 &lt;strong&gt;Pod에서 나가는 트래픽&lt;/strong&gt;을 제어합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod]

B[NetworkPolicy]

C[External Service]

A --&amp;gt; B --&amp;gt; C&lt;/pre&gt;
&lt;hr&gt;
&lt;h3 id="egress-policy-예시"&gt;
 Egress Policy 예시
 &lt;a class="heading-anchor" href="#egress-policy-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;networking.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;NetworkPolicy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;allow-dns&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;podSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;policyTypes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;Egress&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;egress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;namespaceSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="namespace-기반-접근-제어"&gt;
 Namespace 기반 접근 제어
 &lt;a class="heading-anchor" href="#namespace-%ea%b8%b0%eb%b0%98-%ec%a0%91%ea%b7%bc-%ec%a0%9c%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;NetworkPolicy는 &lt;strong&gt;Namespace 단위 제어&lt;/strong&gt;도 가능합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Namespace A]

B[Namespace B]

C[Namespace C]

A --&amp;gt; B
C -. blocked .-&amp;gt; B&lt;/pre&gt;
&lt;p&gt;예&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;frontend → backend 허용&lt;/li&gt;
&lt;li&gt;외부 namespace 차단&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="label-기반-접근-제어"&gt;
 Label 기반 접근 제어
 &lt;a class="heading-anchor" href="#label-%ea%b8%b0%eb%b0%98-%ec%a0%91%ea%b7%bc-%ec%a0%9c%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes는 &lt;strong&gt;Label 기반 정책&lt;/strong&gt;을 사용합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod frontend]

B[Pod backend]

C[Pod database]

A --&amp;gt; B
B --&amp;gt; C
A -. blocked .-&amp;gt; C&lt;/pre&gt;
&lt;p&gt;예&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;frontend → backend 허용&lt;/li&gt;
&lt;li&gt;database 직접 접근 차단&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="networkpolicy-적용-전후"&gt;
 NetworkPolicy 적용 전후
 &lt;a class="heading-anchor" href="#networkpolicy-%ec%a0%81%ec%9a%a9-%ec%a0%84%ed%9b%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="정책-없음"&gt;
 정책 없음
 &lt;a class="heading-anchor" href="#%ec%a0%95%ec%b1%85-%ec%97%86%ec%9d%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod A]

B[Pod B]

C[Pod C]

A --&amp;gt; B
A --&amp;gt; C
B --&amp;gt; C&lt;/pre&gt;
&lt;h3 id="정책-적용"&gt;
 정책 적용
 &lt;a class="heading-anchor" href="#%ec%a0%95%ec%b1%85-%ec%a0%81%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Frontend]

B[Backend]

C[Database]

A --&amp;gt; B
B --&amp;gt; C
A -. blocked .-&amp;gt; C&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="cni-플러그인"&gt;
 CNI 플러그인
 &lt;a class="heading-anchor" href="#cni-%ed%94%8c%eb%9f%ac%ea%b7%b8%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;NetworkPolicy는 &lt;strong&gt;CNI 플러그인&lt;/strong&gt;이 지원해야 동작합니다.&lt;/p&gt;
&lt;p&gt;대표적인 CNI&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;CNI&lt;/th&gt;
					&lt;th&gt;특징&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Calico&lt;/td&gt;
					&lt;td&gt;가장 널리 사용&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Cilium&lt;/td&gt;
					&lt;td&gt;eBPF 기반&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Weave&lt;/td&gt;
					&lt;td&gt;간단한 설정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Flannel&lt;/td&gt;
					&lt;td&gt;기본 네트워크&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="networkpolicy-아키텍처"&gt;
 NetworkPolicy 아키텍처
 &lt;a class="heading-anchor" href="#networkpolicy-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod]

B[CNI Plugin]

C[NetworkPolicy]

D[Allowed Traffic]

E[Blocked Traffic]

A --&amp;gt; B
C --&amp;gt; B
B --&amp;gt; D
B -.-&amp;gt; E&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="실무-보안-설계-예시"&gt;
 실무 보안 설계 예시
 &lt;a class="heading-anchor" href="#%ec%8b%a4%eb%ac%b4-%eb%b3%b4%ec%95%88-%ec%84%a4%ea%b3%84-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;일반적인 서비스 구조&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Internet]

B[Ingress]

C[Frontend]

D[Backend]

E[Database]

A --&amp;gt; B
B --&amp;gt; C
C --&amp;gt; D
D --&amp;gt; E

C -. blocked .-&amp;gt; E&lt;/pre&gt;
&lt;p&gt;보안 원칙&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Frontend → Backend만 허용&lt;/li&gt;
&lt;li&gt;Backend → DB만 허용&lt;/li&gt;
&lt;li&gt;Frontend → DB 차단&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="정리"&gt;
 정리
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes Network Security 핵심&lt;/p&gt;
&lt;h3 id="기본-네트워크"&gt;
 기본 네트워크
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;모든 Pod 간 통신 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="networkpolicy"&gt;
 NetworkPolicy
 &lt;a class="heading-anchor" href="#networkpolicy" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pod 통신 제어&lt;/li&gt;
&lt;li&gt;Ingress / Egress 지원&lt;/li&gt;
&lt;li&gt;Label 기반 정책&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="지원-조건"&gt;
 지원 조건
 &lt;a class="heading-anchor" href="#%ec%a7%80%ec%9b%90-%ec%a1%b0%ea%b1%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CNI 플러그인 필요&lt;/li&gt;
&lt;li&gt;Kubernetes 네트워크 정책 활성화&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] 보안 가이드 (Authentication &amp; Authorization, RBAC)</title><link>https://kyungryeol-yoon.github.io/kubernetes/security/kubernetes-security-authentication-authorization/</link><pubDate>Thu, 02 Jan 2020 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/security/kubernetes-security-authentication-authorization/</guid><description>&lt;h2 id="-kubernetes-보안-개요"&gt;
 ☸️ Kubernetes 보안 개요
 &lt;a class="heading-anchor" href="#-kubernetes-%eb%b3%b4%ec%95%88-%ea%b0%9c%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes는 &lt;strong&gt;클러스터 기반 인프라&lt;/strong&gt;이기 때문에 보안이 매우 중요합니다.&lt;br&gt;
특히 다음 영역이 핵심입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;사용자 인증 (Authentication)&lt;/li&gt;
&lt;li&gt;권한 인가 (Authorization)&lt;/li&gt;
&lt;li&gt;네트워크 보안&lt;/li&gt;
&lt;li&gt;Secret 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 글에서는 그 중에서도 &lt;strong&gt;사용자 인증과 권한 인가&lt;/strong&gt;를 중심으로 정리합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="authentication-vs-authorization"&gt;
 Authentication vs Authorization
 &lt;a class="heading-anchor" href="#authentication-vs-authorization" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;보안 시스템에서 가장 먼저 이해해야 하는 개념은 &lt;strong&gt;인증(Authentication)&lt;/strong&gt; 과 &lt;strong&gt;인가(Authorization)&lt;/strong&gt; 입니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;개념&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Authentication&lt;/td&gt;
					&lt;td&gt;사용자가 누구인지 확인&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Authorization&lt;/td&gt;
					&lt;td&gt;해당 사용자가 어떤 권한을 가지는지 확인&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;예를 들어&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;로그인 → Authentication
권한 체크 → Authorization&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="kubernetes-보안-구조"&gt;
 Kubernetes 보안 구조
 &lt;a class="heading-anchor" href="#kubernetes-%eb%b3%b4%ec%95%88-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Client]

B[Authentication]

C[Authorization]

D[Kubernetes API Server]

E[Cluster Resource]

A --&amp;gt; B
B --&amp;gt; C
C --&amp;gt; D
D --&amp;gt; E&lt;/pre&gt;
&lt;p&gt;흐름&lt;/p&gt;
&lt;p&gt;1️⃣ Client 요청
2️⃣ 인증(Authentication)
3️⃣ 권한 확인(Authorization)
4️⃣ API Server 처리&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="kubernetes-계정-종류"&gt;
 Kubernetes 계정 종류
 &lt;a class="heading-anchor" href="#kubernetes-%ea%b3%84%ec%a0%95-%ec%a2%85%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes에서는 두 가지 계정을 사용합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;계정&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;User Account&lt;/td&gt;
					&lt;td&gt;사람이 사용하는 계정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Service Account&lt;/td&gt;
					&lt;td&gt;시스템 또는 Pod에서 사용하는 계정&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="user-account"&gt;
 User Account
 &lt;a class="heading-anchor" href="#user-account" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;일반적인 사용자 계정입니다.&lt;/p&gt;
&lt;p&gt;특징&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes 내부에서 직접 관리하지 않음&lt;/li&gt;
&lt;li&gt;외부 인증 시스템과 연동&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;대표적인 인증 방식&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OAuth&lt;/li&gt;
&lt;li&gt;Webhook&lt;/li&gt;
&lt;li&gt;LDAP&lt;/li&gt;
&lt;li&gt;OIDC&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="service-account"&gt;
 Service Account
 &lt;a class="heading-anchor" href="#service-account" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Service Account는 &lt;strong&gt;Pod나 애플리케이션이 Kubernetes API를 사용할 때 사용하는 계정&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;예를 들어&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Controller&lt;/li&gt;
&lt;li&gt;Operator&lt;/li&gt;
&lt;li&gt;내부 애플리케이션&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id="serviceaccount-생성"&gt;
 ServiceAccount 생성
 &lt;a class="heading-anchor" href="#serviceaccount-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create sa my-service-account&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h4 id="serviceaccount-구조"&gt;
 ServiceAccount 구조
 &lt;a class="heading-anchor" href="#serviceaccount-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod]

B[ServiceAccount]

C[Secret Token]

D[Kubernetes API]

A --&amp;gt; B
B --&amp;gt; C
C --&amp;gt; D&lt;/pre&gt;
&lt;p&gt;ServiceAccount는 &lt;strong&gt;API 인증을 위한 Token을 Secret에 저장합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="kubernetes-인증-방식"&gt;
 Kubernetes 인증 방식
 &lt;a class="heading-anchor" href="#kubernetes-%ec%9d%b8%ec%a6%9d-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes는 다양한 인증 방식을 지원합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;인증 방식&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Basic Auth&lt;/td&gt;
					&lt;td&gt;HTTP 인증&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Bearer Token&lt;/td&gt;
					&lt;td&gt;API Token 기반 인증&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Client Certificate&lt;/td&gt;
					&lt;td&gt;인증서 기반 인증&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Webhook&lt;/td&gt;
					&lt;td&gt;외부 인증 시스템&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="bearer-token-인증"&gt;
 Bearer Token 인증
 &lt;a class="heading-anchor" href="#bearer-token-%ec%9d%b8%ec%a6%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;가장 많이 사용하는 방식입니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Authorization: Bearer {TOKEN}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ServiceAccount Token을 이용하여 API 호출이 가능합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id="token-조회"&gt;
 Token 조회
 &lt;a class="heading-anchor" href="#token-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl describe sa default&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;또는&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl describe secret &lt;span class="o"&gt;{&lt;/span&gt;secret-name&lt;span class="o"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="api-호출-예시"&gt;
 API 호출 예시
 &lt;a class="heading-anchor" href="#api-%ed%98%b8%ec%b6%9c-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl https://APISERVER/api &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; --header &lt;span class="s2"&gt;&amp;#34;Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; --insecure&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="kubectl-proxy를-이용한-인증"&gt;
 kubectl proxy를 이용한 인증
 &lt;a class="heading-anchor" href="#kubectl-proxy%eb%a5%bc-%ec%9d%b4%ec%9a%a9%ed%95%9c-%ec%9d%b8%ec%a6%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;직접 Token을 사용하는 대신 &lt;strong&gt;kubectl proxy&lt;/strong&gt;를 사용할 수도 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl proxy --port&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이후 API 호출&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl localhost:8080/api&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;proxy가 자동으로 인증 정보를 추가합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="authorization-권한-관리"&gt;
 Authorization (권한 관리)
 &lt;a class="heading-anchor" href="#authorization-%ea%b6%8c%ed%95%9c-%ea%b4%80%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;인증 이후에는 &lt;strong&gt;권한 검사&lt;/strong&gt;가 진행됩니다.&lt;/p&gt;
&lt;p&gt;Kubernetes는 기본적으로 &lt;strong&gt;RBAC(Role Based Access Control)&lt;/strong&gt; 을 사용합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="rbac-구조"&gt;
 RBAC 구조
 &lt;a class="heading-anchor" href="#rbac-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[User]

B[Group]

C[ServiceAccount]

D[Role]

E[RoleBinding]

F[Kubernetes Resource]

A --&amp;gt; E
B --&amp;gt; E
C --&amp;gt; E

E --&amp;gt; D
D --&amp;gt; F&lt;/pre&gt;
&lt;p&gt;핵심 구성&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Role&lt;/li&gt;
&lt;li&gt;RoleBinding&lt;/li&gt;
&lt;li&gt;ClusterRole&lt;/li&gt;
&lt;li&gt;ClusterRoleBinding&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="role"&gt;
 Role
 &lt;a class="heading-anchor" href="#role" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Role은 &lt;strong&gt;특정 리소스에 대한 권한 정의&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;예&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod 조회&lt;/li&gt;
&lt;li&gt;Deployment 생성&lt;/li&gt;
&lt;li&gt;Service 삭제&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="role-예시"&gt;
 Role 예시
 &lt;a class="heading-anchor" href="#role-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Role&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod-reader&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;apiGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pods&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;verbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;watch&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;list&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="rolebinding"&gt;
 RoleBinding
 &lt;a class="heading-anchor" href="#rolebinding" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Role을 사용자 또는 서비스 계정에 연결합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph LR

A[User]

B[RoleBinding]

C[Role]

A --&amp;gt; B --&amp;gt; C&lt;/pre&gt;
&lt;hr&gt;
&lt;h3 id="rolebinding-예시"&gt;
 RoleBinding 예시
 &lt;a class="heading-anchor" href="#rolebinding-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;RoleBinding&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;read-pods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;subjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;User&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;jane&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;roleRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Role&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod-reader&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="role-vs-clusterrole"&gt;
 Role vs ClusterRole
 &lt;a class="heading-anchor" href="#role-vs-clusterrole" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;구분&lt;/th&gt;
					&lt;th&gt;범위&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Role&lt;/td&gt;
					&lt;td&gt;특정 Namespace&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ClusterRole&lt;/td&gt;
					&lt;td&gt;Cluster 전체&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;ClusterRole은 다음과 같은 리소스에 사용됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node&lt;/li&gt;
&lt;li&gt;PersistentVolume&lt;/li&gt;
&lt;li&gt;Cluster 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="기본-제공-role"&gt;
 기본 제공 Role
 &lt;a class="heading-anchor" href="#%ea%b8%b0%eb%b3%b8-%ec%a0%9c%ea%b3%b5-role" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes는 기본 Role을 제공합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Role&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;cluster-admin&lt;/td&gt;
					&lt;td&gt;전체 관리자&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;admin&lt;/td&gt;
					&lt;td&gt;네임스페이스 관리자&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;edit&lt;/td&gt;
					&lt;td&gt;리소스 수정 가능&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;view&lt;/td&gt;
					&lt;td&gt;읽기 전용&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="rbac-전체-아키텍처"&gt;
 RBAC 전체 아키텍처
 &lt;a class="heading-anchor" href="#rbac-%ec%a0%84%ec%b2%b4-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[User]

B[Group]

C[ServiceAccount]

D[Role]

E[ClusterRole]

F[RoleBinding]

G[ClusterRoleBinding]

H[Resource]

A --&amp;gt; F
B --&amp;gt; F
C --&amp;gt; F

F --&amp;gt; D
G --&amp;gt; E

D --&amp;gt; H
E --&amp;gt; H&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="serviceaccount--rbac-예제"&gt;
 ServiceAccount + RBAC 예제
 &lt;a class="heading-anchor" href="#serviceaccount--rbac-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;먼저 ServiceAccount 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;sa-viewer&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;p&gt;ClusterRoleBinding 생성&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRoleBinding&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default-view&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;subjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceAccount&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;sa-viewer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;roleRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterRole&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;view&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;p&gt;Pod에서 ServiceAccount 사용&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod-reader&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serviceAccountName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;sa-viewer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;reader&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gcr.io/terrycho-sandbox/pod-reader:v1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이렇게 하면 Pod 내부에서 Kubernetes API를 호출할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="정리"&gt;
 정리
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes 보안 핵심&lt;/p&gt;
&lt;h3 id="authentication"&gt;
 Authentication
 &lt;a class="heading-anchor" href="#authentication" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;사용자를 식별&lt;/p&gt;
&lt;p&gt;대표 방식&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bearer Token&lt;/li&gt;
&lt;li&gt;Client Certificate&lt;/li&gt;
&lt;li&gt;OAuth&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="authorization"&gt;
 Authorization
 &lt;a class="heading-anchor" href="#authorization" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;권한 관리&lt;/p&gt;
&lt;p&gt;대표 방식&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;RBAC&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="계정-종류"&gt;
 계정 종류
 &lt;a class="heading-anchor" href="#%ea%b3%84%ec%a0%95-%ec%a2%85%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;계정&lt;/th&gt;
					&lt;th&gt;사용&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;User Account&lt;/td&gt;
					&lt;td&gt;사용자&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Service Account&lt;/td&gt;
					&lt;td&gt;Pod / 시스템&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;</description></item><item><title>[Kubernetes] kube-ps1</title><link>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-kube-ps1/</link><pubDate>Sun, 22 Dec 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-kube-ps1/</guid><description>&lt;p&gt;kube-ps1를 사용하면, 현재 사용하고 있는 Kubernetes Context 및 Namespace를 보여줍니다.\
Context와 Namespace를 보는게 불편하다면,\
kubeoff 명령어를 실행해서 kube-ps을 비활성화 시킬수도 있습니다.&lt;/p&gt;
&lt;h2 id="kube-ps1의-설치가-완료되면-셀의-프롬프트가-다음처럼-표시됩니다"&gt;
 kube-ps1의 설치가 완료되면, 셀의 프롬프트가 다음처럼 표시됩니다.
 &lt;a class="heading-anchor" href="#kube-ps1%ec%9d%98-%ec%84%a4%ec%b9%98%ea%b0%80-%ec%99%84%eb%a3%8c%eb%90%98%eb%a9%b4-%ec%85%80%ec%9d%98-%ed%94%84%eb%a1%ac%ed%94%84%ed%8a%b8%ea%b0%80-%eb%8b%a4%ec%9d%8c%ec%b2%98%eb%9f%bc-%ed%91%9c%ec%8b%9c%eb%90%a9%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;⎈ &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;context&lt;span class="o"&gt;]&lt;/span&gt;:&lt;span class="o"&gt;[&lt;/span&gt;namespace&lt;span class="o"&gt;])&lt;/span&gt; $
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;⎈ &lt;span class="p"&gt;|&lt;/span&gt;greentea:kube-system&lt;span class="o"&gt;)&lt;/span&gt; $&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;kube-ps1에 대한 설정 방법은 &lt;a href="https://github.com/jonmosco/kube-ps1"&gt;설치 문서&lt;/a&gt;를 참고하시기 바랍니다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubens</title><link>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-kubens/</link><pubDate>Mon, 16 Dec 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-kubens/</guid><description>&lt;p&gt;Kubernetes의 Namespace를 여러개 사용하고 있다면,\
kubens는 기본 Namespace를 변경할 수 있도록 도와줍니다.\
fzf를 설치하면 대화식 메뉴를 제공하기 때문에, 더욱 편리하게 사용할 수 있습니다.&lt;/p&gt;
&lt;h2 id="kubens-명령을-실행하면-namespace-목록을-보여줍니다"&gt;
 kubens 명령을 실행하면, Namespace 목록을 보여줍니다.
 &lt;a class="heading-anchor" href="#kubens-%eb%aa%85%eb%a0%b9%ec%9d%84-%ec%8b%a4%ed%96%89%ed%95%98%eb%a9%b4-namespace-%eb%aa%a9%eb%a1%9d%ec%9d%84-%eb%b3%b4%ec%97%ac%ec%a4%8d%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;$ kubens
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;kube-system
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;kube-public
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;istio-system
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;default&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="namespace를-변경하기-위해서는-namespace-명을-입력하면-됩니다"&gt;
 Namespace를 변경하기 위해서는, Namespace 명을 입력하면 됩니다.
 &lt;a class="heading-anchor" href="#namespace%eb%a5%bc-%eb%b3%80%ea%b2%bd%ed%95%98%ea%b8%b0-%ec%9c%84%ed%95%b4%ec%84%9c%eb%8a%94-namespace-%eb%aa%85%ec%9d%84-%ec%9e%85%eb%a0%a5%ed%95%98%eb%a9%b4-%eb%90%a9%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;$ kubens kube-system
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;Context &lt;span class="s2"&gt;&amp;#34;minikube&amp;#34;&lt;/span&gt; modified.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;Active namespace is &lt;span class="s2"&gt;&amp;#34;kube-system&amp;#34;&lt;/span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="만약-fzf가-설치되어-있으면-kubens-명령을-실행하면-대화식-메뉴를-보여줍니다"&gt;
 만약 fzf가 설치되어 있으면, kubens 명령을 실행하면 대화식 메뉴를 보여줍니다.
 &lt;a class="heading-anchor" href="#%eb%a7%8c%ec%95%bd-fzf%ea%b0%80-%ec%84%a4%ec%b9%98%eb%90%98%ec%96%b4-%ec%9e%88%ec%9c%bc%eb%a9%b4-kubens-%eb%aa%85%eb%a0%b9%ec%9d%84-%ec%8b%a4%ed%96%89%ed%95%98%eb%a9%b4-%eb%8c%80%ed%99%94%ec%8b%9d-%eb%a9%94%eb%89%b4%eb%a5%bc-%eb%b3%b4%ec%97%ac%ec%a4%8d%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;$ kubens
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&amp;gt; kube-system
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; kube-public
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; istio-system
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; default
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt; 4/4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;kubens에 대한 설정 방법은 &lt;a href="https://github.com/ahmetb/kubectl-aliases"&gt;설치 문서&lt;/a&gt;를 참고하시기 바랍니다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] kubectx</title><link>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-kubectx/</link><pubDate>Tue, 10 Dec 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-kubectx/</guid><description>&lt;p&gt;Kubernetes의 Context를 여러개 사용하고 있다면,\
kubectx는 Context를 쉽게 변경할 수 있도록 도움을 줍니다.\
이 도구를 사용하면, &lt;code&gt;kubectl config use-context greentea&lt;/code&gt; 같은 긴 명령어를 사용하지 않아도 됩니다.\
fzf를 설치하면 대화식 메뉴를 제공하기 때문에, 더욱 편리하게 사용할 수 있습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Kubernetes는 Cluster, User, Namespace를 조합한 Context라는 오브젝트를 제공한다. Context는 독립적인 단위로 흔히 우리가 생각하는 클러스터를 Context 단위로 볼 수도 있지만, 사실 그보다 더 세분화된 단위라고 볼 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="kubectx-명령을-실행하면-context-목록을-보여줍니다"&gt;
 kubectx 명령을 실행하면, Context 목록을 보여줍니다.
 &lt;a class="heading-anchor" href="#kubectx-%eb%aa%85%eb%a0%b9%ec%9d%84-%ec%8b%a4%ed%96%89%ed%95%98%eb%a9%b4-context-%eb%aa%a9%eb%a1%9d%ec%9d%84-%eb%b3%b4%ec%97%ac%ec%a4%8d%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;$ kubectx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;coffee
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;minikube
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="context를-변경하기-위해서는-context-명을-입력하면-됩니다"&gt;
 Context를 변경하기 위해서는, Context 명을 입력하면 됩니다.
 &lt;a class="heading-anchor" href="#context%eb%a5%bc-%eb%b3%80%ea%b2%bd%ed%95%98%ea%b8%b0-%ec%9c%84%ed%95%b4%ec%84%9c%eb%8a%94-context-%eb%aa%85%ec%9d%84-%ec%9e%85%eb%a0%a5%ed%95%98%eb%a9%b4-%eb%90%a9%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;$ kubectx minikube
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;Switched to context &lt;span class="s2"&gt;&amp;#34;minikube&amp;#34;&lt;/span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="만약-fzf가-설치되어-있으면-kubectx-명령을-실행하면-대화식-메뉴를-보여줍니다"&gt;
 만약 fzf가 설치되어 있으면, kubectx 명령을 실행하면 대화식 메뉴를 보여줍니다.
 &lt;a class="heading-anchor" href="#%eb%a7%8c%ec%95%bd-fzf%ea%b0%80-%ec%84%a4%ec%b9%98%eb%90%98%ec%96%b4-%ec%9e%88%ec%9c%bc%eb%a9%b4-kubectx-%eb%aa%85%eb%a0%b9%ec%9d%84-%ec%8b%a4%ed%96%89%ed%95%98%eb%a9%b4-%eb%8c%80%ed%99%94%ec%8b%9d-%eb%a9%94%eb%89%b4%eb%a5%bc-%eb%b3%b4%ec%97%ac%ec%a4%8d%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;$ kubectx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&amp;gt; coffee
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; minikube
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; 3/3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;kubectx에 대한 설정 방법은 &lt;a href="https://github.com/ahmetb/kubectl-aliases"&gt;설치 문서&lt;/a&gt;를 참고하시기 바랍니다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] Alias</title><link>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-alias/</link><pubDate>Sun, 17 Nov 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/tools/kubernetes-alias/</guid><description>&lt;h2 id="별칭-주기"&gt;
 별칭 주기
 &lt;a class="heading-anchor" href="#%eb%b3%84%ec%b9%ad-%ec%a3%bc%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;매번 kubectl의 모든 명령어를 입력할 수 있지만, 상당히 불편함을 느낄것입니다.\
이런 불편함을 줄이는 가장 쉬운 방법은 별칭(alias)를 지정해서 사용하는 것입니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-conf" data-lang="conf"&gt;alias k=&amp;#39;kubectl&amp;#39;
alias kg=&amp;#39;kubectl get&amp;#39;
alias kgpo=&amp;#39;kubectl get pod&amp;#39;

alias ksysgpo=&amp;#39;kubectl --namespace=kube-system get pod&amp;#39;

alias krm=&amp;#39;kubectl delete&amp;#39;
alias krmf=&amp;#39;kubectl delete -f&amp;#39;
alias krming=&amp;#39;kubectl delete ingress&amp;#39;
alias krmingl=&amp;#39;kubectl delete ingress -l&amp;#39;
alias krmingall=&amp;#39;kubectl delete ingress --all-namespaces&amp;#39;

alias kgsvcoyaml=&amp;#39;kubectl get service -o=yaml&amp;#39;
alias kgsvcwn=&amp;#39;kubectl get service --watch --namespace&amp;#39;
alias kgsvcslwn=&amp;#39;kubectl get service --show-labels --watch --namespace&amp;#39;

alias kgwf=&amp;#39;kubectl get --watch -f&amp;#39;

...✂...&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;자주 쓰는 명령어는 &lt;a href="https://github.com/ahmetb/kubectl-aliases"&gt;kubectl-aliases&lt;/a&gt;에 정의되어 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>Machine Learning LSTM</title><link>https://kyungryeol-yoon.github.io/ai/machine-learning/machine-learning-lstm/</link><pubDate>Tue, 01 Oct 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/ai/machine-learning/machine-learning-lstm/</guid><description>&lt;h2 id="recurrent-neural-network"&gt;
 Recurrent Neural Network
 &lt;a class="heading-anchor" href="#recurrent-neural-network" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;전통적인 Neural Network는 이전에 일어난 사건을 바탕으로 나중에 일어나는 사건을 생각하지 못한다.&lt;/li&gt;
&lt;li&gt;Recurrent Neural Network(이하 RNN)는 이 문제를 해결하고자 하는 모델이다. RNN은 스스로를 반복하면서 이전 단계에서 얻은 정보가 지속되도록 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="긴-의존-기간으로-인한-문제점"&gt;
 긴 의존 기간으로 인한 문제점
 &lt;a class="heading-anchor" href="#%ea%b8%b4-%ec%9d%98%ec%a1%b4-%ea%b8%b0%ea%b0%84%ec%9c%bc%eb%a1%9c-%ec%9d%b8%ed%95%9c-%eb%ac%b8%ec%a0%9c%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;RNN의 성공의 열쇠는 &amp;ldquo;Long Short-Term Memory Network&amp;rdquo; (이하 LSTM)의 사용이다.&lt;/li&gt;
&lt;li&gt;LSTM은 RNN의 굉장히 특별한 종류이다.&lt;/li&gt;
&lt;li&gt;기존 RNN도 LSTM만큼 대단히 유용하지만 그 성능이 상황에 따라 그 때 그 때 다르다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="lstm"&gt;
 LSTM?
 &lt;a class="heading-anchor" href="#lstm" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;이러한 RNN에 단점을 보완한 긴 의존 기간을 필요로 하는 학습을 수행할 능력이 있는 LSTM이 Hochreiter &amp;amp; Schmidhuber(1997)에 의해 소개되었고, 그 후에 여러 추후 연구로 계속 발전하고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="keras-lstm"&gt;
 Keras LSTM
 &lt;a class="heading-anchor" href="#keras-lstm" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;keras&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sequential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keras&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LSTM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input_shape&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;input_shape는 (data size, time steps, features) 3차원으로 구성한다.&lt;/li&gt;
&lt;li&gt;대부분 data size는 따로 넘기지 않는다.&lt;/li&gt;
&lt;li&gt;보통 자동으로 전체 data size를 알 수 있기 때문이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="batch에-대하여"&gt;
 Batch에 대하여
 &lt;a class="heading-anchor" href="#batch%ec%97%90-%eb%8c%80%ed%95%98%ec%97%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Batch는 일괄 처리되는 작업의 양이다.&lt;/li&gt;
&lt;li&gt;위에서 설명된 data_size를 한번에 처리하는 갯수를 의미하며, batch크기에 의해 weight 변화가 일어나며 batch크기 단위로 data loading 함수도 구현이 가능하다.&lt;/li&gt;
&lt;li&gt;주의할점은 &lt;code&gt;data_size/batch_size&lt;/code&gt;일때 나머지가 없어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="batch-되는-양이-있다면-아래와-같이-설정할-수도-있다"&gt;
 batch 되는 양이 있다면 아래와 같이 설정할 수도 있다.
 &lt;a class="heading-anchor" href="#batch-%eb%90%98%eb%8a%94-%ec%96%91%ec%9d%b4-%ec%9e%88%eb%8b%a4%eb%a9%b4-%ec%95%84%eb%9e%98%ec%99%80-%ea%b0%99%ec%9d%b4-%ec%84%a4%ec%a0%95%ed%95%a0-%ec%88%98%eb%8f%84-%ec%9e%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;keras&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sequential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keras&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LSTM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch_input_shape&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;batch_size, time_steps, features 각각은 3,4,6이 된다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Netty] Netty in Action 요약 및 실무 활용</title><link>https://kyungryeol-yoon.github.io/backend/architecture/netty-in-action/</link><pubDate>Mon, 02 Sep 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/architecture/netty-in-action/</guid><description>&lt;h2 id="-netty-in-action-요약과-실무-활용"&gt;
 ⚡ Netty in Action 요약과 실무 활용
 &lt;a class="heading-anchor" href="#-netty-in-action-%ec%9a%94%ec%95%bd%ea%b3%bc-%ec%8b%a4%eb%ac%b4-%ed%99%9c%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Netty&lt;/strong&gt;는 Java 기반의 &lt;strong&gt;비동기 이벤트 기반 네트워크 애플리케이션 프레임워크&lt;/strong&gt;입니다.&lt;br&gt;
책 &lt;em&gt;Netty in Action&lt;/em&gt;은 Netty의 핵심 개념과 실무 적용법을 자세히 설명합니다.&lt;/p&gt;
&lt;p&gt;이 글에서는 다음 내용을 다룹니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Netty 핵심 개념&lt;/li&gt;
&lt;li&gt;아키텍처 및 이벤트 처리 모델&lt;/li&gt;
&lt;li&gt;Channel, Pipeline, Handler 이해&lt;/li&gt;
&lt;li&gt;TCP/UDP 서버/클라이언트 실무 활용&lt;/li&gt;
&lt;li&gt;실무에서 Netty 활용 팁&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="1-netty-핵심-개념"&gt;
 1️⃣ Netty 핵심 개념
 &lt;a class="heading-anchor" href="#1-netty-%ed%95%b5%ec%8b%ac-%ea%b0%9c%eb%85%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;비동기(Asynchronous)&lt;/strong&gt;: 모든 I/O 작업이 논블로킹 방식&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;이벤트 기반(Event-driven)&lt;/strong&gt;: 이벤트 발생 시 Handler가 동작&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reactor 패턴&lt;/strong&gt;: 이벤트 루프(EventLoop)가 I/O 이벤트를 감지하고 분배&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;🔹 장점: 고성능, 높은 동시성, 낮은 스레드 오버헤드&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="2-아키텍처-개요"&gt;
 2️⃣ 아키텍처 개요
 &lt;a class="heading-anchor" href="#2-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98-%ea%b0%9c%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Netty의 아키텍처는 &lt;strong&gt;Channel → Pipeline → Handler&lt;/strong&gt; 구조를 중심으로 이해합니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Client/Server
│
Channel ──&amp;gt; Pipeline ──&amp;gt; Handler&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Channel&lt;/strong&gt;: 소켓 연결, 읽기/쓰기 I/O 인터페이스&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pipeline&lt;/strong&gt;: Channel 이벤트를 처리할 Handler의 연결 체인&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Handler&lt;/strong&gt;: 실제 이벤트 처리 로직, 인코딩/디코딩, 비즈니스 로직 담당&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="3-eventloop와-thread-모델"&gt;
 3️⃣ EventLoop와 Thread 모델
 &lt;a class="heading-anchor" href="#3-eventloop%ec%99%80-thread-%eb%aa%a8%eb%8d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Netty는 &lt;strong&gt;Reactor + EventLoop&lt;/strong&gt; 모델 사용&lt;/li&gt;
&lt;li&gt;EventLoop가 I/O 이벤트를 감지하고 등록된 Handler 호출&lt;/li&gt;
&lt;li&gt;하나의 EventLoop는 여러 Channel을 처리 가능 → 스레드 최소화&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;EventLoopGroup
├─ EventLoop 1 → Channel A, B
├─ EventLoop 2 → Channel C, D&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;🔹 Thread-per-connection 모델보다 훨씬 효율적&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="4-tcp-서버-예제"&gt;
 4️⃣ TCP 서버 예제
 &lt;a class="heading-anchor" href="#4-tcp-%ec%84%9c%eb%b2%84-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;EventLoopGroup&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bossGroup&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NioEventLoopGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;EventLoopGroup&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;workerGroup&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NioEventLoopGroup&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ServerBootstrap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ServerBootstrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bossGroup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;workerGroup&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NioServerSocketChannel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;childHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ChannelInitializer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SocketChannel&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;initChannel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SocketChannel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;addLast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MyBusinessHandler&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ChannelFuture&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;closeFuture&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bossGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shutdownGracefully&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;workerGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shutdownGracefully&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ServerBootstrap&lt;/strong&gt;: 서버 설정&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ChannelInitializer&lt;/strong&gt;: Pipeline 설정&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MyBusinessHandler&lt;/strong&gt;: 이벤트 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="5-udp-서버-예제"&gt;
 5️⃣ UDP 서버 예제
 &lt;a class="heading-anchor" href="#5-udp-%ec%84%9c%eb%b2%84-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Bootstrap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bootstrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NioEventLoopGroup&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NioDatagramChannel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SimpleChannelInboundHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DatagramPacket&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;protected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;channelRead0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ChannelHandlerContext&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DatagramPacket&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 패킷 처리&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;9999&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;closeFuture&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;await&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NioDatagramChannel&lt;/strong&gt;: UDP 지원&lt;/li&gt;
&lt;li&gt;Handler에서 패킷 단위로 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="6-실무-활용-팁"&gt;
 6️⃣ 실무 활용 팁
 &lt;a class="heading-anchor" href="#6-%ec%8b%a4%eb%ac%b4-%ed%99%9c%ec%9a%a9-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;📝 &lt;strong&gt;Handler 분리&lt;/strong&gt;: 인코딩/디코딩과 비즈니스 로직을 분리&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;Pipeline 활용&lt;/strong&gt;: ChannelPipeline을 통해 이벤트 흐름 제어&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;Backpressure 관리&lt;/strong&gt;: Channel 옵션과 수신 처리 속도 조절&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;Connection 관리&lt;/strong&gt;: IdleStateHandler로 연결 유지/종료 관리&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;Netty + Spring Boot&lt;/strong&gt;: Embedded Netty 서버로 비동기 REST/WebSocket 구현 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="7-요약"&gt;
 7️⃣ 요약
 &lt;a class="heading-anchor" href="#7-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Netty&lt;/strong&gt; = 비동기 + 이벤트 기반 + Reactor 패턴 기반 네트워크 프레임워크&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;핵심 구조&lt;/strong&gt;: Channel → Pipeline → Handler&lt;/li&gt;
&lt;li&gt;TCP/UDP 모두 지원, 고성능 서버 개발에 최적화&lt;/li&gt;
&lt;li&gt;실무에서는 &lt;strong&gt;Handler 설계, Pipeline 구조, 이벤트 흐름&lt;/strong&gt; 이해가 핵심&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 결론: Netty는 단순 I/O 라이브러리가 아니라,
&lt;strong&gt;고성능 네트워크 애플리케이션을 구조적으로 설계할 수 있는 프레임워크&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Kubernetes] Control-Plane Node에 Pod 띄우기</title><link>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-not-create-pod-in-control-plane-node/</link><pubDate>Fri, 05 Jul 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-not-create-pod-in-control-plane-node/</guid><description>&lt;h2 id="control-plane-node에-pod를-올릴-경우"&gt;
 Control-Plane Node에 Pod를 올릴 경우
 &lt;a class="heading-anchor" href="#control-plane-node%ec%97%90-pod%eb%a5%bc-%ec%98%ac%eb%a6%b4-%ea%b2%bd%ec%9a%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="deployment-yaml-생성"&gt;
 deployment yaml 생성
 &lt;a class="heading-anchor" href="#deployment-yaml-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx-deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;containerPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="apply"&gt;
 Apply
 &lt;a class="heading-anchor" href="#apply" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl apply -f nginx-deployment.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;deployment.apps/nginx-deployment created&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="pod-상태-확인-pending-상태로-지속-됨"&gt;
 Pod 상태 확인 (Pending 상태로 지속 됨)
 &lt;a class="heading-anchor" href="#pod-%ec%83%81%ed%83%9c-%ed%99%95%ec%9d%b8-pending-%ec%83%81%ed%83%9c%eb%a1%9c-%ec%a7%80%ec%86%8d-%eb%90%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;NAME READY STATUS RESTARTS AGE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;nginx-deployment-6dd86d77d-4rkhf 0/1 Pending &lt;span class="m"&gt;0&lt;/span&gt; 20m&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="pod-상태-자세히-확인"&gt;
 Pod 상태 자세히 확인
 &lt;a class="heading-anchor" href="#pod-%ec%83%81%ed%83%9c-%ec%9e%90%ec%84%b8%ed%9e%88-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;kubectl describe pod nginx-deployment-6dd86d77d-4rkhf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;Name: nginx-deployment-6dd86d77d-4rkhf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;Namespace: default
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;...✂...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;Events:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; Type Reason Age From Message 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; ---- ------ ---- ---- ------- 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; Warning FailedScheduling 43s &lt;span class="o"&gt;(&lt;/span&gt;x17 over 22m&lt;span class="o"&gt;)&lt;/span&gt; default-scheduler 0/3 nodes are available: &lt;span class="m"&gt;3&lt;/span&gt; node&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt; had taints that the pod didn&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;t tolerate.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="위처럼-pending-상태로-안올라오는-이유는-contrl-plane-node에-pod를-못-올리도록-설정되어-있기-때문"&gt;
 위처럼 Pending 상태로 안올라오는 이유는 Contrl-Plane Node에 Pod를 못 올리도록 설정되어 있기 때문
 &lt;a class="heading-anchor" href="#%ec%9c%84%ec%b2%98%eb%9f%bc-pending-%ec%83%81%ed%83%9c%eb%a1%9c-%ec%95%88%ec%98%ac%eb%9d%bc%ec%98%a4%eb%8a%94-%ec%9d%b4%ec%9c%a0%eb%8a%94-contrl-plane-node%ec%97%90-pod%eb%a5%bc-%eb%aa%bb-%ec%98%ac%eb%a6%ac%eb%8f%84%eb%a1%9d-%ec%84%a4%ec%a0%95%eb%90%98%ec%96%b4-%ec%9e%88%ea%b8%b0-%eb%95%8c%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="contrl-plane-node-확인-아래-master는-contrl-plane-node-name"&gt;
 Contrl-Plane Node 확인 (아래 master는 Contrl-Plane Node Name)
 &lt;a class="heading-anchor" href="#contrl-plane-node-%ed%99%95%ec%9d%b8-%ec%95%84%eb%9e%98-master%eb%8a%94-contrl-plane-node-name" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl describe node master &lt;span class="p"&gt;|&lt;/span&gt; grep Taints
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;Taints: node-role.kubernetes.io/master:NoSchedule&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="pod를-올리고-싶을-경우"&gt;
 Pod를 올리고 싶을 경우
 &lt;a class="heading-anchor" href="#pod%eb%a5%bc-%ec%98%ac%eb%a6%ac%ea%b3%a0-%ec%8b%b6%ec%9d%84-%ea%b2%bd%ec%9a%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="taint-설정-해제"&gt;
 Taint 설정 해제
 &lt;a class="heading-anchor" href="#taint-%ec%84%a4%ec%a0%95-%ed%95%b4%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl taint nodes –all node-role.kubernetes.io/master-
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;node/master untainted
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;Pod 상태 재조회 &lt;span class="o"&gt;(&lt;/span&gt;자동으로 restart&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods -o wide
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;nginx-deployment-6dd86d77d-4rkhf 1/1 Running &lt;span class="m"&gt;0&lt;/span&gt; 35m 10.244.0.7 master &amp;lt;none&amp;gt; &amp;lt;none&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="다시-pod를-못-올리도록-설정하고-싶은-경우"&gt;
 다시 Pod를 못 올리도록 설정하고 싶은 경우
 &lt;a class="heading-anchor" href="#%eb%8b%a4%ec%8b%9c-pod%eb%a5%bc-%eb%aa%bb-%ec%98%ac%eb%a6%ac%eb%8f%84%eb%a1%9d-%ec%84%a4%ec%a0%95%ed%95%98%ea%b3%a0-%ec%8b%b6%ec%9d%80-%ea%b2%bd%ec%9a%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="taint-설정"&gt;
 Taint 설정
 &lt;a class="heading-anchor" href="#taint-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl taint nodes master node-role.kubernetes.io&lt;span class="o"&gt;=&lt;/span&gt;master:NoSchedule
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;node/master tainted&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="확인"&gt;
 확인
 &lt;a class="heading-anchor" href="#%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl describe node master &lt;span class="p"&gt;|&lt;/span&gt; grep Taints
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;Taints: node-role.kubernetes.io&lt;span class="o"&gt;=&lt;/span&gt;master:NoSchedule&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Web 신입 면접 정리</title><link>https://kyungryeol-yoon.github.io/cs/interview/web-newcomer-interview/</link><pubDate>Sat, 01 Jun 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/cs/interview/web-newcomer-interview/</guid><description>&lt;h2 id="oracle-클러스터-인덱스와-넌-클러스터-인덱스의-차이"&gt;
 Oracle 클러스터 인덱스와 넌 클러스터 인덱스의 차이
 &lt;a class="heading-anchor" href="#oracle-%ed%81%b4%eb%9f%ac%ec%8a%a4%ed%84%b0-%ec%9d%b8%eb%8d%b1%ec%8a%a4%ec%99%80-%eb%84%8c-%ed%81%b4%eb%9f%ac%ec%8a%a4%ed%84%b0-%ec%9d%b8%eb%8d%b1%ec%8a%a4%ec%9d%98-%ec%b0%a8%ec%9d%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;클러스터드 인덱스 : 실제 DB의 데이터 파일에 정렬되어 있는 상태로 디스크에 저장이 됨. (테이블당 한개)&lt;/li&gt;
&lt;li&gt;넌클러스터드 인덱스 : 실제 DB의 데이터 파일에 정렬되지 않는 상태로 디스크에 저장이 됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="get-방식과-post-방식"&gt;
 GET 방식과 POST 방식?
 &lt;a class="heading-anchor" href="#get-%eb%b0%a9%ec%8b%9d%ea%b3%bc-post-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GET
&lt;ul&gt;
&lt;li&gt;클라이언트에서 서버로 데이터를 전달할 때, 주소 뒤에 &amp;ldquo;이름&amp;quot;과 &amp;ldquo;값&amp;quot;이 결합된 스트링 형태로 전달.&lt;/li&gt;
&lt;li&gt;주소창에 쿼리 스트링이 그대로 보여지기 때문에 보안성이 떨어진다.&lt;/li&gt;
&lt;li&gt;길이에 제한이 있다.(=전송 데이터의 한계가 있다.)&lt;/li&gt;
&lt;li&gt;Post 방식보다 상대적으로 전송 속도가 빠르다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;POST
&lt;ul&gt;
&lt;li&gt;일정 크기 이상의 데이터를 보내야 할 때 사용한다.&lt;/li&gt;
&lt;li&gt;서버로 보내기 전에 인코딩하고, 전송 후 서버에서는 다시 디코딩 작업을 한다.&lt;/li&gt;
&lt;li&gt;주소창에 전송하는 데이터의 정보가 노출되지 않아 Get 방식에 비해 보안성이 높다.&lt;/li&gt;
&lt;li&gt;속도가 Get 방식보다 느리다.&lt;/li&gt;
&lt;li&gt;쿼리스트링(문자열) 데이터 뿐만 아니라, 라디오 버튼, 텍스트 박스 같은 객체들의 값도 전송가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Get과 Post 차이점
&lt;ul&gt;
&lt;li&gt;Get은 주로 웹 브라우저가 웹 서버에 데이터를 요청할 때 사용.&lt;/li&gt;
&lt;li&gt;Post는 웹 브라우저가 웹 서버에 데이터를 전달하기 위해 사용.&lt;/li&gt;
&lt;li&gt;Get을 사용하면 웹 브라우저에서 웹 서버로 전달되는 데이터가 인코딩되어 URL에 붙는다.&lt;/li&gt;
&lt;li&gt;Post 방식은 전달되는 데이터가 보이지 않는다.&lt;/li&gt;
&lt;li&gt;Get 방식은 전달되는 데이터가 255개의 문자를 초과하면 무넺가 발생할 수 있다.&lt;/li&gt;
&lt;li&gt;웹서버에 많은 데이터를 전달하기 위해서는 Post 방식을 사용하는 것이 바람직하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="session과-cookie"&gt;
 Session과 Cookie
 &lt;a class="heading-anchor" href="#session%ea%b3%bc-cookie" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Session과 Cookie 사용 이유
&lt;ul&gt;
&lt;li&gt;현재 우리가 인터넷에서 사용하고 있는 HTTP프로토콜은 연결 지향적인 성격을 버렸기 때문에 새로운 페이지를 요청할 때마다 새로운 접속이 이루어지며 이전 페이지와 현재 페이지 간의 관계가 지속되지 않는다. 이에 따라 HTTP프로토콜을 이용하게 되는 웹사이트에서는 웹페이지에 특정 방문자가 머무르고 있는 동안에 그 방문자의 상태를 지속시키기 위해 쿠키와 세션을 이용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Session
&lt;ul&gt;
&lt;li&gt;특정 웹사이트에서 사용자가 머무르는 기간 또는 한 명의 사용자의 한번의 방문을 의미한다.&lt;/li&gt;
&lt;li&gt;Session에 관련된 데이터는 Server에 저장된다.&lt;/li&gt;
&lt;li&gt;웹 브라우저의 캐시에 저장되어 브라우저가 닫히거나 서버에서 삭제시 사라진다.&lt;/li&gt;
&lt;li&gt;Cookie에 비해 보안성이 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cookie
&lt;ul&gt;
&lt;li&gt;사용자 정보를 유지할 수 없다는 HTTP의 한계를 극복할 수 있는 방법.&lt;/li&gt;
&lt;li&gt;인터넷 웹 사이트의 방문 기록을 남겨 사용자와 웹 사이트 사이를 매개해 주는 정보이다.&lt;/li&gt;
&lt;li&gt;Cookie는 인터넷 사용자가 특정 웹서버에 접속할 때, 생성되는 개인 아이디와 비밀번호, 방문한 사이트의 정보를 담은 임시 파일로써, Server가 아닌 Client에 텍스트 파일로 저장되어 다음에 해당 웹서버를 찾을 경우 웹서버에서는 그가 누구인지 어떤 정보를 주로 찾았는지 등을 파악할 때 사용된다.&lt;/li&gt;
&lt;li&gt;Cookie는 Client PC에 저장되는 정보기 때문에, 다른 사용자에 의해서 임의로 변경이 가능하다.(정보 유출 가능, Session보다 보안성이 낮은 이유)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;보안성이 낮은 Cookie 대신 Session을 사용하면 되는데 안하는 이유?
&lt;ul&gt;
&lt;li&gt;모든 정보를 Session에 저장하면 Server의 메모리를 과도하게 사용하게 되어 Server에 무리가 감.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="jdbc"&gt;
 JDBC
 &lt;a class="heading-anchor" href="#jdbc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Java Data Base Connection의 약자로 JAVA 언어를 통해 데이터 베이스에 접근 할 수 있는 프로그래밍의 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="servlet-vs-jsp"&gt;
 Servlet vs JSP
 &lt;a class="heading-anchor" href="#servlet-vs-jsp" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Servlet : 자바 언어로 웹 개발을 위해 만들어진 것으로, Container가 이해할 수 있게 구성된 순수 자바코드로만 이루어진 것.&lt;/li&gt;
&lt;li&gt;JSP : html 기반에 JAVA 코드를 블록화하여 삽입한 것으로 Servlet을 좀 더 쉽게 접근할 수 있도록 만들어 진 것.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="overloading오버로딩과-overriding오버라이딩의-차이"&gt;
 Overloading(오버로딩)과 Overriding(오버라이딩)의 차이?
 &lt;a class="heading-anchor" href="#overloading%ec%98%a4%eb%b2%84%eb%a1%9c%eb%94%a9%ea%b3%bc-overriding%ec%98%a4%eb%b2%84%eb%9d%bc%ec%9d%b4%eb%94%a9%ec%9d%98-%ec%b0%a8%ec%9d%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Overloading(오버로딩)
&lt;ul&gt;
&lt;li&gt;메서드 명은 동일하지만, 매개 변수 타입과 개수를 다르게 해 선언하는 방식.&lt;/li&gt;
&lt;li&gt;같은 이름의 메소드를 여러개 정의하는 것.&lt;/li&gt;
&lt;li&gt;매개변수의 타입이 다르거나 개수가 달라야 한다.&lt;/li&gt;
&lt;li&gt;return type과 접근 제어자는 영향을 주지 않음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Overriding(오버라이딩)
&lt;ul&gt;
&lt;li&gt;상속한 자식에서 부모의 메서드를 재정의하는 방식(부모 클래스의 메소드를 자식 클래스에서 재정의)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="mvc-패턴이란"&gt;
 MVC 패턴이란?
 &lt;a class="heading-anchor" href="#mvc-%ed%8c%a8%ed%84%b4%ec%9d%b4%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Model : data 처리와 접근을 담당, 소프트웨어 응용과 그와 관련된 고급 클래스 내의 논리적 데이터 기반 구조를 표현, 이 목적 모형은 사용자 인터페이스에 관한 어떠한 정보도 가지고 있지 않다.&lt;/li&gt;
&lt;li&gt;View : Client에 보여지는 화면을 담당, 사용자 인터페이스 내의 구성요소들을 표현(사용자에게 보여지는 화면)&lt;/li&gt;
&lt;li&gt;Controller : Model과 View를 제어
하는 3가지 부분으로 나눔으로서, 데이터와 화면 간의 의존관계를 벗어날 수 있게하는 개발 기법.&lt;/li&gt;
&lt;li&gt;사용자가 보는 페이지, 데이터 처리, 그리고 이 2가지를 중간에서 제어하는 컨트롤, 이 3가지로 구성되는 하나의 애플리케이션을 만들면 각각 맡은 바에만 집중을 할 수 있게 됨.&lt;/li&gt;
&lt;li&gt;객체지향프로그래밍에서, MVC란 사용자 인터페이스를 성공적이며 효과적으로 데이터 모형에 관련 시키기 위한 방법론 또는 설계 방식 중 하나.&lt;/li&gt;
&lt;li&gt;MVC 패턴은 목적 코드의 재사용에 유용한 것은 물론, 사용자 인터페이스와 응용프로그램 개발에 소요되는 시간을 현저하게 줄여주는 형식이라고 많은 개발자들이 평가하고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="싱글톤singletone-pattern"&gt;
 싱글톤(SingleTone Pattern)
 &lt;a class="heading-anchor" href="#%ec%8b%b1%ea%b8%80%ed%86%a4singletone-pattern" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;대표적으로 Calendar 객체나 dataSource 객체처럼 객체가 하나만 생성되어야 하는 경우 전체 코드에서 하나의 객체만 존재할 수 있도록 이미 생성된 객체가 있으면 그 객체를 사용하도록 하는 방식.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="팩토리-패턴factory-pattern"&gt;
 팩토리 패턴(Factory Pattern)
 &lt;a class="heading-anchor" href="#%ed%8c%a9%ed%86%a0%eb%a6%ac-%ed%8c%a8%ed%84%b4factory-pattern" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;객체간 의존성을 줄이기 위해 객체의 생성과 데이터 주입만 담당하는 Factory Class를 정의하고 개발 코드 부분에서는 생성된 객체를 가져다 사용함으로서 의존성을 줄이는 방식.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="옵저버-패턴observer-pattern"&gt;
 옵저버 패턴(Observer Pattern)
 &lt;a class="heading-anchor" href="#%ec%98%b5%ec%a0%80%eb%b2%84-%ed%8c%a8%ed%84%b4observer-pattern" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;기후 정보처럼 RSS 수신시 하나의 객체가 변하면 다른 객체에 객체가 변했다는 사항을 알려주어야 할 경우에 주로 사용.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="spring의-aop관점-지향-프로그래밍란"&gt;
 Spring의 AOP(관점 지향 프로그래밍)란?
 &lt;a class="heading-anchor" href="#spring%ec%9d%98-aop%ea%b4%80%ec%a0%90-%ec%a7%80%ed%96%a5-%ed%94%84%eb%a1%9c%ea%b7%b8%eb%9e%98%eb%b0%8d%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AOP는 Aspect Oriented Programming 관점 지향 프로그래밍의 약자로, 기존의 OOP(객체 지향 프로그래밍)에서 기능별로 class를 분리했음에도 불구하고, 여전히 로그, 트랜잭션, 자원해제, 성능테스트 메서드처럼 공통적으로 반복되는 중복코드가 여전히 발생하는 단점을 해결하고자 나온 방식으로 이러한 공통 코드를 &amp;ldquo;횡단 관심사&amp;quot;라 표현하며 개발코드에서는 비지니스 로직에 집중하고 실행시에 비지니스 로직 앞, 뒤 등 원하는 지점에 해당 공통 관심사를 수행할 수 있게 함으로서 중복 코드를 줄일 수 있는 방식&lt;/li&gt;
&lt;li&gt;공통의 관심사항을 적용해서 발생하는 의존관계의 복잡성과 코드 중복을 해소해 주는 프로그래밍 기법. OOP라 하면 관심사가 같은 기능과 데이터를 한데 모아서 객체 지향 설계 원칙에 따라 분리하고, 서로 낮은 결합도를 가진채 독립적이고 유연하게 확장할 수 있는 모듈로 캡슐화 하는 것을 일컫는다. 하지만 대부분의 프로젝트에서는 메소드의 호출 전후의 데이터 확인을 위한 로깅이나 예외처리, 데이터 검증과 관련된 코드가 클래스 전반에 걸쳐서 쓰여지고 있음. OOP 모듈화를 방해. 클래스 여기저기에 반복적으로 나타나서 핵심로직 코드의 가독성이나 확장성, 유지보수 등의 효율을 떨어뜨림. 이렇게 관련된 코드를 한데 모아 모듈화 하여 핵심 로직으로부터 분리하고 개발하는 방식을 AOP&lt;/li&gt;
&lt;li&gt;장점 : 중복되는 코드 제거, Unit Testing 편의성, 유지보수성 향상&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="spirng에서-ioc제어의-역전란"&gt;
 Spirng에서 IoC(제어의 역전)란?
 &lt;a class="heading-anchor" href="#spirng%ec%97%90%ec%84%9c-ioc%ec%a0%9c%ec%96%b4%ec%9d%98-%ec%97%ad%ec%a0%84%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;프레임워크가 제어권을 가짐. 객체 생성도 컨테이너가 함. IoC 의존관계를 결정, 설정, 생명주기를 해결하기 위한 디자인 패턴&lt;/li&gt;
&lt;li&gt;IoC가 아닌 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;IoC인 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Autowired&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;UserService&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;객체 생성 생명 주기 관리. 의존성 관리. POJO의 생성, 초기화, 서비스, 소멸에 대한 권한을 가짐.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ioc-분류"&gt;
 IoC 분류
 &lt;a class="heading-anchor" href="#ioc-%eb%b6%84%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;DL(의존성 검색(특정 컨테이너에 종속되는 API 사용)) : 저장소에 저장되어 있는 Bean에 접근하기 위해 컨테이너가 제공하는 API를 이용하여 Bean을 조회하는 것. 컨테이너가 제공하는 API를 사용하기 때문에 컨테이너에 종속성이 늘어남.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DI : 각 클래스간의 의존관계를 Bean설정 정보를 바탕으로 컨테이너가 자동으로 연결시켜주는 것.
** SetterInjection(셋터를 통해 주입)
** Constructor(생성자를 통해 주입)
** Method(자바 메서드를 통해 주입)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;의존관계 Bean설정(사용자가 설정해줌), 어노테이션 등등이 있다. 컨테이너가 정보들을 읽고 자동으로 설정.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Autowired&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 의존관계 설정&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;UserService&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;컨테이너가 흐름의 주체가 된다.(사용자가 설정해준 것을 컨테이너가 연결)&lt;/li&gt;
&lt;li&gt;장점 : 코드가 단순, 컴포넌트 간의 결합도 제거&lt;/li&gt;
&lt;li&gt;Spring DI 컨테이너가 관리하는 객체를 Bean, 이 Bean들을 관리한다는 의미로 컨테이너를 Bean Factory.&lt;/li&gt;
&lt;li&gt;Spring API에서 BeanFactory 인터페이스 제공.&lt;/li&gt;
&lt;li&gt;BeanFactory에 여러가지 컨테이너 기능을 추가하여 애플리케이션 컨텍스트라고 부름.&lt;/li&gt;
&lt;li&gt;BeanFactory : Bean을 등록, 생성, 조회, 반환 관리한다. 이를 확장한 것이 Application Context.&lt;/li&gt;
&lt;li&gt;Application Context(DI 컨테이너 역할) : Spring의 각종 부가 서비스 추가 제공.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="pojo특정-규약에-종속되지-않는-자바-객체"&gt;
 POJO(특정 규약에 종속되지 않는 자바 객체?)
 &lt;a class="heading-anchor" href="#pojo%ed%8a%b9%ec%a0%95-%ea%b7%9c%ec%95%bd%ec%97%90-%ec%a2%85%ec%86%8d%eb%90%98%ec%a7%80-%ec%95%8a%eb%8a%94-%ec%9e%90%eb%b0%94-%ea%b0%9d%ec%b2%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;특정 규약에 종속되지 않는다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;특정 환경에 종속되지 않는다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;객체 지향 원리에 충실해야 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;사용 이유&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;코드 간결함.&lt;/li&gt;
&lt;li&gt;자동화 테스트에 유리.&lt;/li&gt;
&lt;li&gt;객체지향적 설계의 자유로운 사용.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="spring에서-di의존성-주입란"&gt;
 Spring에서 DI(의존성 주입)란?
 &lt;a class="heading-anchor" href="#spring%ec%97%90%ec%84%9c-di%ec%9d%98%ec%a1%b4%ec%84%b1-%ec%a3%bc%ec%9e%85%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;DI는 Dependency Injection(의존성 주입)의 약자로, 객체들 간의 의존성을 줄이기 위해 사용되는 Spring의 IoC 컨테이너의 구체적인 구현 방식, DI는 기존처럼 개발코드 부분에서 객체를 생성하는 것이 아니라, 팩토리 패턴처럼 객체의 생성과, 데이터를 주입만 담당하는 Factory에 해당 하는 별도의 공간에서 객체를 생성하고 데이터간의 의존성을 주입해 개발코드에서는 이를 가져다 씀으로서 의존성을 줄이는 방식. 이 때, Factory 패턴의 Factory Class의 역할을 Spring의 환경설정 파일이 담당.&lt;/li&gt;
&lt;li&gt;객체 간의 의존관계를 객체 자신이 아닌 외부 조립기가 수행해준다는 개념. DI패턴을 적용할 경우 클래스는 의존하는 객체를 전달받기 위한 설정 메소드다. 생성자를 제공할 뿐 직접 의존하는 클래스를 찾지 않음. 의존하는 객체를 조립기가 삽입해주기 때문에 이 방식을 DI패턴이라고 함. DI패턴 사용시 단위테스트가 가능. 단위테스트는 코드의 품질을 향상시키고 개발속도 증가 시킴. 의존적인 객체를 직접 생성하거나 제어하는 것이 아니라, 특성 객체에 필요한 객체를 외부에서 결정해서 연결시키는 것.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dao"&gt;
 DAO
 &lt;a class="heading-anchor" href="#dao" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Database의 data에 접근하기 위한 객체&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dto"&gt;
 DTO
 &lt;a class="heading-anchor" href="#dto" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;로직을 가지지 않은 순수 데이터 객체(getter, setter)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="spirng-mvc-처리-순서"&gt;
 Spirng MVC 처리 순서
 &lt;a class="heading-anchor" href="#spirng-mvc-%ec%b2%98%eb%a6%ac-%ec%88%9c%ec%84%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;클라이언트가 서버에 어떤 요청을 한다면 스프링에서 제공하는 DispatcherServlet이라는 클래스가 요청을 가로챈다.&lt;/li&gt;
&lt;li&gt;요청을 가로챈 DispatcherServlet은 HaddlerMapping에게 어떤 컨트롤러에게 요청을 위임하면 좋을지 물어본다.&lt;/li&gt;
&lt;li&gt;요청에 매핑된 컨트롤러가 있다면 &lt;code&gt;@RequestMapping&lt;/code&gt;을 통하여 요청을 처리할 메서드에 도달한다.&lt;/li&gt;
&lt;li&gt;컨트롤러에서는 해당 요청을 처리할 Service를 주입(DI)를 받아 비지니스 로직을 Service에게 위임한다.&lt;/li&gt;
&lt;li&gt;Service에서는 요청에 필요한 작업 대부분(코딩)을 담당, DB처리는 DAO를 주입 받아 위임한다.&lt;/li&gt;
&lt;li&gt;DAO는 mybatis 설정을 이용해 SQL쿼리를 날려 DB의 정보를 받아 서비스에게 다시 돌려준다.이 때 보통 VO(DTO)를 컨트롤러에서부터 내려받아 쿼리의 결과를 VO에 담는다.(mybatis의 resulttype)&lt;/li&gt;
&lt;li&gt;모든 로직을 끝낸 서비스가 결과를 컨트롤러에게 넘긴다.&lt;/li&gt;
&lt;li&gt;결과를 받은 컨트롤러는 Model 객체에 결과물인 어떤 view(jsp) 파일을 보내줄 것인지 등의 정보를 담아 DispatcherServlet에게 보낸다.&lt;/li&gt;
&lt;li&gt;DispatcherServlet은 ViewResolver에게 받은 뷰의 대한 정보를 넘긴다.&lt;/li&gt;
&lt;li&gt;ViewResolver는 해당 jsp를 찾아서(응답할 view를 찾음) DispatcherServlet에게 알려준다.(servlet-context.xml에서 suffix, preffix를 통해 /WEB-INF/views/index.jsp 이렇게 만들어주는 것도 ViewResolver)&lt;/li&gt;
&lt;li&gt;DispatcherServlet은 응답할 view에게 Render를 지시하고 view는 응답 로직을 처리한다.&lt;/li&gt;
&lt;li&gt;결과적으로 DispatcherServlet이 클라이언트에게 렌더링된 view를 응답한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="추상메서드-추상클래스-interface인터페이스"&gt;
 추상메서드? 추상클래스? Interface(인터페이스)?
 &lt;a class="heading-anchor" href="#%ec%b6%94%ec%83%81%eb%a9%94%ec%84%9c%eb%93%9c-%ec%b6%94%ec%83%81%ed%81%b4%eb%9e%98%ec%8a%a4-interface%ec%9d%b8%ed%84%b0%ed%8e%98%ec%9d%b4%ec%8a%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;추상메서드 : 메서드의 정의부만 있고 구현부는 있지 않은 메서드&lt;/li&gt;
&lt;li&gt;추상클래스 : 추상메서드를 적어도 하나 이상 가지고 있는 클래스로 자식클래스에서 오버라이딩(재정의)가 필요한 추상메서드를 가지고 있기 때문에 객체화 할 수 없다.&lt;/li&gt;
&lt;li&gt;Interface(인터페이스)
&lt;ul&gt;
&lt;li&gt;일종의 추상 클래스.&lt;/li&gt;
&lt;li&gt;오직 추상 메서드와 상수만을 멤버로 갖는다.&lt;/li&gt;
&lt;li&gt;Implements 키워드를 사용.&lt;/li&gt;
&lt;li&gt;상속의 관계가 없는 클래스간 서로 공통되는 로직을 구현하여 쓸 수 있도록 한다.&lt;/li&gt;
&lt;li&gt;Extends는 하나의 클래스만 상속 가능하나 Interface는 다중 상속이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Abstract
&lt;ul&gt;
&lt;li&gt;추상메서드를 하나 이상 가진 클래스.&lt;/li&gt;
&lt;li&gt;자신의 생성자로 객체 생성 불가능.&lt;/li&gt;
&lt;li&gt;하위 클래스를 참조하여 상위 클래스의 객체를 생성.&lt;/li&gt;
&lt;li&gt;하위 클래스를 제어하기 위해 사용.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Interface vs Abstract
&lt;ul&gt;
&lt;li&gt;공통점
&lt;ul&gt;
&lt;li&gt;new 연산자로 인스턴스 생성 불가능.&lt;/li&gt;
&lt;li&gt;프로토타입만 있는 메서드를 갖는다.&lt;/li&gt;
&lt;li&gt;사용하기 위해서는 하위클래스에서 확장/구현 해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;차이점
&lt;ul&gt;
&lt;li&gt;사용하는 키워드가 다르다.&lt;/li&gt;
&lt;li&gt;Abstract는 일반 메서드를 사용할 수 있지만, Interface는 메서드 선언만 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="call-by-reference-call-by-value"&gt;
 Call by Reference, Call by Value
 &lt;a class="heading-anchor" href="#call-by-reference-call-by-value" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Call by Reference : 매개 변수의 원래 주소에 값을 저장하는 방식, 클래스 객체를 인수로 전달한 경우&lt;/li&gt;
&lt;li&gt;Call by Value : 인수로 기본 데이터형을 사용, 주어진 값을 복사하여 처리하는 방식, 메서드 내의 처리 결과는 메서드 밖의 변수에 영향을 미치지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="static"&gt;
 Static
 &lt;a class="heading-anchor" href="#static" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;클래스가 로딩될 때, 메모리 공간을 할다하는데 처음 설정된 메모리 공간이 변하지 않음을 의미.&lt;/li&gt;
&lt;li&gt;객체를 아무리 많이 만들어도 해당 변수는 하나만 존재(객체와 무관한 키워드)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="캐시cache와-세션session의-공통점과-차이점은"&gt;
 캐시(Cache)와 세션(Session)의 공통점과 차이점은?
 &lt;a class="heading-anchor" href="#%ec%ba%90%ec%8b%9ccache%ec%99%80-%ec%84%b8%ec%85%98session%ec%9d%98-%ea%b3%b5%ed%86%b5%ec%a0%90%ea%b3%bc-%ec%b0%a8%ec%9d%b4%ec%a0%90%ec%9d%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;공통점 : 둘 다 사용자의 데이터를 저장&lt;/li&gt;
&lt;li&gt;캐시 : 캐시는 Client 컴퓨터에 저장했다 서버 요청시 네트워크를 타고 서버로 전달되기 때문에 보안에 취약하다.&lt;/li&gt;
&lt;li&gt;세션 : 세션은 서버에 저장되고 브라우저 단위로 관리된다. 캐시에 비해 보안성이 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="프로세스process와-쓰레드thread의-차이점"&gt;
 프로세스(Process)와 쓰레드(Thread)의 차이점?
 &lt;a class="heading-anchor" href="#%ed%94%84%eb%a1%9c%ec%84%b8%ec%8a%a4process%ec%99%80-%ec%93%b0%eb%a0%88%eb%93%9cthread%ec%9d%98-%ec%b0%a8%ec%9d%b4%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;프로세스(Process) : OS가 메모리 등의 자원을 할당해준 실행중인 프로그램을 가리킨다. 이 때, 각각의 프로세스는 서로 메모리 공간을 독자적으로 갖기 때문에 서로 메모리 공간을 공유하지 못한다. 따라서 공유하기 위해서는 IPC(InterProcess Communication)과 같은 방식이 필요.&lt;/li&gt;
&lt;li&gt;쓰레드(Thread) : 쓰레드는 프로세스 내에서 프로세스의 자원을 가지고 실제로 일하는 &amp;ldquo;일꾼&amp;quot;과 같으며 각 쓰레드는 독자적인 Stack 메모리를 갖고 그 외의 자원(메모리)는 프로세스 내에서 공유하기 된다. 프로세스 내에서 동시에 실행되는 독립적인 실행 단위를 말함. 장점으로는 자원을 많이 사용하지 않고 구현이 쉬우며 범용성이 높다.
&lt;ul&gt;
&lt;li&gt;쓰레드(Thread) 장점
&lt;ul&gt;
&lt;li&gt;빠른 프로세스 생성&lt;/li&gt;
&lt;li&gt;적은 메모리 사용&lt;/li&gt;
&lt;li&gt;쉬운 정보 공유&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;쓰레드(Thread) 단점
&lt;ul&gt;
&lt;li&gt;교착상태에 빠질 수 있다.(교착상태 : 다중프로그래밍 체제에서 하나 또는 그 이상의 프로세스가 수행할 수 없는 어떤 특정시간을 기다리고 있는 상태)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;데드락 : 프로세스가 자원을 얻지 못해 다음 처리를 못하는 상태로, &amp;lsquo;교착 상태&amp;rsquo;라고도 하며 시스템적으로 한정된 자원을 여러 곳에서 사용하려고 할 때 발생.
&lt;ul&gt;
&lt;li&gt;발생 조건
&lt;ul&gt;
&lt;li&gt;상호 배제(Mutual Exclusion) : 자원은 한 번에 한 프로세스만이 사용할 수 있어야 한다.&lt;/li&gt;
&lt;li&gt;점유 대기(Hold and Wait) : 최소한 하나의 자원을 점유하고 있으면서 다른 프로세스에 할당되어 사용하고 있는 자원을 추가로 점유하기 위해 대기하는 프로세스가 있어야 한다.&lt;/li&gt;
&lt;li&gt;비선점(No preemption) : 다른 프로세스에 할당된 자원은 사용이 끝날 때까지 강제로 빼앗을 수 없어야 한다.&lt;/li&gt;
&lt;li&gt;순환 대기(Circular Wait) : 프로세스의 집합 {P0, P1, , &amp;hellip; Pn}에서 P0는 P1이 점유한 자원을 대기하고 P1은 P2가 점유한 자원을 대기하고 P2&amp;hellip;Pn-1은 Pn이 점유한 자원을 대기하며 Pn은 P0가 점유한 자원을 요구해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;프로세스(Process)와 쓰레드(Thread) 차이
&lt;ul&gt;
&lt;li&gt;여러 분야에서 &amp;lsquo;과정&amp;rsquo; 또는 &amp;lsquo;처리&amp;rsquo;라는 뜻으로 사용되는 용어로 컴퓨터 분야에서는 &amp;lsquo;실행중인 프로그램&amp;rsquo;이라는 뜻으로 쓰인다. 이 프로세스 내에서 실행되는 각각의 일을 쓰레드라고 한다. 프로세스 내에서 실행되는 세부 작업 단위로 여러 개의 쓰레드가 하나의 프로세스를 이루게 되는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="자바-스레드java-thread-란"&gt;
 자바 스레드(Java Thread) 란?
 &lt;a class="heading-anchor" href="#%ec%9e%90%eb%b0%94-%ec%8a%a4%eb%a0%88%eb%93%9cjava-thread-%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;일반 스레드와 거의 차이가 없으며, JVM가 운영체제의 역할을 한다.&lt;/li&gt;
&lt;li&gt;자바에는 프로세스가 존재하지 않고 스레드만 존재하며, 자바 스레드는 JVM에 의해 스케줄되는 실행 단위 코드 블록이다.&lt;/li&gt;
&lt;li&gt;자바에서 스레드 스케줄링은 전적으로 JVM에 의해 이루어진다.&lt;/li&gt;
&lt;li&gt;아래와 같은 스레드와 관련된 많은 정보들도 JVM이 관리한다.
&lt;ul&gt;
&lt;li&gt;스레드가 몇 개 존재하는지&lt;/li&gt;
&lt;li&gt;스레드로 실행되는 프로그램 코드의 메모리 위치는 어디인지&lt;/li&gt;
&lt;li&gt;스레드의 상태는 무엇인지&lt;/li&gt;
&lt;li&gt;스레드 우선순위는 얼마인지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;즉, 개발자는 자바 스레드로 작동할 스레드 코드를 작성하고, 스레드 코드가 생명을 가지고 실행을 시작하도록 JVM에 요청하는 일 뿐이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="멀티-프로세스와-멀티-스레드의-차이"&gt;
 멀티 프로세스와 멀티 스레드의 차이
 &lt;a class="heading-anchor" href="#%eb%a9%80%ed%8b%b0-%ed%94%84%eb%a1%9c%ec%84%b8%ec%8a%a4%ec%99%80-%eb%a9%80%ed%8b%b0-%ec%8a%a4%eb%a0%88%eb%93%9c%ec%9d%98-%ec%b0%a8%ec%9d%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;멀티 프로세스
&lt;ul&gt;
&lt;li&gt;멀티 프로세싱이란
&lt;ul&gt;
&lt;li&gt;하나의 응용프로그램을 여러 개의 프로세스로 구성하여 각 프로세스가 하나의 작업(태스크)을 처리하도록 하는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;여러 개의 자식 프로세스 중 하나에 문제가 발생하면 그 자식 프로세스만 죽는 것 이상으로 다른 영향이 확산되지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;Context Switching에서의 오버헤드
&lt;ul&gt;
&lt;li&gt;Context Switching 과정에서 캐쉬 메모리 초기화 등 무거운 작업이 진행되고 많은 시간이 소모되는 등의 오버헤드가 발생하게 된다.&lt;/li&gt;
&lt;li&gt;프로세스는 각각의 독립된 메모리 영역을 할당받았기 때문에 프로세스 사이에서 공유하는 메모리가 없어, Context Switching가 발생하면 캐쉬에 있는 모든 데이터를 모두 리셋하고 다시 캐쉬 정보를 불러와야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;프로세스 사이의 어렵고 복잡한 통신 기법(IPC)
&lt;ul&gt;
&lt;li&gt;프로세스는 각각의 독립된 메모리 영역을 할당받았기 때문에 하나의 프로그램에 속하는 프로세스들 사이의 변수를 공유할 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;참고 Context Switching란?
&lt;ul&gt;
&lt;li&gt;CPU에서 여러 프로세스를 돌아가면서 작업을 처리하는 데 이 과정을 Context Switching라 한다.&lt;/li&gt;
&lt;li&gt;구체적으로, 동작 중인 프로세스가 대기를 하면서 해당 프로세스의 상태(Context)를 보관하고, 대기하고 있던 다음 순서의 프로세스가 동작하면서 이전에 보관했던 프로세스의 상태를 복구하는 작업을 말한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;멀티 스레드
&lt;ul&gt;
&lt;li&gt;멀티 스레딩이란
&lt;ul&gt;
&lt;li&gt;하나의 응용프로그램을 여러 개의 스레드로 구성하고 각 스레드로 하여금 하나의 작업을 처리하도록 하는 것이다.&lt;/li&gt;
&lt;li&gt;윈도우, 리눅스 등 많은 운영체제들이 멀티 프로세싱을 지원하고 있지만 멀티 스레딩을 기본으로 하고 있다.&lt;/li&gt;
&lt;li&gt;웹 서버는 대표적인 멀티 스레드 응용 프로그램이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;시스템 자원 소모 감소 (자원의 효율성 증대)
&lt;ul&gt;
&lt;li&gt;프로세스를 생성하여 자원을 할당하는 시스템 콜이 줄어들어 자원을 효율적으로 관리할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;시스템 처리량 증가 (처리 비용 감소)
&lt;ul&gt;
&lt;li&gt;스레드 간 데이터를 주고 받는 것이 간단해지고 시스템 자원 소모가 줄어들게 된다.&lt;/li&gt;
&lt;li&gt;스레드 사이의 작업량이 작아 Context Switching이 빠르다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;간단한 통신 방법으로 인한 프로그램 응답 시간 단축
&lt;ul&gt;
&lt;li&gt;스레드는 프로세스 내의 Stack 영역을 제외한 모든 메모리를 공유하기 때문에 통신의 부담이 적다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;주의 깊은 설계가 필요하다.&lt;/li&gt;
&lt;li&gt;디버깅이 까다롭다.&lt;/li&gt;
&lt;li&gt;단일 프로세스 시스템의 경우 효과를 기대하기 어렵다.&lt;/li&gt;
&lt;li&gt;다른 프로세스에서 스레드를 제어할 수 없다. (즉, 프로세스 밖에서 스레드 각각을 제어할 수 없다.)&lt;/li&gt;
&lt;li&gt;멀티 스레드의 경우 자원 공유의 문제가 발생한다. (동기화 문제)&lt;/li&gt;
&lt;li&gt;하나의 스레드에 문제가 발생하면 전체 프로세스가 영향을 받는다.&lt;/li&gt;
&lt;li&gt;멀티 프로세스 대신 멀티 스레드를 사용하는 이유?&lt;/li&gt;
&lt;li&gt;멀티 프로세스 대신 멀티 스레드를 사용하는 것의 의미?&lt;/li&gt;
&lt;li&gt;쉽게 설명하면, 프로그램을 여러 개 키는 것보다 하나의 프로그램 안에서 여러 작업을 해결하는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="멀티-프로세스-대신-멀티-스레드를-사용하는-이유"&gt;
 멀티 프로세스 대신 멀티 스레드를 사용하는 이유?
 &lt;a class="heading-anchor" href="#%eb%a9%80%ed%8b%b0-%ed%94%84%eb%a1%9c%ec%84%b8%ec%8a%a4-%eb%8c%80%ec%8b%a0-%eb%a9%80%ed%8b%b0-%ec%8a%a4%eb%a0%88%eb%93%9c%eb%a5%bc-%ec%82%ac%ec%9a%a9%ed%95%98%eb%8a%94-%ec%9d%b4%ec%9c%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;멀티 프로세스 대신 멀티 스레드를 사용하는 것의 의미?
&lt;ul&gt;
&lt;li&gt;쉽게 설명하면, 프로그램을 여러 개 키는 것보다 하나의 프로그램 안에서 여러 작업을 해결하는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;여러 프로세스(멀티 프로세스)로 할 수 있는 작업들을 하나의 프로세스에서 여러 스레드로 나눠가면서 하는 이유?
&lt;ul&gt;
&lt;li&gt;자원의 효율성 증대
&lt;ul&gt;
&lt;li&gt;멀티 프로세스로 실행되는 작업을 멀티 스레드로 실행할 경우, 프로세스를 생성하여 자원을 할당하는 시스템 콜이 줄어들어 자원을 효율적으로 관리할 수 있다.&lt;/li&gt;
&lt;li&gt;–&amp;gt; 프로세스 간의 Context Switching시 단순히 CPU 레지스터 교체 뿐만 아니라 RAM과 CPU 사이의 캐쉬 메모리에 대한 데이터까지 초기화되므로 오버헤드가 크기 때문&lt;/li&gt;
&lt;li&gt;스레드는 프로세스 내의 메모리를 공유하기 때문에 독립적인 프로세스와 달리 스레드 간 데이터를 주고 받는 것이 간단해지고 시스템 자원 소모가 줄어들게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;처리 비용 감소 및 응답 시간 단축
&lt;ul&gt;
&lt;li&gt;또한 프로세스 간의 통신(IPC)보다 스레드 간의 통신의 비용이 적으므로 작업들 간의 통신의 부담이 줄어든다.&lt;/li&gt;
&lt;li&gt;–&amp;gt; 스레드는 Stack 영역을 제외한 모든 메모리를 공유하기 때문&lt;/li&gt;
&lt;li&gt;프로세스 간의 전환 속도보다 스레드 간의 전환 속도가 빠르다.&lt;/li&gt;
&lt;li&gt;–&amp;gt; Context Switching시 스레드는 Stack 영역만 처리하기 때문&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="메모리-영역"&gt;
 메모리 영역
 &lt;a class="heading-anchor" href="#%eb%a9%94%eb%aa%a8%eb%a6%ac-%ec%98%81%ec%97%ad" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;메서드 영역 : static 변수, 전역변수, 코드에서 사용되는 Class 정보 등이 올라간다. 코드에서 사용되는 Class들을 로더로 읽고 클래스별로 런타임 필드데이터, 메서드 데이터 등을 분류해 저장.&lt;/li&gt;
&lt;li&gt;스택(Stack) : 지역변수, 함수(메서드) 등이 할당되는 LIFO(Last In First Out) 방식의 메모리&lt;/li&gt;
&lt;li&gt;힙(Heap) : new 연산자를 통한 동적할당된 객체들이 저장되며, 가비지 컬렉션에 의해 메모리가 관리되어 진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="메모리-구조"&gt;
 메모리 구조
 &lt;a class="heading-anchor" href="#%eb%a9%94%eb%aa%a8%eb%a6%ac-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;코드(Code) 영역 : 실행할 프로그램의 코드가 저장되는 영역으로 텍스트(Code) 영역이라고도 부름, CPU는 코드 영역에 저장된 명령어를 하나씩 가져가서 처리하게 됨.&lt;/li&gt;
&lt;li&gt;데이터(Data) 영역 : 전역 변수, 정적(Static) 변수가 저장되는 영역, 데이터 영역은 프로그램의 시작과 함께 할당되며, 프로그램이 종료되면 소멸함.&lt;/li&gt;
&lt;li&gt;힙 영역 : 사용자의 의해 메모리 공간이 동적으로 할당되고 해제됨, 메모리의 낮은 주소에서 높은 주소의 방향으로 할당됨.&lt;/li&gt;
&lt;li&gt;스택(Stack) 영역 : 지역 변수, 매개 변수가 저장되는 영역, 스택 영역은 함수의 호출과 함께 할당되며, 함수의 호출이 완료되면 소멸함.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="접근제한자public--protected--default--private"&gt;
 접근제한자(public &amp;gt; protected &amp;gt; default &amp;gt; private)
 &lt;a class="heading-anchor" href="#%ec%a0%91%ea%b7%bc%ec%a0%9c%ed%95%9c%ec%9e%90public--protected--default--private" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;public : 접근 제한이 없다.(같은 프로젝트 내에 어디서든 사용가능)&lt;/li&gt;
&lt;li&gt;protected : 같은 패키지 내. 다른 패키지에서 상속받아 자식클래스에서 접근 가능.&lt;/li&gt;
&lt;li&gt;default : 같은 패키지 내에서만 접근 가능.&lt;/li&gt;
&lt;li&gt;private : 같은 클래스 내에서만 접근 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="restful-api"&gt;
 RestFul API
 &lt;a class="heading-anchor" href="#restful-api" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;해당 UR만 보더라도 바로 어떤 작업을 하는지를 알 수 있도록 하나의 데이터는 하나의 URL을 갖도록 작업하는 방식.&lt;/li&gt;
&lt;li&gt;규칙
&lt;ul&gt;
&lt;li&gt;자원&lt;/li&gt;
&lt;li&gt;메소드만으로 표현&lt;/li&gt;
&lt;li&gt;동사 말고 명사만&lt;/li&gt;
&lt;li&gt;확장자는 표시하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Get, Put, Post, Delete&lt;/li&gt;
&lt;li&gt;웹에 존재하는 모든 자원(이미지, 동영상, DB자원)에 고유한 URI를 부여해 활용. 자원을 정의하고 자원에 대한 주소를 지정하는 방법론을 의미. 다양한 Device를 대응하기 위해&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="iaas"&gt;
 IaaS
 &lt;a class="heading-anchor" href="#iaas" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;기업(아마존이나 마소)이 준비해놓은 환경에서 사용자가 선택.&lt;/li&gt;
&lt;li&gt;AWS, EC2, Azure.&lt;/li&gt;
&lt;li&gt;고객은 OS와 어플리케이션을 직접 관리.&lt;/li&gt;
&lt;li&gt;관리 측면에서 개발자와 인프라 관리자의 역할 분담.&lt;/li&gt;
&lt;li&gt;장점 : 고객은 가상 서버 하위의 레벨에 대해서는 고려할 필요가 없다는 점.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="paas"&gt;
 PaaS
 &lt;a class="heading-anchor" href="#paas" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;운영팀이 인프라를 모니터링할 필요가 없음.&lt;/li&gt;
&lt;li&gt;사용자는 OS, Server 하드웨어, 네트워크 등등을 고려할 필요가 없음.&lt;/li&gt;
&lt;li&gt;사용자는 어플리케이션 자체에만 집중할 수 있음.&lt;/li&gt;
&lt;li&gt;우리는 소스코드만 적어서 빌드하는 것이고, 컴파일은 클라우드에서 하며 결과만 가져오는 것.&lt;/li&gt;
&lt;li&gt;장점 : PaaS의 경우 이미 설치된 미들웨어 위에 코드만 돌리면 되기 때문에 아무래도 관리가 매우 편함.&lt;/li&gt;
&lt;li&gt;단점 : 기본적으로 어플리케이션과 플랫폼이 함께 제공됨. 어플리케이션이 플랫폼에 종속되어 개발되기 때문에 다른 플랫폼으로의 이동이 어려울 수도 있음.&lt;/li&gt;
&lt;li&gt;ex) Heroku, Google App Engine, IBM Bluemix&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="saas"&gt;
 SaaS
 &lt;a class="heading-anchor" href="#saas" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;모든 것을 기업(클라우드)에서 제공함으로 사용자는 별도의 설치나 부담이 필요없이 SW을 사용.&lt;/li&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;Public Cloud에 있는 SW를 웹브라우저로 불러와 언제 어디서나 사용.&lt;/li&gt;
&lt;li&gt;사용자는 웹만 접속하면 되기 때문에 사용하기 매우 쉽고, 최신 SW업데이트를 빠르게 제공받을 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;SaaS의 특성상 반드시 인터넷에 접속할 수 있어야만 사용, 외부의 데이터 노출에 대한 위험.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ex) 웹메일, 구글 클라우드, 드롭박스 등&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="serverless-아키텍처"&gt;
 Serverless 아키텍처
 &lt;a class="heading-anchor" href="#serverless-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="baas--firebase"&gt;
 BaaS : Firebase
 &lt;a class="heading-anchor" href="#baas--firebase" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;필요한 다양한 기능들(데이터베이스, SNS연동, 파일시스템 등)을 쉽고 빠르게 구현할 수 있게 해주고, 서버도 알아서 확장.&lt;/li&gt;
&lt;li&gt;백엔드 로직들이 클라이언트 쪽에서 구현해야 함.&lt;/li&gt;
&lt;li&gt;복잡한 쿼리가 불가능함.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="faas--aws-lambda"&gt;
 FaaS : AWS Lambda
 &lt;a class="heading-anchor" href="#faas--aws-lambda" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;프로젝트를 여러개의 함수로 쪼개서, 매우 거대하고 분산된 컴퓨팅 자원에 우리가 준비해둔 함수를 등록하고, 이 함수들이 실행되는 횟수 만큼 비용을 내는 방식.&lt;/li&gt;
&lt;li&gt;어플리케이션이 아닌 함수를 배포하며, 계속 실행되고 있는 것이 아닌, 특정 이벤트가 발생했을 때 실행되며, 실행이 되었다가 작업을 마치며 종료.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="serverless의-장점"&gt;
 Serverless의 장점
 &lt;a class="heading-anchor" href="#serverless%ec%9d%98-%ec%9e%a5%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;서버 스케일링이 필요없다.
&lt;ul&gt;
&lt;li&gt;요즘 서버를 직접 운영하는 경우는 잘 없고 대부분 클라우드 서비스를 이용한다. 서버가 죽는 대부분의 경우는 서버가 감당가 능한 통신 대역폭, 메모리 용량, 컴퓨팅 능력을 넘어서는 요청이 들어오는 경우이다. 대부분의 경우는 그렇게 요청이 많이 들어오는 것에 대해서 어느 정도 알 수 있으므로, 미리 서버를 많이 늘려놓으면 된다. 그리고 요즘은 클라우드 서비스 상에 컨테이너를 이용해서 스케일링해주는 서비스 를 대부분 제공해주므로, 오토 스케일링을 설정해 놓으면 해결된다. 하지만 컨테이너에 서버 이미지를 복사해서 가동하는데 대략 15분의 시간이 걸린다고 가정했을 때, 15분동안 기존에 실행하고 있던 서버들 이 죽지않고 요청들을 잘 처리해 준다면 문제가 되지 않지만 그러지 못할 경우에는 바로 장애가 발생하는거다. 심지어 ELB에 같이 물렸을 때에 AWS EC2가 이미 전멸해 있고 트래픽은 계속 몰리는 상태에서 AutoScaling으로 삐용하고 올라와도 트래픽 몰매맞고 또 뻗어버린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;비용
&lt;ul&gt;
&lt;li&gt;싸다. 다른 말이 더 필요한가 ? AWS EC2 서버로 운영하는것 보다 Lambda + API Gateway를 이용해서 API를 서비스 해보니 훨씬 더 싸다. EC2의 경우에는 운영중인 서버수 x 서버 인스턴스의 비용 x 서버가 운영중인 기간 (1시간 단위)로 과금이 이루어 진다. Lambda의 경우는 코드 가 수행된 시간을 100ms 단위로 올림하여 과금한다. API Gateway의 경우 100만 요청 당 3.5 USD가 과금된다. 이렇게 봐서는 과연 더 싼지 바로 판단이 안되겠지만, 실제로 운영해보니 훨씬 더 싸다. 비교도 안되게 싸다. 일단 이 두가지가 직접 겪었던 큰 이유다. 이것 말고도 여러가지 발표자료들을 찾아보면 다른 장점들이 많다. 하지만 그건 옵션 사항인듯 하다.&lt;/li&gt;
&lt;li&gt;비용: 특정 작업을 하기 위하여 서버를 준비하고 하루종일 켜놓는것이 아니라, 필요할때만 함수가 호출되어 처리되며 함수가 호출된 만큼만 비용이 드므로, 비용이 많이 절약됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;인프라 관리: 네트워크, 장비 이런것들에 대한 구성 작업을 신경 쓸 필요 없습니다.&lt;/li&gt;
&lt;li&gt;인프라 보안: 리눅스 업데이트, 최근 발생한 Intel Meltdown 취약점 보안패치, 이런것들 또한 신경 쓸 필요 없습니다.&lt;/li&gt;
&lt;li&gt;확장성: FaaS 는 확장성 면에서 매우 뛰어납니다. 일반적으로, FaaS 를 사용하지 않는다면, 다양한 트래픽에 유연한 대응을 하기 위하여 우리는 AWS 의 Auto Scaling 같은 기술을 사용합니다. 이를 통하여 CPU 사용량, 네트워크 처리량에 따라 서버의 갯수를 늘리는 방식으로 처리를 분산시키는데요, FaaS 를 사용하게 되면 이렇게 특정 조건에 따라 자동으로 확장되는 것이 아닙니다. 그냥, 확장됩니다. 함수가 1초에 1개가 호출되면 1개가 호출되는것이고, 100,000,00 개가 호출되면 100,000,00 개가 호출되는것입니다. 그리고 호출된 횟수 만큼 돈을 내는거죠.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="serverless의-단점"&gt;
 Serverless의 단점
 &lt;a class="heading-anchor" href="#serverless%ec%9d%98-%eb%8b%a8%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;제한: 모든 코드를 함수로 쪼개서 작업하다보니, 함수에서 사용 할 수 있는 자원에 제한이 있습니다. 하나의 함수가 한번 호출 될 때, AWS 에서는 최대 1500MB 의 메모리까지 사용 가능하며, 처리시간은 최대 300 초 까지 사용 가능합니다. 때문에, 웹소켓 같이 계속 켜놔야 하는것은 사용하지 못합니다. 그 대신에, AWS IoT, Pusher 등의 서비스를 사용하면 됩니다.&lt;/li&gt;
&lt;li&gt;FaaS 제공사에 강한 의존: AWS, Azure, Google 등의 FaaS 제공사에 강한 의존을 하게 됩니다. 즉, 갑자기 이 회사들이 망해버리면…? 정말 골치 아프겠죠. 물론 가능성은 매우 희박합니다.
로컬 데이터 사용 불가능: 함수들은 무상태적(stateless)입니다. 때문에, 데이터를 로컬 스토리지에서 읽고 쓸 수 없습니다. 그 대신에, AWS 라면 S3, Azure 라면 Storage 를 이용 할 수 있습니다.&lt;/li&gt;
&lt;li&gt;비교적 신기술: FaaS 는 비교적 새로운 기술 입니다. 물론 AWS 에서 Lambda 는 2014년에 등장하긴 했지만요, 주관적으로 보기엔, 2016년쯤 사용률이 올라가기 시작했으며, 이제 기업에서 사용한 사례들도 여럿 등장하며 자리를 잡아가고 있습니다. 2018년, 아직까지는, 해외에서는 관련 자료들을 볼 수 있는 반면, 국내에서는 관련 자료를 찾아보기가 힘듭니다. 아마 2020년 쯤에는 조금 더 국내에서도 관련 자료를 많이 찾아 볼 수 있을 것이라 예상합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="폭포수"&gt;
 폭포수?
 &lt;a class="heading-anchor" href="#%ed%8f%ad%ed%8f%ac%ec%88%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;한 번 떨어지면 거슬로 올라갈 수 없는 폭포수와 같이 소프트웨어 개발도 각 단계를 확실히 매듭짓고, 다음 단계로 넘어간다는 의미.&lt;/li&gt;
&lt;li&gt;각 단계가 명확하여 관리가 쉬우나, 폭포수 모델을 따르기 위해서는 완전히 순차적으로 한 단계, 한 단계를 진행해야 함.&lt;/li&gt;
&lt;li&gt;즉, 폭포수 모델은 전 단계가 수행되어 완료되기 전에는 다음 단계로 진행할 수 없도록 제한하는 것이 가장 큰 특징.&lt;/li&gt;
&lt;li&gt;그러므로 요구 분석에 상당한 시간이 소요되며, 일단 분석이 끝나면 수정이 어렵다는 단점. 또 개발 단계마다 피드백이 발생하므로 순차적인 흐름을 따라가기 어려우며, 규모가 크고 복잡한 시스템에는 적합하지 않다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="애자일"&gt;
 애자일?
 &lt;a class="heading-anchor" href="#%ec%95%a0%ec%9e%90%ec%9d%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;폭포수 모델을 보완하여 나온 것이 애자일 모델.&lt;/li&gt;
&lt;li&gt;일정한 주기를 가지고 끊임 없이 프로토타입을 만들어내며 그 때 그 때 필요한 요구를 더하고 수정하여 하나의 커다란 소프트웨어를 개발해 나가는 방법.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="스크럼"&gt;
 스크럼?
 &lt;a class="heading-anchor" href="#%ec%8a%a4%ed%81%ac%eb%9f%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;작은 단위의 개발 업무를 단기간 내에 전력 질주하여 개발한다는 뜻. 애자일 개발 방법론 중 하나.
&lt;ul&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;반복주기(스프린트)마다 생산되는 실행 가능한 제품을 통해 사용자와 충분히 의견을 나눌 수 있다.&lt;/li&gt;
&lt;li&gt;일일회의를 함으로써 팀원들 간에 신속한 협조와 조율이 가능하다.&lt;/li&gt;
&lt;li&gt;일일회의 시 직접 자신의 일정을 발표함으로써 업무에 집중할 수 있는 환경이 조성된다.&lt;/li&gt;
&lt;li&gt;다른 개발 방법론들에 비해 단순하고 실천지향적이다.&lt;/li&gt;
&lt;li&gt;스크럼 마스터는 개발 팀원들이 목표달성에 집중할 수 있도록 팀의 문제를 해결한다.&lt;/li&gt;
&lt;li&gt;프로젝트의 진행 현황을 볼 수 있어, 목표에 맞게 변화를 시도할 수 있으며, 신속하게 목표와 결과 추정이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;추가 작업 시간 필요 : 반복주기(스프린트)가 끝날 때 마다 실행가능하거나 테스트할 수 있는 제품을 만들어야 한다. 이 작업이 많아지면, 그만큼 시간이 더 필요하다.&lt;/li&gt;
&lt;li&gt;투입 공수 불측정에 따른 효율성 평가 불가 : 투입 공수를 측정하지 않기 때문에 얼마나 효율적으로 수행되었는지는 알기 어렵다.&lt;/li&gt;
&lt;li&gt;프로세스 품질 평가 불가 : 스크럼은 프로젝트 관리에 무게 중심을 많이 둔 방법. 따라서 스프린트 수행 후 검토 회의를 하지만 프로세스 품질을 평가하지 않기 때문에 품질 관련 활동이 미약하고 따라서 품질의 정도를 알 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="데브옵스devops의-장단점"&gt;
 데브옵스(DevOps)의 장단점
 &lt;a class="heading-anchor" href="#%eb%8d%b0%eb%b8%8c%ec%98%b5%ec%8a%a4devops%ec%9d%98-%ec%9e%a5%eb%8b%a8%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;개발(Development)과 운영(Operations)의 합성어로 시스템 개발과 운영을 병행 및 협업하는 방식 개발자는 개발이 완료된 시스템을 운영팀에게 이관하고 운영팀은 개발된 시스템을 배포/ 관리 운영을 한다는 것을 말함. 서로 주어진 업무로 전문적인 자기 분야에 집중할 수 있어 높은 퀄리티와 책임감으로 위험 감소가 보장된다는 장점이 있지만, 협업을 위해서 개발자는 운영자를, 운영자는 개발자를 생각하는 오픈 마인드를 가지고 커뮤니케이션이 되어야 함.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;시스템 발생 장애
시스템 운영 시 장애가 발생되는 것은 고질적인 문제라고 볼 수 있는데요. 대부분 이런 상황에 부딪힐 때 근본적인 원인을 민첩하게 해결하지 못하고 서로 책임 전가하느라 클라이언트 요구 사항의 반영이 늦어진다는 것&lt;/li&gt;
&lt;li&gt;추가되는 이슈와 요청 사항 거절
운영팀은 서비스 운영에도 업무가 포함되어 있기 때문에 다양한 VOC(고객의 소리-Voice Of Customer)의 이슈 및 개선 사항을 취합하게 되는데요. 이 부분을 개발팀에게 넘겼을 때 운영의 업무를 이해하지 못하고 추가적인 업무로 인식하여 쉽게 받아들이지 못한다는 것&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;노옵스(NoOps)란 단어 그대로 운영자가 없다는 뜻.
&lt;ul&gt;
&lt;li&gt;개발자는 발전된 인터넷으로 지식, 각종 오픈 소스, 클라우드를 통해 시스템 운영자 없이도 네트워크 및 서버 등 다양한 설정을 습득하여 직접 처리할 수 있는 환경이 되면서 직접 개발한 시스템의 방향 및 범위까지 파악된 상태로 장애 발생 또는 요구사항의 대응과 처리 속도가 빠르고 조금 더 효율적이라는 것.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="마이크로-아키텍처와-모놀리스-아키텍처-장단점과-설명"&gt;
 마이크로 아키텍처와 모놀리스 아키텍처 장단점과 설명
 &lt;a class="heading-anchor" href="#%eb%a7%88%ec%9d%b4%ed%81%ac%eb%a1%9c-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98%ec%99%80-%eb%aa%a8%eb%86%80%eb%a6%ac%ec%8a%a4-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98-%ec%9e%a5%eb%8b%a8%ec%a0%90%ea%b3%bc-%ec%84%a4%eb%aa%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;모노리틱 아키텍쳐(Monolithic Architecture)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;마이크로 서비스 아키텍쳐를 이해하려면 먼저 모노리틱 아키텍쳐 스타일에 대해서 이해해야 한다. 모노리틱 아키텍쳐 스타일은 기존의 전통적인 웹 시스템 개발 스타일로, 하나의 애플리케이션 내에 모든 로직들이 모두 들어 가 있는 “통짜 구조” 이다.&lt;/li&gt;
&lt;li&gt;예를 들어, 온라인 쇼핑몰 애플리케이션이 있을때, 톰캣 서버에서 도는 WAR 파일(웹 애플리케이션 패키징 파일)내에, 사용자 관리,상품,주문 관리 모든 컴포넌트들이 들어 있고 이를 처리하는 UX 로직까지 하나로 포장되서 들어가 있는 구조이다. 각 컴포넌트들은 상호 호출을 함수를 이용한 call-by-reference 구조를 취한다. 전체 애플리케이션을 하나로 처리하기 때문에, 개발툴 등에서 하나의 애플리케이션만 개발하면 되고, 배포 역시 간편하며 테스트도 하나의 애플리케이션만 수행하면 되기 때문에 편리하다.&lt;/li&gt;
&lt;li&gt;문제점
&lt;ul&gt;
&lt;li&gt;그러나 이러한 모노리틱 아키텍쳐 시스템은 대형 시스템 개발시 몇가지 문제점을 갖는다. 모노리틱 구조의 경우 작은 크기의 애플리케이션에서는 용이 하지만, 규모가 큰 애플리케이션에서는 불리한 점이 많다. 크기가 크기 때문에, 빌드 및 배포 시간, 서버의 기동 시간이 오래 걸리며 (서버 기동에만 2시간까지 걸리는 사례도 경험해봤음) 프로젝트를 진행하는 관점에서도, 한두사람의 실수는 전체 시스템의 빌드 실패를 유발하기 때문에, 프로젝트가 커질 수 록, 여러 사람들이 협업 개발하기가 쉽지 않다. 또한 시스템 컴포넌트들이 서로 로컬 콜 (call-by-reference)기반으로 타이트하게 연결되어 있기 때문에, 전체 시스템의 구조를 제대로 파악하지 않고 개발을 진행하면, 특정 컴포넌트나 모듈에서의 성능 문제나 장애가 다른 컴포넌트에까지 영향을 주게 되며, 이런 문제를 예방하기 위해서는 개발자가 대략적인 전체 시스템의 구조 등을 이해 해야 하는데, 시스템의 구조가 커질 수 록, 개인이 전체 시스템의 구조와 특성을 이해하는 것은 어려워진다. 특정 컴포넌트를 수정하고자 했을때, 컴포넌트 재 배포시 수정된 컴포넌트만 재 배포 하는 것이 아니라 전체 애플리케이션을 재 컴파일 하여 전체를 다시 통으로 재배포 해야하기 때문에 잦은 배포가 있는 시스템의 경우 불리하며, 컴포넌트 별로, 기능/비기능적 특성에 맞춰서 다른 기술을 도입하고자 할때 유연하지 않다. 예를 들어서, 전체 애플리케이션을 자바로 개발했다고 했을 때, 파일 업로드/다운 로드와 같이 IO 작업이 많은 컴포넌트의 경우 node.js를 사용하는 것이 좋을 수 있으나, 애플리케이션이 자바로 개발되었기 때문에 다른 기술을 집어 넣기가 매우 어렵다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;※ 모노리틱 아키텍쳐가 꼭 나쁘다는 것이 아니다. 규모가 작은 애플리케이션에서는 배포가 용이하고, 규모가 크더라도, call-by-reference call에 의해서 컴포넌트간 호출시 성능에 제약이 덜하며, 운영 관리가 용이하다. 또한 하나의 구조로 되어 있기 때문에, 트렌젝션 관리등이 용이하다는 장점이 있다. 즉 마이크로 서비스 아키텍쳐가 모든 부분에 통용되는 정답은 아니며, 상황과 필요에 따라서 마이크로 서비스 아키텍쳐나 모노리틱 아키텍쳐를 적절하게 선별 선택 또는 변형화 해서 사용할 필요가 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;마이크로 서비스 아키텍쳐&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;마이크로 서비스 아키텍쳐는 대용량 웹서비스가 많아짐에 따라 정의된 아키텍쳐인데, 그 근간은 SOA (Service Oriented Architecture : 서비스 지향 아키텍쳐)에 두고 있다. SOA는 엔터프라이즈 시스템을 중심으로 고안된 아키텍쳐라면, 마이크로 서비스 아키텍쳐는 SOA 사상에 근간을 두고, 대용량 웹서비스 개발에 맞는 구조로 사상이 경량화 되고, 대규모 개발팀의 조직 구조에 맞도록 변형된 아키텍쳐이다.&lt;/li&gt;
&lt;li&gt;장점 1
&lt;ul&gt;
&lt;li&gt;단일체 소프트웨어에서는 코드 저장소로써 개발자는 오직 하나의 언어(예를들면 자바)로 개발합니다. 하지만 마이크로서비스에서는 각 서비스는 독립적이고 새로운 프로젝트이며 요구사항에 맞는 어떠한 언어든지 사용해서 개발될 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;장점 2
&lt;ul&gt;
&lt;li&gt;개발자는 오직 특정 서비스만 집중하기 때문에 코드 저장소는 매우 작을 것이고 개발자는 코드를 잘 알고 있을 것입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;장점 3
&lt;ul&gt;
&lt;li&gt;서비스가 다른 서비스와 통신할 필요가 있을때 API를 통해(구체적으로 REST 서비스에 의해) 서비스들은 통신할 수 있습니다. REST 서비스는 커뮤니키에션을 위한 중개자이기 때문에 매우 작은 변환만 있습니다. SOA와는 다르게 마이크로 서비스 메시지 버스는 아주 많은 변환, 분류, 라우팅을 하는 ESB보다 훨씬 더 얇습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;장점 4
&lt;ul&gt;
&lt;li&gt;중앙화된 데이터베이스가 없습니다. 각 모듈은 각자의 데이터베이스를 가지고 있기 때문에 데이터는 분산 되어있습니다. 개발자는 모듈에 따라 NoSQL 또는 관계형 데이터베이스를 사용할 수 있다는 사실은 전에 언급한 폴리글랏 퍼시스턴스를 데뷔시킵니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;많은 사람들이 SOA와 마이크로서비스가 같은 것이라고 생각합니다. 정의에 따르면 같아 보이지만 SOA는 데이터를 관리하고 분류하는 등 많은 책임을 가진 ESB를 통해 서로 다른 시스템간에 통신을 위해 사용되었습니다. 하지만 마이크로서비스는 입력을 한 서비스에서 다른 서비스로 전송만하는 단순 메시지 버스(dumb message bus)를 사용하지만 메시지를 받는 엔드포인트(endpoint)는 전에 언급한 작업들을 할 수 있을 정도로 똑똑합니다. 마이크로서비스는 우둔한 메시지 버스를 가지고 있지만 똑똑한 엔드포인트가 있습니다. 마이크로 서비스는 REST를 통해 통신을 하며 변환 범위는 API를 통해 호출하는 다른 서비스에 의존하는 오직 하나의 서비스로 아주 작습니다. 하지만 마이크로서비스 또한 단점을 가지고 있습니다. 모든 기능적 특성은 개별 서비스이며 따라서 큰 프로젝트에는 많은 서비스들이 있습니다. 이러한 서비스들을 모니터링하는 것은 오버헤드를 증가시킵니다. 그뿐만이 아니라 서비스가 장애가 나는 경우 장애를 추적하는 것은 힘든 작업이 될 수 있습니다. 서비스는 다른 서비스를 호출하기 때문에 경로를 추적하고 디버깅하는 것 또한 어렵습니다. 각 서비스는 로그를 생성하기 때문에 중앙 로그 모니터링은 없습니다. 이는 매우 고통스러운 부분이며 장애를 대비해 아주 좋은 로그 관리 시스템을 필요로 합니다. 마이크로서비스에서는 각 서비스는 모놀리스 소프트웨어의 프로세스간 통신에 비해 좀 더 큰 오버헤드를 가진 API/원격 호출을 통해 통신합니다. 이러한 모든 결점에도 불구하고 마이크로서비스는 실제로 책임의 분리를 이뤄냅니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;장점1. 각 모듈은 독립적이기 때문에 해당 모듈에 가장 잘 맞는 프로그래밍 언어를 선택할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;장점2. 각 모듈마다 자신의 데이터베이스를 가지고 있기 때문에 제약없이 NoSQL 또는 관계형 데이터베이스를 선택할 수 있다. 따라서 애플리케이션도 전적으로 폴리글랏이다. (여러가지 언어로 개발하는 것, 여러 언어를 자유롭게)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;장점3. 개발자는 마이크로서비스의 개발과 관리함으로 모듈에 대한 방대한 지식을 갖게 된다. 다기능 멤버들은 서비스를 위해 함께 일한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;단점1. 서버는 다른 서버를 호출할 수 있기 때문에 큰 규모의 프로젝트에서는 서비스 호출을 추적하거나 서비스들을 모니터링하기 힘들다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;단점2. 하나의 서비스는 다른 서비스와 REST API를 통해 소통하기 때문에 단일체의 프로세스간 통신에 비해 느리다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;단점3. 디버깅이 힘들다. 서비스 호촐이 다른 서비스를 연속적으로 호출하는 경우에 특히 힘들다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;결론&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;개인적으로는 마이크로 서비스 아키텍처는 이미 기존 서비스 운영을 잘하고 있고, 장애 처리나 모니터링 등을 잘하고 있는 조직이 다음 단계로 진화하는 아키텍처로 선정하는 것이 좋다고 생각합니다. 처음부터 마이크로서비스 아키텍처를 선택하면 운영 및 관리의 헬에서 빠져 나오기 어렵고 그런 오버헤드가 마이크로서비스 아키텍처의 장점을 상쇄시킬 정도로 충분히 클 가능성이 높기 때문입니다. 그리고 초기 단일체 구조 아키텍처로 시작된 작은 서비스가 서비스가 복잡해지고, 조직도 커지고, 팀원의 역량은 충분히 높아졌으면 마이크로서비스 아키텍처로의 진화를 고려하는 것이 좋을 것 같습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="http와-https의-차이점"&gt;
 HTTP와 HTTPS의 차이점?
 &lt;a class="heading-anchor" href="#http%ec%99%80-https%ec%9d%98-%ec%b0%a8%ec%9d%b4%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;HTTP
&lt;ul&gt;
&lt;li&gt;HTTP 는 웹브라우저(Client)와 서버(Server)간의 웹페이지같은 자원을 주고 받을 때 쓰는 통신 규약&lt;/li&gt;
&lt;li&gt;HTTP는 HyperText Transfer Protocol의 약자로 클라이언트(정보 요청자)와 서버 사이에 이루어지는 프로토콜로 주로 HTML문서를 주고 받는데 사용되는 것으로 우리가 검색을 통해서 볼 수 있는 글이나 그림은 등이 http로 규정된 약속에 의해서 보게 된다.&lt;/li&gt;
&lt;li&gt;하지만 HTTP는 클라이언트가 요청한 페이지를 암호화 되지 않은 상태로 주고 받을 수 있어 HTTP로 만든 홈페이지는 클라이언트와 서버의 네트워크에 침입 해 중간에서 정보를 가로챌 수 있는 위험이 상존한다.&lt;/li&gt;
&lt;li&gt;정보를 마음대로 열람, 수정이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HTTPS
&lt;ul&gt;
&lt;li&gt;인터넷 상에서 정보를 암호화하는 SSL(Secure Sockey Layer)프로토콜을 이용하여 웹브라우저(클라이언트)와 서버가 데이터를 주고 받는 통신 규약&lt;/li&gt;
&lt;li&gt;HTTPS의 S는 HTTP에 비해 달랑 한 글자 밖에 차이가 없지만 그 차이는 크다. S는 SSL(Secure Socket Layer)를 의미하는 것으로 주고 받는 정보가 암호화되어 있음을 뜻한다. 때문에 보안이 필요한 은행이나 쇼핑몰, 정부사이트 등에서 HTTPS로 된 홈페이지를 만들어 사용한다.&lt;/li&gt;
&lt;li&gt;HTTPS의 암호화는 클라이언트는 공개키를, 서버는 서버만 알 수 있는 개인키를 이용하는 방식이다. 즉 이용자(클라이언트)가 사이트에 접속하게 되면 서버가 공개키를 이용자에게 보내게 되고 이를 통해서 이용자의 암호화된 정보를 서버는 개인키로 볼 수 있어 네크워크에 침입한 해커는 아무것도 볼 수 없게 된다.&lt;/li&gt;
&lt;li&gt;HTTPS는 이러한 보안상의 장점이 있는 반면 암호화된 정보를 교환하기 때문에 서버가 과부하에 걸리는 경우가 발생하며, 접속이 끊기게 되면 다시 처음부터 시작해야 하는 불편함이 따른다. 이러한 불편함에도 빠른 속도와 다양한 기능을 제공하고 있는 구글은 우리나라 포털사이트와 달리 안전한 https로 만든 홈페이지를 운영하고 있어 비교된다.&lt;/li&gt;
&lt;li&gt;네트워크 상에서 열람, 수정이 불가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;모든 페이지에서 HTTPS를 사용하지 않는 이유
&lt;ul&gt;
&lt;li&gt;SSL 인증서 구입 비용 및 갱신 비용이 발생한다.&lt;/li&gt;
&lt;li&gt;HTTP에 비해 서버에 부하가 더 많이 간다.(HTTP보다 속도가 느리다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="http-버전별로-설명"&gt;
 HTTP 버전별로 설명
 &lt;a class="heading-anchor" href="#http-%eb%b2%84%ec%a0%84%eb%b3%84%eb%a1%9c-%ec%84%a4%eb%aa%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;HTTP/0.9&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;HTTP의 초기 버전에는 버전 정보가 없었고 차후에 구분을 위해 0.9라고 불리게 되었다고 합니다. 아주 단순하게 GET 통신만 가능하고 이후에 버전에 존재하는 HTTP 헤더가 없기 때문에 전송은 HTML 문서만 가능하고 다른 유형은 전송할 수 없습니다. 또한 상태 혹은 오류 코드가 없기 때문에 문제의 상황시 해당 파일 내부에 문제에 대한 설명을 포함하여 보내졌다고 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;HTTP/1.0&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;HTTP/1.0 에서는 상태코드가 응답값 시작 부분에 포함되어 요청에 대한 성공과 실패를 바로 확인할 수 있게 되었습니다. 그리고 위에 언급하였던 HTTP 헤더가 요청과 응답 모두에 추가되어 프로토콜의 확상이 가능해지고 헤더의 ‘Content-Type’의 도움으로 HTML 파일 이외의 다른 문서들도 전송이 가능하게 되었습니다. 또한 메서드 POST, HEAD가 추가되었습니다. (용어의 좁은 의미에서 공식적인 표준은 아니라고 합니다)&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;HTTP/1.1&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;HTTP/1.1은 HTTP의 첫번째 표준 버전입니다. 눈에 잘 보이는 추가점은 메서드에 OPTIONS, PUT, DELETE, TRACE 가 추가되었습니다. 그리고 헤더값도 몇가지 추가되었는데요, 역시 그 중에 조금 낯익은 부분들은 아래와 같습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Via : 중계서버(프록시, 게이트웨이 등)의 지원 프로토이름.버전.호스트명 (ex. via: 1.1 123abc.cloudfront.net (CloudFront))&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Accept : 클라이언트의 사용가능 미디어타입 (ex. application/json, text/plain, &lt;em&gt;/&lt;/em&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그리고 HTTP/1.1 에서는 성능향상을 위해 바뀐 부분이 몇가지 있는데요. 깊이 있게 알고 있진 않지만 대략 이야기를 해보자면, 이전 HTTP/1.0에서의 통신은 예를 들어, 같은 요청하는 서버(클라이언트 서버)와 응답해 줄 서버(API 서버)가 10개의 API 통신을 한다고 하면 연결(커넥션)을 맺고 그다음 리소스를 주고 받고 둘의 연결을 끊고를 10번 반복하게 됩니다. 그런데 HTTP/1.1 에서는 일정시간 클라이언트 서버와 API서버간의 연결 정보를 기억하여 반복적으로 일어나는 통신에 연결의 맺고 끊음을 줄였습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;위의 이야기는 쉽고 간단한 이해를 위한 글로 실제와 차이가 있을 수 있습니다…&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그리고 파이프라이닝이라는 것이 추가되었는데요 이 역시 간단하게 이야기를 하면, 여러개의 요청이 있을때 이전의 요청이 완전히 전송되기 전에 다음의 요청을 전송을 가능하게하여 레이턴시를 낮추었다고 합니다. 쉽게 이야기를 하면… 전송받는데 1초가 걸리는 이미지 파일 10개 요청한다 했을때, 이전에는 1초씩 10번 걸려서 10초가 걸렸는데, 파이프라이닝이라는 것을 통해서 0.8초 쯤 다음 이미지를 요청하도록 해서 총 8초면 된다. 뭐 이런 이야기 같습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="4"&gt;
&lt;li&gt;HTTP/2&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;사실은 앞선 이야기는 이것을 적기 위환 과정이었던 거 같아요. 우선 HTTP/2는 2010년 전반기에 구글이 실험적인 SPDY 프로토콜을 구현해서 클라이언트와 서버 간의 데이터 교환을 대체할 수단을 실증했다고 합니다. 그리고 그것이 HTTP/2의 기초로서 기여했다고 합니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HTTP/2 프로토콜은 HTTP/1.1 과 몇가지 근본적인 차이가 있는데요. 몇가지가 적혀있는데, 가장 핵심적인 부분은 HTTP/1.1이 텍스트 프로토콜이라면 HTTP/2는 이진 프로토콜이라는 점 같습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;하지만, 대략적으로 추측을 해보자면, 텍스트 형태의 리소스는 바이너리 형태에 비해 당연히 효율이 나쁠 것 같아요. 텍스트는 사람이 이해하기 좋을 뿐 컴퓨터는 어짜피 결론적으로 바이너리 형태로 이해할태니까요. 간추리면 브라우저에서 데이터를 바이너리 값으로 변환하여 서버로 보내고 서버는 그 바이너리 값을 해석하여 처리하겠죠? ‘Google ? Web Fundamentals’의 문서를 참고하면 아래와 같이 데이터를 바이너리 프레이밍 값으로 캡슐화하여 주고 받는 것 같습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;# HTTP 1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;POST /upload HTTP/1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;Host: www.example.org
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;Content-Type: application/json
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;COntent-Length: 15
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;...✂...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;{&amp;#34;msg&amp;#34;: &amp;#34;hello&amp;#34;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;# HTTP 2.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;HEADER frame
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;DATA frame&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;그리고 이러한 바이너리 프레이밍 구조가 이후에 나오게 될 HTTP2의 특징이나 장점에 기본이 되는 부분인 것 같습니다. 저의 지식이 얕기 때문에 프로토콜의 원리에 대해 이해하고 이야기하는 것은 어려울 것 같고 간단하게 특징을 적어보려합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;4-1. 요청 및 응답 다중화&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTTP/1.1 에서는 한번에 커넥션을 맺고 데이터를 요청하고 응답받고를 반복하는데요, HTTP/2에서는 스트림(stream)으로 한번의 커넥션으로 동시에 여러개의 데이터를 주고 받을 수 있습니다. 이렇게 하여 HTTP/1.x 에서의 이미지 스프라이트, 도메인 분할 같은 임시방편을 사용하지 않아도 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;4-2. 스트림 우선 순위&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;위와 같이 스트림의 프레임으로 다중화가 가능해짐과 동시에 클라이언트와 서버의 통신 순서를 위해 각 스트림에는 1~256 사이의 정수 가중치가 할당되어 스트림 처리 우선순위를 정합니다.
그런데 이게 우선 순위를 지정하여 이를 처리할 CPU, 메모리 및 기타 리소스의 할당을 제어하는 것일 뿐 특정 순서로 처리되도록 서버에 강요될 수 없다고 합니다.&lt;/li&gt;
&lt;li&gt;HTTP도 TCP 위에서 돌아가는데… 이 부분은 좀 더 공부해야 이해할 수 있을 것 같습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;4-3. 헤더 압축&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTTP/1.x의 경우에는 가령 두개의 동일한 요청을 보낸다고 했을때, 두개의 헤더에 중복값이 존재해도 모두 전송하는데요, HTTP/2에서는 HPACK 압축형식을 사용해서 요청 및 응답 헤더 메타데이터를 압축하는데 이때 이 중복되는 헤더값을 색인값으로 처리해준다고 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="java"&gt;
 JAVA
 &lt;a class="heading-anchor" href="#java" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;JAVA는 네트워크상에서 쓸 수 있도록 미국의 선 마이크로 시스템즈가 개발한 객체 지향 프로그래밍 언어&lt;/li&gt;
&lt;li&gt;Java의 특징
&lt;ul&gt;
&lt;li&gt;자바가상머신(JVM)만 설치하면 컴퓨터의 운영체제의 상관없이 작동한다.(즉, 운영체제에 독립적)&lt;/li&gt;
&lt;li&gt;기본 자료형을 제외한 모든 요소들이 객체로 표현&lt;/li&gt;
&lt;li&gt;객체 지향 개념의 특징인 캡슐화, 상속, 다형성이 잘 적용된 언어&lt;/li&gt;
&lt;li&gt;메모리를 자동으로 관리한다
&lt;ul&gt;
&lt;li&gt;C++이 메모리 관리를 위해 개발자가 직접 코드를 작성해야 하는 반면, 자바는 개발자가 메모리에 직접 접근할 수 없으며 자바가 직접 메모리를 관리한다. 객체를 생성할 때 자동적으로 메모리 영역을 찾아서 할당하고, 사용이 완료되면 Garbage Collector를 실행시켜 자동적으로 사용하지 않는 객체를 제거한다. 따라서 개발자는 메모리 관리의 수고스러움을 덜고, 코딩에 좀 더 집중할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;멀티쓰레드(Multi-thread)를 지원
&lt;ul&gt;
&lt;li&gt;자바는 스레드 생성 및 제어와 관련된 라이브러리 API를 제공하고 있기 때문에 실행되는 운영체제에 상관없이 멀티 스레드를 쉽게 구현할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;동적 로딩(Dynamic Loading)을 지원한다
&lt;ul&gt;
&lt;li&gt;애플리케이션이 실행될 때 모든 객체가 생성되지 않고, 각 객체가 필요한 시점에 클래스를 동적 로딩해서 생성한다. 또한 유지보수 시 해당 클래스만 수정하면 되기 때문에 전체 애플리케이션을 다시 컴파일할 필요가 없다. 따라서 유지보수가 쉽고 빠르다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이식성이 높은 언어이다
&lt;ul&gt;
&lt;li&gt;이식성이란 서로 다른 실행 환경을 가진 시스템 간에 프로그램을 옮겨 실행할 수 있는 것을 말한다. 자바 언어로 개발된 프로그램은 소스 파일을 수정하지 않아도, 자바 실행 환경(JRE)이 설치되어 있는 모든 운영 체제에서 실행 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="java의-jvm이란"&gt;
 JAVA의 JVM이란?
 &lt;a class="heading-anchor" href="#java%ec%9d%98-jvm%ec%9d%b4%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;JVM이란 Java Virtual Machine, 자바 가상 머신의 약자를 따서 줄여 부르는 용어이다. (가상머신이란 프로그램의 실행하기 위해 물리적 머신과 유사한 머신을 소프트웨어로 구현한 것이다.) JVM 역할은 자바 애플리케이션을 클래스 로더를 통해 읽어 들여 자바 API와 함께 실행하는 것이다. 그리고 JVM은 JAVA와 OS사이에서 중개자 역할을 수행하여 JAVA가 OS에 구애받지 않고 재사용을 가능하게 해준다. 그리고 가장 중요한 메모리관리, Garbage Collection을 수행한다. 그리고 JVM은 스택기반의 가상머신이다. ARM 아키텍쳐 같은 하드웨어는 레지스터 기반으로 동작하는데 비해 JVM은 스택기반으로 동작한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="java-프로그램의-실행-과정"&gt;
 Java 프로그램의 실행 과정
 &lt;a class="heading-anchor" href="#java-%ed%94%84%eb%a1%9c%ea%b7%b8%eb%9e%a8%ec%9d%98-%ec%8b%a4%ed%96%89-%ea%b3%bc%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;프로그램이 실행되면 JVM은 OS로부터 프로그램이 필요로 하는 메모리를 할당받는다. JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;Java 컴파일러(javac)가 Java 소스코드(.java)를 읽어들여 Java 바이트코드(.class)로 변환시킨다.&lt;/li&gt;
&lt;li&gt;Class Loader를 통해 .class파일들을 JVM으로 로딩한다.&lt;/li&gt;
&lt;li&gt;로딩된 class파일들은 Execution Engine을 통해 해석된다. -&amp;gt; 클래스 로딩이 끝나면 JVM은 main메소드를 찾아 지역변수, 객체변수, 참조변수를 스택에 쌓는다.&lt;/li&gt;
&lt;li&gt;해석된 바이트코드는 Runtime Data Areas에 배치되어 실질적인 명령어 수행이 이루어지게 된다(CPU).&lt;/li&gt;
&lt;li&gt;위와 같은 과정 속에서 JVM은 필요에 따라 Thread Synchronization과 GC같은 관리작업을 수행한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="jvm-내부-모듈의-역할"&gt;
 JVM 내부 모듈의 역할
 &lt;a class="heading-anchor" href="#jvm-%eb%82%b4%eb%b6%80-%eb%aa%a8%eb%93%88%ec%9d%98-%ec%97%ad%ed%95%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ClassLoader
&lt;ul&gt;
&lt;li&gt;JVM내로 클래스들을 Load하고, Link를 통해 배치하는 작업을 수행하는 모듈로써, 런타임시 동적으로 클래스를 로드한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Excution Engine
&lt;ul&gt;
&lt;li&gt;ClassLoader를 통해 배치된 바이트코드를 명령어 단위로 실행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Garbage Collector
&lt;ul&gt;
&lt;li&gt;메모리 관리 기능을 자동으로 수행한다. 애플리케이션이 생성한 객체의 생존 여부를 판단하여 더 이상 사용되지 않는 객체를 해제한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Runtime Data Areas
&lt;ul&gt;
&lt;li&gt;JVM이 운영체제 위에서 실행되면서 할당받는 메모리 영역이다. ClassLoader에서 준비한 데이터들을 보관하는 저장소&lt;/li&gt;
&lt;li&gt;PC 레지스터: 쓰레드마다 현재 수행중인 JVM 명령의 주소를 갖는다.&lt;/li&gt;
&lt;li&gt;스택 영역: 메소드가 호출될 때 마다 각각의 스택 프레임이 생성되며 메소드안에서 사용되는 local variables를 저장한다.&lt;/li&gt;
&lt;li&gt;메소드 영역: 클래스 정보를 처음 메모리 공간에 올릴 때 초기화되는 대상(바이트코드)을 저장하기 위한 메모리 공간이다. Runtime Constant Pool이라는 영역도 함께 존재하는데, 상수 자료형을 저장하여 참조하고 중복을 막는 역할을 수행한다.&lt;/li&gt;
&lt;li&gt;힙 영역: 객체를 저장하는 가상 메모리 공간이다. new 연산자로 생성된 객체와 배열을 저장한다. 힙영역에 생성되는 객체는 자동 초기화됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="java-제네릭generics"&gt;
 JAVA 제네릭(Generics)
 &lt;a class="heading-anchor" href="#java-%ec%a0%9c%eb%84%a4%eb%a6%adgenerics" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;타입인수를 사용해 일반화된 클래스나 메소드를 정의하는 기법&lt;/li&gt;
&lt;li&gt;메소드의 인자값으로 들어가는 타입만 달라질 뿐 하는 동작이 똑같다면, 여러 타입의 인자가 들어갈 경우에 대해 일일히 명시적으로 인자값을 지정 함수를 오버로딩 하는 방법이 있다. 하지만 제네릭을 이용해 한 번만 구현해놓고 &amp;lt;&amp;gt; 안에 사용 타입을 지정함으로써, 재사용성, 형식 안정성 및 효율성을 달성할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="java-컬렉션collection"&gt;
 JAVA 컬렉션(Collection)
 &lt;a class="heading-anchor" href="#java-%ec%bb%ac%eb%a0%89%ec%85%98collection" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="java-collections-frameworkjcf"&gt;
 Java Collections Framework(JCF)
 &lt;a class="heading-anchor" href="#java-collections-frameworkjcf" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Java에서 컬렉션(Collection)이란 데이터의 집합, 그룹을 의미하며 JCF(Java Collections Framework)는 이러한 데이터, 자료구조인 컬렉션과 이를 구현하는 클래스를 정의하는 인터페이스를 제공한다.&lt;/li&gt;
&lt;li&gt;다음은 JCF의 상속 구조를 나타낸다.
&lt;img src="https://kyungryeol-yoon.github.io/images/java/java-collection-framework-structures.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/li&gt;
&lt;li&gt;Collection 인터페이스는 List, Set, Queue로 크게 3가지 상위 인터페이스로 분류할 수 있다.&lt;/li&gt;
&lt;li&gt;Map의 경우 Collection 인터페이스를 상속 받고 있지 않지만 Collection으로 분류된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Collection 인터페이스의 특징&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;인터페이스&lt;/th&gt;
					&lt;th style="text-align: center"&gt;구현클래스&lt;/th&gt;
					&lt;th style="text-align: right"&gt;특징&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;Set&lt;/td&gt;
					&lt;td style="text-align: center"&gt;HashSet, TreeSet&lt;/td&gt;
					&lt;td style="text-align: right"&gt;순서를 유지하지 않는 데이터의 집합으로 데이터의 중복을 허용하지 않는다.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;List&lt;/td&gt;
					&lt;td style="text-align: center"&gt;LinkedList, Vector, ArrayList&lt;/td&gt;
					&lt;td style="text-align: right"&gt;순서가 있는 데이터의 집합으로 데이터의 중복을 허용한다.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;Queue&lt;/td&gt;
					&lt;td style="text-align: center"&gt;LinkedList, PriorityQueue&lt;/td&gt;
					&lt;td style="text-align: right"&gt;List와 유사&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;Map&lt;/td&gt;
					&lt;td style="text-align: center"&gt;Hashtable, HashMap, TreeMap&lt;/td&gt;
					&lt;td style="text-align: right"&gt;키(Key), 값(Value)의 쌍으로 이루어진 데이터의 집합으로, 순서는 유지되지 않으며 키(Key)의 중복을 허용하지 않으나 값(Value)의 중복은 허용한다.&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ol&gt;
&lt;li&gt;Set 인터페이스&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;순서를 유지하지 않는 데이터의 집합으로 데이터의 중복을 허용하지 않는다.
&lt;ul&gt;
&lt;li&gt;HashSet
&lt;ul&gt;
&lt;li&gt;가장 빠른 임의 접근 속도&lt;/li&gt;
&lt;li&gt;순서를 예측할 수 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TreeSet
&lt;ul&gt;
&lt;li&gt;정렬 방법을 지정할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;List 인터페이스&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;순서가 있는 데이터의 집합으로 데이터의 중복을 허용한다.
&lt;ul&gt;
&lt;li&gt;LinkedList
&lt;ul&gt;
&lt;li&gt;양방향 포인터 구조로 데이터의 삽입, 삭제가 빈번할 경우 데이터의 위치 정보만 수정하면 되기에 유용&lt;/li&gt;
&lt;li&gt;스택, 큐, 양방향 큐 등을 만들기 위한 용도로 쓰임&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Vector
&lt;ul&gt;
&lt;li&gt;과거에 대용량 처리를 위해 사용했으며, 내부에서 자동으로 동기화 처리가 일어나 비교적 성능이 좋지 않고 무거워 잘 쓰이지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ArrayList
&lt;ul&gt;
&lt;li&gt;단방향 포인터 구조로 각 데이터에 대한 인덱스를 가지고 있어 조회 기능에 성능이 뛰어남&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Map 인터페이스&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;키(Key), 값(Value)의 쌍으로 이루어진 데이터의 집합으로, 순서는 유지되지 않으며 키(Key)의 중복을 허용하지 않으나 값(Value)의 중복은 허용한다.
&lt;ul&gt;
&lt;li&gt;Hashtable
&lt;ul&gt;
&lt;li&gt;HashMap보다는 느리지만 동기화 지원&lt;/li&gt;
&lt;li&gt;null 불가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HashMap
&lt;ul&gt;
&lt;li&gt;중복과 순서가 허용되지 않으며 null 값이 올 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TreeMap
&lt;ul&gt;
&lt;li&gt;정렬된 순서대로 키(Key)와 값(Value)을 저장하여 검색이 빠름&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="garbage-collection가비지-컬렉션"&gt;
 Garbage Collection(가비지 컬렉션)
 &lt;a class="heading-anchor" href="#garbage-collection%ea%b0%80%eb%b9%84%ec%a7%80-%ec%bb%ac%eb%a0%89%ec%85%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;시스템에서 더이상 사용하지 않는 동적 할당된 메모리 블럭을 찾아 자동으로 다시 사용 가능한 자원으로 회수하는 것으로 시스템에서 가비지 컬렉션을 수행하는 부분을 가비지 컬렉터라 부른다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="jquery-ajax-json"&gt;
 Jquery, Ajax, Json?
 &lt;a class="heading-anchor" href="#jquery-ajax-json" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;jQuery : javascript 기반으로 만들어진 라이브러리&lt;/li&gt;
&lt;li&gt;JSON : 인터넷에서 자료를 주고받을때 쓰는 문법&lt;/li&gt;
&lt;li&gt;ajax : 비동기로 화면깜박임 없이 데이터를 주고받는 방법&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="primitive-type과-reference-type"&gt;
 Primitive type과 Reference type
 &lt;a class="heading-anchor" href="#primitive-type%ea%b3%bc-reference-type" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Primitive type : 변수에 값 자체를 저장.
&lt;ul&gt;
&lt;li&gt;정수형 : byte, short, int, long&lt;/li&gt;
&lt;li&gt;실수형 : float, double&lt;/li&gt;
&lt;li&gt;문자형 : char&lt;/li&gt;
&lt;li&gt;논리형 : boolean&lt;/li&gt;
&lt;li&gt;Primitive type은 Wrapper Class를 통해 객체로 변형할 수 있다.&lt;/li&gt;
&lt;li&gt;예) int-&amp;gt;Integer, char-&amp;gt;Character(int와 char르 제외한 Primitive type의 다른 자료형들은 맨 앞 알파벳을 대문자로 바꿔주면 된다. float-&amp;gt;Float)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reference type : 메모리상에 객체가 있는 위치를 저장.
&lt;ul&gt;
&lt;li&gt;종류 : Class, Interface, Array 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="wrapper-class"&gt;
 Wrapper Class
 &lt;a class="heading-anchor" href="#wrapper-class" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Primitive type으로 표현할 수 있는 간단한 데이터를 객체로 만들어야 할 경우가 있는 그러한 기능을 지원하는 클래스.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="oop객체지향-프로그래밍"&gt;
 OOP(객체지향 프로그래밍)
 &lt;a class="heading-anchor" href="#oop%ea%b0%9d%ec%b2%b4%ec%a7%80%ed%96%a5-%ed%94%84%eb%a1%9c%ea%b7%b8%eb%9e%98%eb%b0%8d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;OOP란 Object-Oriented Programming의 약어로써 객체지향 프로그래밍을 의미&lt;/li&gt;
&lt;li&gt;데이터를 객체로 취급하여 프로그램에 반영한 것이며, 순차적으로 프로그램이 동작하는 기존의 것들과는 다르게 객체와 객체의 상호작용을 통해 프로그램이 동작하는 것을 말한다.&lt;/li&gt;
&lt;li&gt;OOP 특징
&lt;ul&gt;
&lt;li&gt;객체지향 프로그래밍은 코드의 재사용성이 높다.&lt;/li&gt;
&lt;li&gt;코드의 변경이 용이&lt;/li&gt;
&lt;li&gt;직관적인 코드 분석&lt;/li&gt;
&lt;li&gt;개발속도 향상&lt;/li&gt;
&lt;li&gt;상속을 통한 장점 극대화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="object"&gt;
 Object
 &lt;a class="heading-anchor" href="#object" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Object(객체)는 OOP에 데이터(변수)와 그 데이터에 관련되는 동작(함수). 즉 절차, 방법, 기능을 모두 포함한 개념.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="소켓-통신tcpudp"&gt;
 소켓 통신(TCP/UDP)
 &lt;a class="heading-anchor" href="#%ec%86%8c%ec%bc%93-%ed%86%b5%ec%8b%a0tcpudp" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;TCP(Transmission Control Protocol)
&lt;ul&gt;
&lt;li&gt;연결형 서비스 제공&lt;/li&gt;
&lt;li&gt;높은 신뢰성 보장&lt;/li&gt;
&lt;li&gt;연결의 설정(3-way handshaking)&lt;/li&gt;
&lt;li&gt;연결의 해제(4-way handshaking)&lt;/li&gt;
&lt;li&gt;데이터 흐름 제어, 혼잡 제어&lt;/li&gt;
&lt;li&gt;전이중, 점대점 서비스(양방향 송수신 서비스)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;UDP(User Datagram Protocol)
&lt;ul&gt;
&lt;li&gt;비연결형 서비스 제공&lt;/li&gt;
&lt;li&gt;신뢰성이 낮음&lt;/li&gt;
&lt;li&gt;데이터의 전송 순서가 바뀔 수 있음&lt;/li&gt;
&lt;li&gt;데이터 수신 여부 확인 안함(3-way handshaking과 같은 과정 X)&lt;/li&gt;
&lt;li&gt;TCP보다 전송속도가 빠름&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="웹-서버와-wasweb-application-server의-정의"&gt;
 웹 서버와 WAS(Web Application Server)의 정의
 &lt;a class="heading-anchor" href="#%ec%9b%b9-%ec%84%9c%eb%b2%84%ec%99%80-wasweb-application-server%ec%9d%98-%ec%a0%95%ec%9d%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;웹 서버와 WAS는 비슷한 개념이기 때문에 같이 또는 다르게 사용되는 단어 가운데 하나이다. 인터넷 확산 초기에는 웹 서버라는 개념으로 통칭해서 사용했지만, 시간이 지남에 따라 WAS를 더 많이 사용하고 있다. 인터넷 사용자가 증가함에 따라, 각 웹 사이트는 보다 많은 사용자에게 원활한 서비스를 제공하기 위해 기능적인 layer를 나우게 되었고 여기서 웹 서버와 WAS의 구분점이 생기게 된 것이다.&lt;/li&gt;
&lt;li&gt;기능적으로만 본다면, 거의 대부분의 웹 서버가 웹 애플리케이션을 동작시킬 수 있겠지만 모두 웹 서버 혹은 WAS라고 부르는 것보다는 어떤 기능을 수행하는지에 따라, 즉 기능상의 분류를 통해 구분지어 사용해야 할 것이다.&lt;/li&gt;
&lt;li&gt;WAS와 웹 서버의 차이점 : 동적 컨텐츠 처리를 수행 가능한가 아닌가. WAS는 정적, 동적 처리 둘다 가능하지만 정적 처리를 WAS가 하게 되면 부하가 많이 걸려서 좋지 않다.
&lt;ul&gt;
&lt;li&gt;웹 서버
&lt;ol&gt;
&lt;li&gt;웹브라우저(Web Client)에게 컨텐츠를 제공하는 서버. 즉, 정적인 HTML이나 jpeg, gif 같은 이미지를 HTTP 프로토콜을 통해 웹 브라우저에 제공한다.&lt;/li&gt;
&lt;li&gt;최근에는 웹 서버에서도 내부 애플리케이션을 동작시킬 수 있는 컨테이너를 내장하고 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;WAS
&lt;ol&gt;
&lt;li&gt;서버단에서 애플리케이션을 동작할 수 있도록 지원한다.&lt;/li&gt;
&lt;li&gt;일반적으로 컨테이너라는 용어로 쓰인다.&lt;/li&gt;
&lt;li&gt;초장기에는 CGI, 그 이후에는 Servlet, ASP, JSP, PHP 등의 프로그램으로 사용되고 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="database에서-index란"&gt;
 Database에서 Index란?
 &lt;a class="heading-anchor" href="#database%ec%97%90%ec%84%9c-index%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;인덱스는 데이터베이스 분야에 있어서 테이블에 대한 동작의 속도를 높여주는 자료 구조를 일컫는다. 인덱스는 테이블 내의 1개의 컬럼, 혹은 여러 개의 컬럼을 이용하여 생성될 수 있다. 고속의 검색 동작뿐만 아니라 레코드 접근과 관련 효율적인 순서 매김 동작에 대한 기초를 제공한다. 인덱스를 저장하는 데 필요한 디스크 공간은 보통 테이블을 저장하는 데 필요한 디스크 공간보다 작다. 데이터베이스에서 테이블과 클러스터에 연관되어 독립적인 저장 공간을 보유하고 있는 객체(object)이다. 사용자는 데이터베이스에 저장된 자료를 더욱 빠르게 조회하기 위하여 인덱스를 생성하고 사용한다.&lt;/li&gt;
&lt;li&gt;DB에서 자료를 검색하는 두 가지 방법
&lt;ul&gt;
&lt;li&gt;FTS(Full Table Scan) : 테이블을 처음부터 끝까지 검색하는 방법.&lt;/li&gt;
&lt;li&gt;Index Scan : 인덱스를 검색하여 해당 자료의 테이블을 액세스하는 방법.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="db의-옵티마이저란"&gt;
 DB의 옵티마이저란?
 &lt;a class="heading-anchor" href="#db%ec%9d%98-%ec%98%b5%ed%8b%b0%eb%a7%88%ec%9d%b4%ec%a0%80%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;사용자가 요청한 SQL 을 가장 효율적이고 빠르게 수행할 수 있는 최적의 처리경로를 선택해 주는 DBMS 의 핵심엔진&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="로그를-남기는-이유-로그를-남기지-말아야-할-데이터"&gt;
 로그를 남기는 이유, 로그를 남기지 말아야 할 데이터
 &lt;a class="heading-anchor" href="#%eb%a1%9c%ea%b7%b8%eb%a5%bc-%eb%82%a8%ea%b8%b0%eb%8a%94-%ec%9d%b4%ec%9c%a0-%eb%a1%9c%ea%b7%b8%eb%a5%bc-%eb%82%a8%ea%b8%b0%ec%a7%80-%eb%a7%90%ec%95%84%ec%95%bc-%ed%95%a0-%eb%8d%b0%ec%9d%b4%ed%84%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;로그는 표시다. 로직의 흐름이나, 문제점이나, 오작동여부를 확인하는 데 도움을 주기 때문이다. 로그를 남기는 이유는 로직이 의도된 바로 흐르는지, 내 코드의 문제나 내 코드를 잘못 사용한 코드가 없는지를 감지하기 위해서다.&lt;/li&gt;
&lt;li&gt;로그 처리와 관련해 가장 좋은 모범 사례 중 하나는 운영 모드에서는 불필요한 로그를 꺼두는 것입니다. 디스크 IO는 매우 비싼 작업이기 때문입니다. 불필요한 로그를 켜두는 것은 잦은 디스크 IO를 발생시켜 애플리케이션을 느리게 할 뿐 아니라, 확장성에도 심각한 영향을 미칠 수 있습니다. 로그를 디스크에 남기려면 많은 디스크 공간이 필요하며, 디스크 공간이 고갈되면 애플리케이션도 다운됩니다. 로깅 프레임워크는 어떤 로그를 남기고 어떤 로그를 남기지 말아야 할지 런타임에 제어할 수 있는 옵션을 제공합니다. 대부분의 로깅 프레임워크는 세밀한 수준의 로깅 제어 기능을 제공하며, 로깅 관련 설정을 런타임에 변경할 수 있는 옵션을 제공합니다.&lt;/li&gt;
&lt;li&gt;반대로 로그는 중요한 정보를 담고 있기도 하므로 적절히 분석한다면 높은 가치의 정보를 얻을 수도 있습니다. 그래서 로그 남기는 것을 제한하면 애플리케이션의 동작을 이해하는 데 방해가 되는 것도 사실입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="비동기와-동기-방식의-차이점"&gt;
 비동기와 동기 방식의 차이점?
 &lt;a class="heading-anchor" href="#%eb%b9%84%eb%8f%99%ea%b8%b0%ec%99%80-%eb%8f%99%ea%b8%b0-%eb%b0%a9%ec%8b%9d%ec%9d%98-%ec%b0%a8%ec%9d%b4%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;동기(synchronous : 동시에 일어나는)
&lt;ul&gt;
&lt;li&gt;동기는 말 그대로 동시에 일어난다는 뜻입니다. 요청과 그 결과가 동시에 일어난다는 약속인데요. 바로 요청을 하면 시간이 얼마가 걸리던지 요청한 자리에서 결과가 주어져야 합니다.
&lt;ul&gt;
&lt;li&gt;요청과 결과가 한 자리에서 동시에 일어남&lt;/li&gt;
&lt;li&gt;A노드와 B노드 사이의 작업 처리 단위(transaction)를 동시에 맞추겠다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;비동기(Asynchronous : 동시에 일어나지 않는)
&lt;ul&gt;
&lt;li&gt;비동기는 동시에 일어나지 않는다를 의미합니다. 요청과 결과가 동시에 일어나지 않을거라는 약속입니다.
&lt;ul&gt;
&lt;li&gt;요청한 그 자리에서 결과가 주어지지 않음&lt;/li&gt;
&lt;li&gt;노드 사이의 작업 처리 단위를 동시에 맞추지 않아도 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;동기와 비동기는 상황에 따라서 각각의 장단점이 있습니다.&lt;/li&gt;
&lt;li&gt;동기방식은 설계가 매우 간단하고 직관적이지만 결과가 주어질 때까지 아무것도 못하고 대기해야 하는 단점이 있고, 비동기방식은 동기보다 복잡하지만 결과가 주어지는데 시간이 걸리더라도 그 시간 동안 다른 작업을 할 수 있으므로 자원을 효율적으로 사용할 수 있는 장점이 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="vss-cvs-svn-git"&gt;
 VSS, CVS, SVN, Git
 &lt;a class="heading-anchor" href="#vss-cvs-svn-git" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;구분&lt;/th&gt;
					&lt;th style="text-align: center"&gt;CVS&lt;/th&gt;
					&lt;th style="text-align: right"&gt;SVN&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;커밋단위&lt;/td&gt;
					&lt;td style="text-align: center"&gt;지원&lt;/td&gt;
					&lt;td style="text-align: right"&gt;체인지 셋(Change set)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;원자적 커밋(커밋 실패 시 롤백)&lt;/td&gt;
					&lt;td style="text-align: center"&gt;미지원&lt;/td&gt;
					&lt;td style="text-align: right"&gt;지원&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;처리 속도&lt;/td&gt;
					&lt;td style="text-align: center"&gt;느림&lt;/td&gt;
					&lt;td style="text-align: right"&gt;빠름&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;파일과 Directory의 삭제, 이동, 이름 변경, 복사&lt;/td&gt;
					&lt;td style="text-align: center"&gt;미지원&lt;/td&gt;
					&lt;td style="text-align: right"&gt;지원&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;소스코드외 이진파일(문서, 라이브러리 등) 지원&lt;/td&gt;
					&lt;td style="text-align: center"&gt;미지원&lt;/td&gt;
					&lt;td style="text-align: right"&gt;지원&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;GUI(Graphic User Interface) 지원여부&lt;/td&gt;
					&lt;td style="text-align: center"&gt;지원&lt;/td&gt;
					&lt;td style="text-align: right"&gt;지원&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;웹 인터페이스(Web Interface) 지원여부&lt;/td&gt;
					&lt;td style="text-align: center"&gt;지원&lt;/td&gt;
					&lt;td style="text-align: right"&gt;지원&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ol&gt;
&lt;li&gt;VSS&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;설명 : VSS는 &amp;lsquo;Visual SourceSafe&amp;rsquo;의 약자로써 버전관리 소프트웨어이다. One Tree Software라는 회사에 의해 16비트용 응용프로그램(ver3.1)으로 처음 만들어졌다. 그 시절 Microsoft에도 &amp;lsquo;Delta&amp;rsquo;라는 이름의 버전관리 소프트웨어가 있었으나, 그 기능과 성능이 VSS만 못했으므로 1994년 Microsoft는 One Tree Software를 인수하여 1995년 32비트용 응용프로그램의 첫 버전인 VSS 4.0을 출시한다. 가장 최근 버전으로는 Visual Source Safe 2005가 있다.&lt;/li&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;Microsoft사의 제품이기 때문에 Microsoft의 솔루션들과의 통합이 아주 용이하다.&lt;/li&gt;
&lt;li&gt;Windows기반이기 때문에 설치와 사용이 그다지 어렵지 않다.&lt;/li&gt;
&lt;li&gt;동시 수정이 불가능하여 작업의 충돌이 일어나지 않는다.(단점이기도 함)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;VSS의 직접적인 파일기반 접근 메카니즘은 어떤 클라이언트든 저장소안의 파일을 잠금(Locking)후에 수정하는 것을 허락하기 때문에 만약 파일을 업데이트 하는 도중 클라이언트의 PC에 충돌이 일어나기라도 하면 파일이 손상된 상태로 남겨질 수 있다.(잦은 저장소 손상)&lt;/li&gt;
&lt;li&gt;파일이 누군가에 의해 수정중인(Locking) 경우 파일에 접근하지 못함.(동시 수정 불가능)&lt;/li&gt;
&lt;li&gt;대규모 프로젝트에는 부적합하며, 소규모(5명) 프로젝트인 경우에 적합하다. (대규모 프로젝트에는 Microsoft사의 &amp;lsquo;Team Foundation Server&amp;rsquo; 사용)&lt;/li&gt;
&lt;li&gt;가지치기(Branch) 기능이 빈약하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;CVS&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;설명 : CVS는 &amp;lsquo;Concurrent Versions System&amp;rsquo;의 약자로써 버전관리 소프트웨어이다. 소프트웨어 개발 프로젝트에서 파일 단위의 모든 작업과 모든 변화를 추적하고 여러 개발자(지역적으로 떨어진)가 협력하여 작업할 수 있도록 지원한다. CVS는 GNU 라이선스하에서 배포되며 오픈 소스 프로젝트에서 널리 사용된다. 현재는 설계상 몇가지 크고 작은 문데들로 인해 Sub version(SVN)에게 그 자리를 내어주고 있는 추세이다.&lt;/li&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;CVS는 오랜기간에 걸쳐 많은 사용자들을 확보한 안정되고 검증된 버전관리 소프트웨어이다.&lt;/li&gt;
&lt;li&gt;하나의 파일에 대한 동시작업이 가능하다.&lt;/li&gt;
&lt;li&gt;병합(merge), 가지치기(branch), 태그(tag), 비교(compare) 기능을 지원한다.&lt;/li&gt;
&lt;li&gt;Unix, Linux, Windows 등 대부분의 운영체제를 지원한다.&lt;/li&gt;
&lt;li&gt;파일 전체를 저장하는 것이 아니라 변경사항만을 저장함으로 백업용량을 적게 차지한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;CVS 저장소의 파일들은 이름을 바꿀 수 없다. 제거하고 나서 다시 추가해야 한다.&lt;/li&gt;
&lt;li&gt;CVS 프로토콜은 디렉터리의 이동이나 이름 변경을 허용하지 않는다. 서브 디렉터리의 파일은 모두 지우고 다시 추가해야 한다.&lt;/li&gt;
&lt;li&gt;아스키 코드로 된 파일 이름이 아닌 유니코드 파일을 제한적으로 지원한다.&lt;/li&gt;
&lt;li&gt;속도가 느리다.&lt;/li&gt;
&lt;li&gt;커밋 실패 시 롤백이 지원되지 않는다.&lt;/li&gt;
&lt;li&gt;VSS와 비교했을 경우 저장소가 다소 지저분하다.(&amp;lsquo;CVS&amp;rsquo; Directory들로 인해)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;SVN&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;설명 : SVN은 &amp;lsquo;Subversion&amp;rsquo;의 약자로써 버전관리 소프트웨어이다. 명령행 인터페이스에서 사용하는 명령어를 따서 &amp;lsquo;SVN&amp;rsquo;이라고 줄여서 부르기도 하며, CVS의 단점을 보완하기 위해 만들어졌다.&lt;/li&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;원자적 커밋을 지원하므로 다른 사용자의 커밋과 엉키지 않으며, 실패 시 롤백 기능을 지원한다.&lt;/li&gt;
&lt;li&gt;파일과 Directory의 삭제, 이동, 이름변경, 복사 등을 지원한다.&lt;/li&gt;
&lt;li&gt;소스 파일 이외에 이진파일도 효율적으로 저장할 수 있다.&lt;/li&gt;
&lt;li&gt;Directory도 버전 관리를 할 수 있다. Directory 전체를 빠르게 옮기거나 복사할 수 있으며, 리비전 기록도 그대로 유지한다.&lt;/li&gt;
&lt;li&gt;저장소의 크기에 상관없이 일정한 시간 안에 가지치기나 태그를 할 수 있다.&lt;/li&gt;
&lt;li&gt;처리 속도가 빠르다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;안정성에 있어선 아직까진 CVS에 미치지 못함.&lt;/li&gt;
&lt;li&gt;VSS와 비교했을 경우 저장소가 다소 지저분하다.(&amp;rsquo;.svn&amp;rsquo; Directory들로 인해)&lt;/li&gt;
&lt;li&gt;잦은 커밋으로 인해 리비전 번호의 인플레이션(inflation)이 유발될 수 있다.&lt;/li&gt;
&lt;li&gt;소스코드는 Diff를 통해 병합(Merge)이 가능하지만 이진파일은 어느 한쪽을 버릴 수 밖에 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;설명 : 프로그램 등의 소스 코드 관리를 위한 분산 버전 관리 시스템.&lt;/li&gt;
&lt;li&gt;지향점
&lt;ul&gt;
&lt;li&gt;빠른 수행 속도에 중점.&lt;/li&gt;
&lt;li&gt;네트워크에 접근하거나 중앙 서버에 의존하지 않음.&lt;/li&gt;
&lt;li&gt;작업 폴더는 모두, 전체 기록과 각 기록을 추적할 수 있는 정보를 포함한 완전한 형태의 저장소.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="변수-명명법"&gt;
 변수 명명법
 &lt;a class="heading-anchor" href="#%eb%b3%80%ec%88%98-%eb%aa%85%eb%aa%85%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;카멜 표기법&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Java를 하는 사람들에게 가장 익숙한 표기법이 바로 카멜 표기법&lt;/li&gt;
&lt;li&gt;기본적으로 변수를 소문자로 선언하는데, 두 단어 이상 이어진 변수는 첫 단어를 뺀 나머지 단어의 시작 부분을 대분자로 표기&lt;/li&gt;
&lt;li&gt;낙타의 등을 닮았다고 해서 붙여진 이름&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;busan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;appStore&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;javaWebProgramming&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;파스칼 표기법&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;C 계열에 익숙한 사람들이 많이 사용했을 표기법&lt;/li&gt;
&lt;li&gt;카멜 표기법과 유사하지만 유일한 차이점으로 모든 단어를 대분자로 표기&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Pascal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BlackCherry&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;RedAndBlue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="3"&gt;
&lt;li&gt;헝가리안 표기법&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;잘 안 쓰이는 표기법이지만 간혹가다 오래전에 짠 코드에서 가끔씩 발견되는 표기법&lt;/li&gt;
&lt;li&gt;변수의 앞에 자료형을 붙여서 명명하는 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strText&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;intNumber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arrBook&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="64bit와-32bit-차이점"&gt;
 64bit와 32bit 차이점?
 &lt;a class="heading-anchor" href="#64bit%ec%99%80-32bit-%ec%b0%a8%ec%9d%b4%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;CPU는 외부에서 들어오는 데이터 처리능력이 있다. 한번에 처리하는 데이터가 32bit라면 32bit, 64bit CPU는 한번에 64bit 처리가 가능하다.&lt;/li&gt;
&lt;li&gt;32bit로 메모리 공간을 표현한다면 최대 4Gbyte이다. 64bit라면 더 넓은 메모리 공간을 표현할 수 있는 것이다. 64bit를 사용하면 현재 보통 시스템에서는 128GB RAM과 1TB 페이징 스페이스를 사용할 수 있습니다.&lt;/li&gt;
&lt;li&gt;즉 64bit는 메모리의 확장을 통해 보다 많은 프로그램을 한번에 돌리는 것이 수월해 진다는 장점을 가지고 있습니다. 하지만 32bit에서 64bit로 변경시 2배의 속도증가를 체감할 수 있는 것은 아니다. 단순히 CPU와 메모리만으로 PC가 구동되는 것이 아니기 때문에 Disk나 VGA등 여러 구성요소에 병목이 존재하기 때문이다.&lt;/li&gt;
&lt;li&gt;만약 32bit컴퓨터의 주소값을 64bit로 표현하기로 하였다면 최소 주소공간은 2의 64승 개 만큼 넓어지나 CPU에서 처리를 위해서는 주소값을 2번에 걸쳐 전송이 이루어져야 하고 최소 2번 이상의 연산과정이 필요하다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Coding] Coding Test 정리</title><link>https://kyungryeol-yoon.github.io/cs/interview/coding-tests/</link><pubDate>Fri, 31 May 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/cs/interview/coding-tests/</guid><description>&lt;h2 id="모든-코딩-테스트는-c로-작성하였습니다"&gt;
 모든 코딩 테스트는 C++로 작성하였습니다.
 &lt;a class="heading-anchor" href="#%eb%aa%a8%eb%93%a0-%ec%bd%94%eb%94%a9-%ed%85%8c%ec%8a%a4%ed%8a%b8%eb%8a%94-c%eb%a1%9c-%ec%9e%91%ec%84%b1%ed%95%98%ec%98%80%ec%8a%b5%eb%8b%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;글자 뒤집기. 글자안에 특수문자 잇으면 그건 그대로 들고오기&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;Reverse&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;isSpecial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="sc"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;&amp;#39;z&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="sc"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;&amp;#39;Z&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Reverse&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;rev&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// i points to the first index of the array
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// j points to the last index of the array
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isSpecial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isSpecial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Reverse&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ReverseMain&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;kr.yoon1101@gamil.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;stringSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;rev&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stringSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;링크드리스트 두개 합치기 그리고 정렬. 중복은 한개만&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;바이너리 서치(Binary Search, 이진 검색)를 이용해서 배열안에 원하는 숫자 찾기&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//반복문을 이용한 이진 탐색
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;BinarySearch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;binarySearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_find&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;_find&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_find&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//재귀를 이용한 이진 탐색
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;BinarySearch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;binarySearch2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_find&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;_find&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;BinarySearch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;binaryRun&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;찾고 싶은 값은 : &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;cin&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;114&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;213&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;dataSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ans&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;binarySearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dataSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;ans&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;BinarySearch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;STLbinary_search&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;exist : &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;binary_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;사전 검색 프로그램 (띄어쓰기)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;회전수 구하기&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;비트 1의 갯수&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LRU&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;셀프 넘버 구하기&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;사다리 타기 프로그램&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;삼각별 만들기&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;스도쿠 만들기&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;지뢰게임&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>[Kubernetes] 쿠버네티스 네트워킹 이해하기 (3) - 외부로 서비스 노출하기 (NodePort, LoadBalancer)</title><link>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-networking-03-external/</link><pubDate>Fri, 17 May 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-networking-03-external/</guid><description>&lt;h2 id="-1-가장-단순한-외부-노출-nodeport"&gt;
 🚪 1. 가장 단순한 외부 노출: NodePort
 &lt;a class="heading-anchor" href="#-1-%ea%b0%80%ec%9e%a5-%eb%8b%a8%ec%88%9c%ed%95%9c-%ec%99%b8%eb%b6%80-%eb%85%b8%ec%b6%9c-nodeport" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;NodePort&lt;/strong&gt;는 말 그대로 모든 노드(서버)의 특정 포트를 개방하여 내부 서비스로 연결하는 방식입니다.&lt;/p&gt;
&lt;h3 id="-동작-원리"&gt;
 💡 동작 원리
 &lt;a class="heading-anchor" href="#-%eb%8f%99%ec%9e%91-%ec%9b%90%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;모든 노드의 동일한 포트(기본 범위: 30000-32767)를 엽니다.&lt;/li&gt;
&lt;li&gt;사용자가 &lt;code&gt;노드IP:포트&lt;/code&gt;로 접속하면, 해당 노드는 그 트래픽을 서비스(ClusterIP)로 전달합니다.&lt;/li&gt;
&lt;li&gt;서비스는 다시 이를 파드(Pod)로 전달합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="-특징"&gt;
 ✅ 특징
 &lt;a class="heading-anchor" href="#-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;장점&lt;/strong&gt;: 별도의 외부 장비 없이 클러스터 자체 기능만으로 외부 접속이 가능합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;단점&lt;/strong&gt;: 노드의 실제 IP가 노출되며, 포트 관리가 번거롭습니다. 노드 IP가 변경되면 클라이언트 설정도 바꿔야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-2-클라우드의-표준-loadbalancer"&gt;
 ⚖️ 2. 클라우드의 표준: LoadBalancer
 &lt;a class="heading-anchor" href="#-2-%ed%81%b4%eb%9d%bc%ec%9a%b0%eb%93%9c%ec%9d%98-%ed%91%9c%ec%a4%80-loadbalancer" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;대부분의 클라우드 환경(AWS, GCP, Azure 등)에서 사용하는 가장 대중적인 방식입니다.&lt;/p&gt;
&lt;h3 id="-동작-원리-1"&gt;
 💡 동작 원리
 &lt;a class="heading-anchor" href="#-%eb%8f%99%ec%9e%91-%ec%9b%90%eb%a6%ac-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Service&lt;/code&gt;를 생성하면 클라우드 공급자에게 로드밸런서 생성을 요청합니다.&lt;/li&gt;
&lt;li&gt;클라우드 공급자는 외부 IP가 할당된 로드밸런서를 생성하고 클러스터의 NodePort와 연결합니다.&lt;/li&gt;
&lt;li&gt;사용자는 클라우드사가 제공하는 고정된 &lt;strong&gt;외부 IP&lt;/strong&gt;나 &lt;strong&gt;DNS&lt;/strong&gt;를 통해 접속합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="-특징-1"&gt;
 ✅ 특징
 &lt;a class="heading-anchor" href="#-%ed%8a%b9%ec%a7%95-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;장점&lt;/strong&gt;: 노드의 IP를 숨길 수 있고, 고정된 엔드포인트를 제공하여 운영이 편리합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;단점&lt;/strong&gt;: 클라우드 서비스 비용이 발생하며, 온프레미스(자체 서버) 환경에서는 별도의 솔루션(예: MetalLB)이 없으면 사용하기 어렵습니다. 💸&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-3-성능-최적화의-핵심-externaltrafficpolicy"&gt;
 ⚡ 3. 성능 최적화의 핵심: externalTrafficPolicy
 &lt;a class="heading-anchor" href="#-3-%ec%84%b1%eb%8a%a5-%ec%b5%9c%ec%a0%81%ed%99%94%ec%9d%98-%ed%95%b5%ec%8b%ac-externaltrafficpolicy" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;외부 트래픽이 들어올 때 매우 중요한 설정값이 하나 있습니다. 바로 &lt;code&gt;externalTrafficPolicy&lt;/code&gt;입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cluster (기본값)&lt;/strong&gt;: 트래픽을 받은 노드에 파드가 없으면 다른 노드로 전달합니다. 이 과정에서 홉(Hop)이 발생하고 **Client IP가 소실(SNAT)**될 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Local&lt;/strong&gt;: 트래픽을 받은 노드에 파드가 있을 때만 처리합니다. 다른 노드로 전달하지 않으므로 &lt;strong&gt;성능이 빠르고 Client IP가 보존&lt;/strong&gt;되지만, 특정 노드에 트래픽이 몰릴 수 있습니다. 🏎️&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-4-핵심-요약-어떤-것을-선택할까"&gt;
 🔍 4. 핵심 요약: 어떤 것을 선택할까?
 &lt;a class="heading-anchor" href="#-4-%ed%95%b5%ec%8b%ac-%ec%9a%94%ec%95%bd-%ec%96%b4%eb%96%a4-%ea%b2%83%ec%9d%84-%ec%84%a0%ed%83%9d%ed%95%a0%ea%b9%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;방식&lt;/th&gt;
					&lt;th style="text-align: left"&gt;용도&lt;/th&gt;
					&lt;th style="text-align: left"&gt;권장 환경&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;NodePort&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;테스트, 내부 통신용&lt;/td&gt;
					&lt;td style="text-align: left"&gt;온프레미스, 간단한 데모&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;LoadBalancer&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;실서비스 운영용&lt;/td&gt;
					&lt;td style="text-align: left"&gt;퍼블릭 클라우드, MetalLB 환경&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Ingress&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;L7 영역 제어 (도메인 기반)&lt;/td&gt;
					&lt;td style="text-align: left"&gt;여러 서비스를 하나의 IP로 묶을 때&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;</description></item><item><title>[Kubernetes] 쿠버네티스 네트워킹 이해하기 (2) - Service와 kube-proxy의 마법</title><link>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-networking-02-service/</link><pubDate>Sat, 11 May 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-networking-02-service/</guid><description>&lt;h2 id="-1-왜-service가-필요한가요"&gt;
 🧐 1. 왜 Service가 필요한가요?
 &lt;a class="heading-anchor" href="#-1-%ec%99%9c-service%ea%b0%80-%ed%95%84%ec%9a%94%ed%95%9c%ea%b0%80%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;쿠버네티스의 Pod은 영구적이지 않습니다. 에러가 나서 재시작되거나, 업데이트를 위해 교체되면 새로운 IP를 할당받습니다. 클라이언트가 매번 바뀌는 Pod의 IP를 추적하는 것은 불가능에 가깝죠.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;해결책&lt;/strong&gt;: 여러 개의 Pod 앞단에 **고정된 가상 IP(Virtual IP)**를 가진 Service를 둡니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;역할&lt;/strong&gt;: 클라이언트는 서비스의 VIP로만 요청을 보내고, 서비스는 뒤에 살아있는 Pod들에게 트래픽을 골고루 전달(Load Balancing)합니다. ⚖️&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-2-서비스의-핵심-조력자-kube-proxy"&gt;
 🛠️ 2. 서비스의 핵심 조력자: kube-proxy
 &lt;a class="heading-anchor" href="#-2-%ec%84%9c%eb%b9%84%ec%8a%a4%ec%9d%98-%ed%95%b5%ec%8b%ac-%ec%a1%b0%eb%a0%a5%ec%9e%90-kube-proxy" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;서비스는 실제로 물리적인 랜카드나 인터페이스가 존재하는 장치가 아닙니다. 리눅스 커널 수준에서 돌아가는 &lt;strong&gt;가상의 규칙&lt;/strong&gt;일 뿐입니다. 이 규칙을 실시간으로 관리하는 것이 바로 모든 노드에서 실행 중인 &lt;strong&gt;kube-proxy&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;kube-proxy는 크게 두 가지 방식으로 트래픽을 제어합니다.&lt;/p&gt;
&lt;h3 id="21-iptables-모드-기본-방식"&gt;
 2.1 iptables 모드 (기본 방식)
 &lt;a class="heading-anchor" href="#21-iptables-%eb%aa%a8%eb%93%9c-%ea%b8%b0%eb%b3%b8-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;원리&lt;/strong&gt;: 리눅스 커널의 네트워크 관리 도구인 &lt;code&gt;iptables&lt;/code&gt;를 이용합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;동작&lt;/strong&gt;: 서비스로 들어오는 패킷을 가로채서, 무작위로 선택된 Pod의 실제 IP로 목적지를 바꿉니다(&lt;strong&gt;DNAT&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;특징&lt;/strong&gt;: 설정이 복잡해질수록 성능이 약간 저하될 수 있지만, 가장 널리 쓰이는 표준 방식입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="22-ipvs-모드-고성능-방식"&gt;
 2.2 IPVS 모드 (고성능 방식)
 &lt;a class="heading-anchor" href="#22-ipvs-%eb%aa%a8%eb%93%9c-%ea%b3%a0%ec%84%b1%eb%8a%a5-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;원리&lt;/strong&gt;: 커널의 L4 로드밸런서인 &lt;code&gt;IPVS&lt;/code&gt;를 이용합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;특징&lt;/strong&gt;: &lt;code&gt;iptables&lt;/code&gt;보다 훨씬 빠르고 더 다양한 로드밸런싱 알고리즘(Round Robin 등)을 지원합니다. 대규모 클러스터에서 권장됩니다. 🚀&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-3-트래픽의-여정-clusterip-통신-과정"&gt;
 🔄 3. 트래픽의 여정: ClusterIP 통신 과정
 &lt;a class="heading-anchor" href="#-3-%ed%8a%b8%eb%9e%98%ed%94%bd%ec%9d%98-%ec%97%ac%ec%a0%95-clusterip-%ed%86%b5%ec%8b%a0-%ea%b3%bc%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;가장 기본인 &lt;strong&gt;ClusterIP&lt;/strong&gt; 서비스로 요청이 전달되는 과정을 살펴봅시다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;요청 시작&lt;/strong&gt;: 클라이언트 Pod이 서비스의 가상 IP(&lt;code&gt;10.96.0.1&lt;/code&gt;)로 패킷을 보냅니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;패킷 가로채기&lt;/strong&gt;: 패킷이 노드의 네트워크를 통과할 때, 커널의 &lt;code&gt;netfilter&lt;/code&gt;(iptables 규칙)가 이 패킷이 서비스 IP임을 알아채고 가로챕니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;목적지 변경(DNAT)&lt;/strong&gt;: 규칙에 따라 목적지 주소를 서비스 VIP에서 **실제 살아있는 Pod 중 하나(예: 172.16.0.5)**의 IP로 변경합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;전달&lt;/strong&gt;: 이제 패킷은 일반적인 Pod 대 Pod 통신 방식을 타고 목적지 Pod에 무사히 도착합니다. 🏁&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="-4-핵심-요약-서비스-네트워킹의-진실"&gt;
 🔍 4. 핵심 요약: 서비스 네트워킹의 진실
 &lt;a class="heading-anchor" href="#-4-%ed%95%b5%ec%8b%ac-%ec%9a%94%ec%95%bd-%ec%84%9c%eb%b9%84%ec%8a%a4-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%82%b9%ec%9d%98-%ec%a7%84%ec%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;서비스 IP는 가짜다&lt;/strong&gt;: 서비스 IP(ClusterIP)는 핑(ping)이 가지 않는 가상의 주소입니다. 오직 TCP/UDP 통신만 &lt;code&gt;iptables&lt;/code&gt; 규칙에 의해 변환됩니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;kube-proxy가 지휘자다&lt;/strong&gt;: API 서버를 감시하다가 서비스나 Pod에 변화가 생기면 즉시 모든 노드의 &lt;code&gt;iptables&lt;/code&gt; 규칙을 업데이트합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NAT의 연속&lt;/strong&gt;: 우리가 서비스 주소로 통신하는 것은 사실 커널 수준에서 엄청난 속도로 주소를 갈아치우는 NAT 연산의 결과물입니다.&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>[Kubernetes] 쿠버네티스 네트워킹 이해하기 (1) - Pod 네트워킹의 원리</title><link>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-networking-01-pod/</link><pubDate>Tue, 07 May 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-networking-01-pod/</guid><description>&lt;h2 id="-1-쿠버네티스-네트워킹의-4가지-당면-과제"&gt;
 🏗️ 1. 쿠버네티스 네트워킹의 4가지 당면 과제
 &lt;a class="heading-anchor" href="#-1-%ec%bf%a0%eb%b2%84%eb%84%a4%ed%8b%b0%ec%8a%a4-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%82%b9%ec%9d%98-4%ea%b0%80%ec%a7%80-%eb%8b%b9%eb%a9%b4-%ea%b3%bc%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;쿠버네티스 네트워킹은 크게 4가지 통신 패턴을 해결해야 합니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;컨테이너 대 컨테이너&lt;/strong&gt;: 같은 Pod 내의 컨테이너 간 통신&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pod 대 Pod&lt;/strong&gt;: Pod과 Pod 간의 통신&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pod 대 Service&lt;/strong&gt;: Pod과 서비스 간의 통신&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;외부 대 Service&lt;/strong&gt;: 외부에서 내부 서비스로의 통신&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이 글은 그중에서도 가장 기초가 되는 &lt;strong&gt;1번과 2번&lt;/strong&gt;을 집중적으로 다룹니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-2-같은-pod-내-컨테이너-통신-pause-컨테이너"&gt;
 📦 2. 같은 Pod 내 컨테이너 통신: Pause 컨테이너
 &lt;a class="heading-anchor" href="#-2-%ea%b0%99%ec%9d%80-pod-%eb%82%b4-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%ed%86%b5%ec%8b%a0-pause-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;쿠버네티스에서 Pod 내의 여러 컨테이너는 어떻게 서로 &lt;code&gt;localhost&lt;/code&gt;로 통신할 수 있을까요? 바로 &lt;strong&gt;Pause 컨테이너&lt;/strong&gt; 덕분입니다. 🛡️&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pause 컨테이너의 역할&lt;/strong&gt;: Pod이 생성될 때 가장 먼저 생성되는 컨테이너로, 네트워크 네임스페이스(Network Namespace)를 유지하는 역할을 합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Network Sharing&lt;/strong&gt;: 이후 생성되는 실제 컨테이너들은 이 Pause 컨테이너의 네트워크 환경을 공유합니다. 따라서 같은 Pod 내 컨테이너들은 서로 IP가 같고, 포트 번호로만 구분하여 통신하게 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-3-pod-대-pod-통신-ip-per-pod-모델"&gt;
 🌉 3. Pod 대 Pod 통신 (IP-per-Pod 모델)
 &lt;a class="heading-anchor" href="#-3-pod-%eb%8c%80-pod-%ed%86%b5%ec%8b%a0-ip-per-pod-%eb%aa%a8%eb%8d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;쿠버네티스의 네트워킹 철학 중 가장 중요한 것은 **&amp;ldquo;모든 Pod은 고유한 IP를 가지며, NAT 없이 서로 통신할 수 있어야 한다&amp;rdquo;**는 것입니다.&lt;/p&gt;
&lt;h3 id="31-같은-노드-내의-통신"&gt;
 3.1 같은 노드 내의 통신
 &lt;a class="heading-anchor" href="#31-%ea%b0%99%ec%9d%80-%eb%85%b8%eb%93%9c-%eb%82%b4%ec%9d%98-%ed%86%b5%ec%8b%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;하나의 노드(서버) 안에서 Pod들이 통신할 때는 **veth pair(Virtual Ethernet)**와 &lt;strong&gt;Bridge&lt;/strong&gt;를 사용합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;각 Pod은 가상 이더넷 인터페이스를 통해 노드에 설치된 브리지(예: cbr0)에 연결됩니다.&lt;/li&gt;
&lt;li&gt;브리지는 허브 역할을 하여 같은 노드 내의 Pod들이 서로의 IP를 찾을 수 있게 해줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="32-서로-다른-노드-간의-통신"&gt;
 3.2 서로 다른 노드 간의 통신
 &lt;a class="heading-anchor" href="#32-%ec%84%9c%eb%a1%9c-%eb%8b%a4%eb%a5%b8-%eb%85%b8%eb%93%9c-%ea%b0%84%ec%9d%98-%ed%86%b5%ec%8b%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;서로 다른 노드에 있는 Pod끼리 통신할 때는 라우팅(Routing)이나 터널링 기술이 필요합니다. 이때 우리가 흔히 듣는 **CNI(Calico, Flannel, Cilium 등)**가 이 복잡한 경로를 대신 찾아주는 역할을 합니다. 🗺️&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-4-핵심-요약-쿠버네티스의-약속"&gt;
 🔍 4. 핵심 요약: 쿠버네티스의 약속
 &lt;a class="heading-anchor" href="#-4-%ed%95%b5%ec%8b%ac-%ec%9a%94%ec%95%bd-%ec%bf%a0%eb%b2%84%eb%84%a4%ed%8b%b0%ec%8a%a4%ec%9d%98-%ec%95%bd%ec%86%8d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;쿠버네티스 네트워크가 성립하려면 아래 3가지 규칙이 반드시 지켜져야 합니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;임의의 노드에 있는 Pod은 NAT 없이 다른 노드에 있는 Pod과 통신할 수 있어야 한다.&lt;/li&gt;
&lt;li&gt;노드에 있는 에이전트(예: kubelet, 대시보드)는 해당 노드에 있는 모든 Pod과 통신할 수 있어야 한다.&lt;/li&gt;
&lt;li&gt;(선택사항) 노드의 호스트 네트워크에 있는 Pod은 NAT 없이 다른 노드의 Pod과 통신할 수 있어야 한다.&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>[Spring] JPA (Hibernate) - Error (creating bean with name 'entityManagerFactory')</title><link>https://kyungryeol-yoon.github.io/backend/spring/spring-jpa-error/</link><pubDate>Fri, 22 Feb 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/spring/spring-jpa-error/</guid><description>&lt;h2 id="jdk를-openjdk11로-변경했더니-startup할-때-오류가-발생"&gt;
 JDK를 openjdk11로 변경했더니 startup할 때 오류가 발생
 &lt;a class="heading-anchor" href="#jdk%eb%a5%bc-openjdk11%eb%a1%9c-%eb%b3%80%ea%b2%bd%ed%96%88%eb%8d%94%eb%8b%88-startup%ed%95%a0-%eb%95%8c-%ec%98%a4%eb%a5%98%ea%b0%80-%eb%b0%9c%ec%83%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;ERROR o.s.boot.SpringApplication - Application run failed
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;org.springframework.beans.factory.BeanCreationException: Error creating bean with name &lt;span class="s1"&gt;&amp;#39;entityManagerFactory&amp;#39;&lt;/span&gt; defined in class path resource &lt;span class="o"&gt;[&lt;/span&gt;org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class&lt;span class="o"&gt;]&lt;/span&gt;: Invocation of init method failed&lt;span class="p"&gt;;&lt;/span&gt; nested exception is javax.persistence.PersistenceException: &lt;span class="o"&gt;[&lt;/span&gt;PersistenceUnit: default&lt;span class="o"&gt;]&lt;/span&gt; Unable to build Hibernate SessionFactory&lt;span class="p"&gt;;&lt;/span&gt; nested exception is org.hibernate.MappingException: Could not get constructor &lt;span class="k"&gt;for&lt;/span&gt; org.hibernate.persister.entity.SingleTableEntityPersister
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean&lt;span class="o"&gt;(&lt;/span&gt;AbstractAutowireCapableBeanFactory.java:1699&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean&lt;span class="o"&gt;(&lt;/span&gt;AbstractAutowireCapableBeanFactory.java:573&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean&lt;span class="o"&gt;(&lt;/span&gt;AbstractAutowireCapableBeanFactory.java:495&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.beans.factory.support.AbstractBeanFactory.lambda&lt;span class="nv"&gt;$doGetBean$0&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;AbstractBeanFactory.java:317&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton&lt;span class="o"&gt;(&lt;/span&gt;DefaultSingletonBeanRegistry.java:222&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean&lt;span class="o"&gt;(&lt;/span&gt;AbstractBeanFactory.java:315&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.beans.factory.support.AbstractBeanFactory.getBean&lt;span class="o"&gt;(&lt;/span&gt;AbstractBeanFactory.java:199&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.context.support.AbstractApplicationContext.getBean&lt;span class="o"&gt;(&lt;/span&gt;AbstractApplicationContext.java:1089&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization&lt;span class="o"&gt;(&lt;/span&gt;AbstractApplicationContext.java:859&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.context.support.AbstractApplicationContext.refresh&lt;span class="o"&gt;(&lt;/span&gt;AbstractApplicationContext.java:550&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh&lt;span class="o"&gt;(&lt;/span&gt;ServletWebServerApplicationContext.java:140&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.boot.SpringApplication.refresh&lt;span class="o"&gt;(&lt;/span&gt;SpringApplication.java:762&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.boot.SpringApplication.refreshContext&lt;span class="o"&gt;(&lt;/span&gt;SpringApplication.java:398&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.boot.SpringApplication.run&lt;span class="o"&gt;(&lt;/span&gt;SpringApplication.java:330&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.boot.SpringApplication.run&lt;span class="o"&gt;(&lt;/span&gt;SpringApplication.java:1258&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.boot.SpringApplication.run&lt;span class="o"&gt;(&lt;/span&gt;SpringApplication.java:1246&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;at com.yhkim.study.FirstprojectApplication.main&lt;span class="o"&gt;(&lt;/span&gt;FirstprojectApplication.java:10&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;Caused by: javax.persistence.PersistenceException: &lt;span class="o"&gt;[&lt;/span&gt;PersistenceUnit: default&lt;span class="o"&gt;]&lt;/span&gt; Unable to build Hibernate essionFactory&lt;span class="p"&gt;;&lt;/span&gt; nested exception is org.hibernate.MappingException: Could not get constructor &lt;span class="k"&gt;for&lt;/span&gt; org.hibernate.persister.entity.SingleTableEntityPersister
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory&lt;span class="o"&gt;(&lt;/span&gt;AbstractEntityManagerFactoryBean.java:402&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet&lt;span class="o"&gt;(&lt;/span&gt;AbstractEntityManagerFactoryBean.java:377&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet&lt;span class="o"&gt;(&lt;/span&gt;LocalContainerEntityManagerFactoryBean.java:341&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods&lt;span class="o"&gt;(&lt;/span&gt;AbstractAutowireCapableBeanFactory.java:1758&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean&lt;span class="o"&gt;(&lt;/span&gt;AbstractAutowireCapableBeanFactory.java:1695&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;... &lt;span class="m"&gt;16&lt;/span&gt; common frames omitted
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;Caused by: org.hibernate.MappingException: Could not get constructor &lt;span class="k"&gt;for&lt;/span&gt; org.hibernate.persister.entity.SingleTableEntityPersister
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister&lt;span class="o"&gt;(&lt;/span&gt;PersisterFactoryImpl.java:123&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister&lt;span class="o"&gt;(&lt;/span&gt;PersisterFactoryImpl.java:77&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.metamodel.internal.MetamodelImpl.initialize&lt;span class="o"&gt;(&lt;/span&gt;MetamodelImpl.java:129&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.internal.SessionFactoryImpl.&amp;lt;init&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;SessionFactoryImpl.java:300&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build&lt;span class="o"&gt;(&lt;/span&gt;SessionFactoryBuilderImpl.java:462&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build&lt;span class="o"&gt;(&lt;/span&gt;EntityManagerFactoryBuilderImpl.java:892&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory&lt;span class="o"&gt;(&lt;/span&gt;SpringHibernateJpaPersistenceProvider.java:57&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory&lt;span class="o"&gt;(&lt;/span&gt;LocalContainerEntityManagerFactoryBean.java:365&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory&lt;span class="o"&gt;(&lt;/span&gt;AbstractEntityManagerFactoryBean.java:390&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;... &lt;span class="m"&gt;20&lt;/span&gt; common frames omitted
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;Caused by: org.hibernate.HibernateException: Unable to instantiate default tuplizer &lt;span class="o"&gt;[&lt;/span&gt;org.hibernate.tuple.entity.PojoEntityTuplizer&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.tuple.entity.EntityTuplizerFactory.constructTuplizer&lt;span class="o"&gt;(&lt;/span&gt;EntityTuplizerFactory.java:91&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.tuple.entity.EntityTuplizerFactory.constructDefaultTuplizer&lt;span class="o"&gt;(&lt;/span&gt;EntityTuplizerFactory.java:116&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.tuple.entity.EntityMetamodel.&amp;lt;init&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;EntityMetamodel.java:382&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.persister.entity.AbstractEntityPersister.&amp;lt;init&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;AbstractEntityPersister.java:519&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.persister.entity.SingleTableEntityPersister.&amp;lt;init&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;SingleTableEntityPersister.java:124&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0&lt;span class="o"&gt;(&lt;/span&gt;Native Method&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance&lt;span class="o"&gt;(&lt;/span&gt;NativeConstructorAccessorImpl.java:62&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance&lt;span class="o"&gt;(&lt;/span&gt;DelegatingConstructorAccessorImpl.java:45&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;at java.base/java.lang.reflect.Constructor.newInstance&lt;span class="o"&gt;(&lt;/span&gt;Constructor.java:490&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister&lt;span class="o"&gt;(&lt;/span&gt;PersisterFactoryImpl.java:96&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;... &lt;span class="m"&gt;28&lt;/span&gt; common frames omitted
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;Caused by: java.lang.reflect.InvocationTargetException: null
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0&lt;span class="o"&gt;(&lt;/span&gt;Native Method&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance&lt;span class="o"&gt;(&lt;/span&gt;NativeConstructorAccessorImpl.java:62&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance&lt;span class="o"&gt;(&lt;/span&gt;DelegatingConstructorAccessorImpl.java:45&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;at java.base/java.lang.reflect.Constructor.newInstance&lt;span class="o"&gt;(&lt;/span&gt;Constructor.java:490&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.tuple.entity.EntityTuplizerFactory.constructTuplizer&lt;span class="o"&gt;(&lt;/span&gt;EntityTuplizerFactory.java:88&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt;... &lt;span class="m"&gt;37&lt;/span&gt; common frames omitted
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;57&lt;/span&gt;&lt;span class="cl"&gt;Caused by: java.lang.NullPointerException: null
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;58&lt;/span&gt;&lt;span class="cl"&gt;at javassist.util.proxy.SecurityActions.setAccessible&lt;span class="o"&gt;(&lt;/span&gt;SecurityActions.java:103&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;59&lt;/span&gt;&lt;span class="cl"&gt;at javassist.util.proxy.DefineClassHelper.toClass3&lt;span class="o"&gt;(&lt;/span&gt;DefineClassHelper.java:151&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;60&lt;/span&gt;&lt;span class="cl"&gt;at javassist.util.proxy.DefineClassHelper.toClass2&lt;span class="o"&gt;(&lt;/span&gt;DefineClassHelper.java:134&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;61&lt;/span&gt;&lt;span class="cl"&gt;at javassist.util.proxy.DefineClassHelper.toClass&lt;span class="o"&gt;(&lt;/span&gt;DefineClassHelper.java:95&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;62&lt;/span&gt;&lt;span class="cl"&gt;at javassist.util.proxy.FactoryHelper.toClass&lt;span class="o"&gt;(&lt;/span&gt;FactoryHelper.java:131&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;63&lt;/span&gt;&lt;span class="cl"&gt;at javassist.util.proxy.ProxyFactory.createClass3&lt;span class="o"&gt;(&lt;/span&gt;ProxyFactory.java:530&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;64&lt;/span&gt;&lt;span class="cl"&gt;at javassist.util.proxy.ProxyFactory.createClass2&lt;span class="o"&gt;(&lt;/span&gt;ProxyFactory.java:515&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;65&lt;/span&gt;&lt;span class="cl"&gt;at javassist.util.proxy.ProxyFactory.createClass1&lt;span class="o"&gt;(&lt;/span&gt;ProxyFactory.java:451&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;66&lt;/span&gt;&lt;span class="cl"&gt;at javassist.util.proxy.ProxyFactory.createClass&lt;span class="o"&gt;(&lt;/span&gt;ProxyFactory.java:422&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;67&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.proxy.pojo.javassist.JavassistProxyFactory.postInstantiate&lt;span class="o"&gt;(&lt;/span&gt;JavassistProxyFactory.java:75&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;68&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.tuple.entity.PojoEntityTuplizer.buildProxyFactory&lt;span class="o"&gt;(&lt;/span&gt;PojoEntityTuplizer.java:162&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;69&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.tuple.entity.AbstractEntityTuplizer.&amp;lt;init&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;AbstractEntityTuplizer.java:156&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;70&lt;/span&gt;&lt;span class="cl"&gt;at org.hibernate.tuple.entity.PojoEntityTuplizer.&amp;lt;init&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;PojoEntityTuplizer.java:58&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;71&lt;/span&gt;&lt;span class="cl"&gt;... &lt;span class="m"&gt;42&lt;/span&gt; common frames omitted&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="원인"&gt;
 원인
 &lt;a class="heading-anchor" href="#%ec%9b%90%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;JPA(Hibernate)라는 것은 결국 BCI방식으로 class load시점에 entity와 JPA Interface를 이용하여 SQL문을 자동 생성하여 삽입시켜주는 역할&lt;/li&gt;
&lt;li&gt;로그를 보면 org.hibernate.persister.entity.SingleTableEntityPersister의 생성자에서 그 역할을 하는듯 하다.&lt;/li&gt;
&lt;li&gt;그런데 openjdk11에서는 javaassist가 removed 되었는지 entityManagerFactory 빈을 생성할 때
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;at javassist.util.proxy.SecurityActions.setAccessible(SecurityActions.java:103)&lt;/code&gt;에서 NullPointerException이 발생한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="해결"&gt;
 해결
 &lt;a class="heading-anchor" href="#%ed%95%b4%ea%b2%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;pom.xml에 javassist에 대한 dependency를 추가해주면 된다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.javassist&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;javassist&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.23.1-GA&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Logging &amp; Monitoring 완벽 가이드 (Prometheus, Grafana, Fluentd)</title><link>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-logging-monitoring-guide/</link><pubDate>Thu, 21 Feb 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/observability/grafana-loki/kubernetes-logging-monitoring-guide/</guid><description>&lt;h2 id="-kubernetes-logging--monitoring-이해하기"&gt;
 ☸️ Kubernetes Logging &amp;amp; Monitoring 이해하기
 &lt;a class="heading-anchor" href="#-kubernetes-logging--monitoring-%ec%9d%b4%ed%95%b4%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes 클러스터를 운영하다 보면 &lt;strong&gt;로그 수집과 모니터링&lt;/strong&gt;이 필수입니다.&lt;/p&gt;
&lt;p&gt;목적&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod / Cluster 상태 확인&lt;/li&gt;
&lt;li&gt;문제 발생 시 빠른 원인 파악&lt;/li&gt;
&lt;li&gt;운영 효율성 향상&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이를 위해 많이 사용되는 도구&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fluentd&lt;/strong&gt;: 로그 수집/전송&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prometheus&lt;/strong&gt;: 모니터링, 메트릭 수집&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Grafana&lt;/strong&gt;: 시각화&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="클러스터-로그-수집-구조"&gt;
 클러스터 로그 수집 구조
 &lt;a class="heading-anchor" href="#%ed%81%b4%eb%9f%ac%ec%8a%a4%ed%84%b0-%eb%a1%9c%ea%b7%b8-%ec%88%98%ec%a7%91-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod / Container]

B[Fluentd DaemonSet]

C[Log Storage]

A --&amp;gt; B --&amp;gt; C&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Fluentd는 &lt;strong&gt;각 Node에 DaemonSet으로 배포&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Pod 로그를 수집하고 중앙 저장소로 전송&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="모니터링-구조"&gt;
 모니터링 구조
 &lt;a class="heading-anchor" href="#%eb%aa%a8%eb%8b%88%ed%84%b0%eb%a7%81-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod / Node Metrics]

B[Prometheus Server]

C[Grafana Dashboard]

A --&amp;gt; B --&amp;gt; C&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Prometheus: 메트릭 수집, 저장&lt;/li&gt;
&lt;li&gt;Grafana: 시각화 및 알람 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="fluentd-예시"&gt;
 Fluentd 예시
 &lt;a class="heading-anchor" href="#fluentd-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;DaemonSet&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;fluentd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;fluentd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;fluent/fluentd:v1.14&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;varlog&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/log&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Pod 로그를 수집 후 중앙 저장소로 전송 가능&lt;/li&gt;
&lt;li&gt;Elasticsearch, S3, Kafka 등 연동 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="prometheus-설정-예시"&gt;
 Prometheus 설정 예시
 &lt;a class="heading-anchor" href="#prometheus-%ec%84%a4%ec%a0%95-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;monitoring.coreos.com/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ServiceMonitor&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pod-monitor&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;myapp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/metrics&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Pod / Node 메트릭 수집&lt;/li&gt;
&lt;li&gt;AlertManager와 연동 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="grafana-대시보드-예시"&gt;
 Grafana 대시보드 예시
 &lt;a class="heading-anchor" href="#grafana-%eb%8c%80%ec%8b%9c%eb%b3%b4%eb%93%9c-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Prometheus]

B[Grafana]

C[Dashboard]

A --&amp;gt; B --&amp;gt; C&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Pod 상태, Node 리소스, 클러스터 이벤트 시각화&lt;/li&gt;
&lt;li&gt;알람(Alert) 설정 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="logging--monitoring-전체-아키텍처"&gt;
 Logging &amp;amp; Monitoring 전체 아키텍처
 &lt;a class="heading-anchor" href="#logging--monitoring-%ec%a0%84%ec%b2%b4-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod / Container]

B[Node Metrics]

C[Fluentd]

D[Prometheus]

E[Central Log Storage]

F[Grafana Dashboard]

A --&amp;gt; C --&amp;gt; E
A --&amp;gt; D --&amp;gt; F
B --&amp;gt; D --&amp;gt; F&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;로그와 메트릭을 중앙화&lt;/li&gt;
&lt;li&gt;운영자가 쉽게 모니터링 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="실무-운영-팁"&gt;
 실무 운영 팁
 &lt;a class="heading-anchor" href="#%ec%8b%a4%eb%ac%b4-%ec%9a%b4%ec%98%81-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;1️⃣ Pod 이름 / Namespace 기준으로 로그 분리
2️⃣ 중요한 이벤트는 Alert 설정 (CPU, Memory, CrashLoop)
3️⃣ 장기 로그는 S3 등 외부 스토리지로 아카이브
4️⃣ Grafana Dashboard를 팀별/서비스별로 구성&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="정리"&gt;
 정리
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes Logging &amp;amp; Monitoring 핵심&lt;/p&gt;
&lt;h3 id="logging"&gt;
 Logging
 &lt;a class="heading-anchor" href="#logging" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Fluentd DaemonSet으로 Pod 로그 수집&lt;/li&gt;
&lt;li&gt;중앙 저장소로 전송&lt;/li&gt;
&lt;li&gt;필터링/분류 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="monitoring"&gt;
 Monitoring
 &lt;a class="heading-anchor" href="#monitoring" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Prometheus로 메트릭 수집&lt;/li&gt;
&lt;li&gt;Grafana로 시각화, 알람 설정&lt;/li&gt;
&lt;li&gt;Pod / Node 상태 모니터링&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="운영-팁"&gt;
 운영 팁
 &lt;a class="heading-anchor" href="#%ec%9a%b4%ec%98%81-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Alert 설정&lt;/li&gt;
&lt;li&gt;로그 장기 보관&lt;/li&gt;
&lt;li&gt;Dashboard 관리&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Resource Management 완벽 이해 (CPU, Memory, Limits &amp; Requests, QoS)</title><link>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-resource-management-guide/</link><pubDate>Tue, 19 Feb 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-resource-management-guide/</guid><description>&lt;h2 id="-kubernetes-resource-management-이해하기"&gt;
 ☸️ Kubernetes Resource Management 이해하기
 &lt;a class="heading-anchor" href="#-kubernetes-resource-management-%ec%9d%b4%ed%95%b4%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes에서 **리소스 관리(Resource Management)**는 안정적인 클러스터 운영과 애플리케이션 성능 보장을 위해 필수적입니다.&lt;/p&gt;
&lt;p&gt;리소스를 관리하지 않으면 다음 문제가 발생할 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod가 OOMKilled로 종료됨&lt;/li&gt;
&lt;li&gt;노드 리소스 부족으로 스케줄링 실패&lt;/li&gt;
&lt;li&gt;특정 Pod가 다른 Pod를 독점하여 클러스터 불균형 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kubernetes는 &lt;strong&gt;CPU, Memory 요청(Requests)과 제한(Limits), QoS Class&lt;/strong&gt;를 통해 이를 관리합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="pod-리소스-요청request과-제한limit"&gt;
 Pod 리소스 요청(Request)과 제한(Limit)
 &lt;a class="heading-anchor" href="#pod-%eb%a6%ac%ec%86%8c%ec%8a%a4-%ec%9a%94%ec%b2%adrequest%ea%b3%bc-%ec%a0%9c%ed%95%9climit" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Pod/Container 리소스는 &lt;strong&gt;Requests&lt;/strong&gt;와 &lt;strong&gt;Limits&lt;/strong&gt;로 정의합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Requests&lt;/td&gt;
					&lt;td&gt;Pod가 필요로 하는 최소 리소스&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Limits&lt;/td&gt;
					&lt;td&gt;Pod가 사용할 수 있는 최대 리소스&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;500m&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;256Mi&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;512Mi&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="cpu와-memory-단위"&gt;
 CPU와 Memory 단위
 &lt;a class="heading-anchor" href="#cpu%ec%99%80-memory-%eb%8b%a8%ec%9c%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;CPU: 1 = 1 Core, 500m = 0.5 Core&lt;/li&gt;
&lt;li&gt;Memory: Mi = Mebibyte, Gi = Gibibyte&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="resource-management-구조"&gt;
 Resource Management 구조
 &lt;a class="heading-anchor" href="#resource-management-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod]

B[Container]

C[Requests]

D[Limits]

A --&amp;gt; B
B --&amp;gt; C
B --&amp;gt; D&lt;/pre&gt;
&lt;p&gt;Pod는 Requests 만큼 리소스를 보장받고, Limits를 넘으면 제한됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="qos-class"&gt;
 QoS Class
 &lt;a class="heading-anchor" href="#qos-class" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes는 리소스 설정에 따라 Pod를 3가지 QoS Class로 분류합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;QoS Class&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
					&lt;th&gt;조건&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Guaranteed&lt;/td&gt;
					&lt;td&gt;요청 = 제한&lt;/td&gt;
					&lt;td&gt;모든 컨테이너 Requests = Limits&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Burstable&lt;/td&gt;
					&lt;td&gt;요청 &amp;lt; 제한&lt;/td&gt;
					&lt;td&gt;일부 컨테이너 Requests &amp;lt; Limits&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;BestEffort&lt;/td&gt;
					&lt;td&gt;리소스 요청 없음&lt;/td&gt;
					&lt;td&gt;Requests, Limits 설정 없음&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod QoS]

B[Guaranteed]
C[Burstable]
D[BestEffort]

A --&amp;gt; B
A --&amp;gt; C
A --&amp;gt; D&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="qos-class-활용"&gt;
 QoS Class 활용
 &lt;a class="heading-anchor" href="#qos-class-%ed%99%9c%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Guaranteed: 안정성 최우선, 리소스 보장&lt;/li&gt;
&lt;li&gt;Burstable: 유연성 제공, 여유 자원 사용&lt;/li&gt;
&lt;li&gt;BestEffort: 최소 보장, 클러스터가 여유 있을 때만 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="리소스-관리-동작-예시"&gt;
 리소스 관리 동작 예시
 &lt;a class="heading-anchor" href="#%eb%a6%ac%ec%86%8c%ec%8a%a4-%ea%b4%80%eb%a6%ac-%eb%8f%99%ec%9e%91-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="1-cpu-초과"&gt;
 1️⃣ CPU 초과
 &lt;a class="heading-anchor" href="#1-cpu-%ec%b4%88%ea%b3%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod CPU Usage]

B[CPU Limit]

A --&amp;gt;|Exceed| B[Throttle]&lt;/pre&gt;
&lt;p&gt;CPU Limit를 초과하면 컨테이너가 &lt;strong&gt;Throttle(제한)&lt;/strong&gt; 됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="2-memory-초과"&gt;
 2️⃣ Memory 초과
 &lt;a class="heading-anchor" href="#2-memory-%ec%b4%88%ea%b3%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod Memory Usage]

B[Memory Limit]

A --&amp;gt;|Exceed| B[OOMKilled]&lt;/pre&gt;
&lt;p&gt;Memory Limit를 초과하면 컨테이너가 &lt;strong&gt;OOMKilled&lt;/strong&gt; 됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="resource-management-전체-아키텍처"&gt;
 Resource Management 전체 아키텍처
 &lt;a class="heading-anchor" href="#resource-management-%ec%a0%84%ec%b2%b4-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod]

B[Container]

C[Requests]

D[Limits]

E[QoS Class]

F[CPU/Memory Scheduling]

A --&amp;gt; B --&amp;gt; C
B --&amp;gt; D
B --&amp;gt; E
E --&amp;gt; F&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="정리"&gt;
 정리
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes Resource Management 핵심&lt;/p&gt;
&lt;h3 id="requests"&gt;
 Requests
 &lt;a class="heading-anchor" href="#requests" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pod/Container 최소 리소스 보장&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="limits"&gt;
 Limits
 &lt;a class="heading-anchor" href="#limits" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pod/Container 최대 리소스 제한&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="qos-class-1"&gt;
 QoS Class
 &lt;a class="heading-anchor" href="#qos-class-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Guaranteed / Burstable / BestEffort&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="관리-효과"&gt;
 관리 효과
 &lt;a class="heading-anchor" href="#%ea%b4%80%eb%a6%ac-%ed%9a%a8%ea%b3%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;안정적인 클러스터 운영&lt;/li&gt;
&lt;li&gt;Pod 재시작 최소화&lt;/li&gt;
&lt;li&gt;리소스 균형 최적화&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Scheduler 이해 (Pod 스케줄링 원리, Node Selection, Taints/Tolerations)</title><link>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-scheduler-guide/</link><pubDate>Sun, 17 Feb 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-scheduler-guide/</guid><description>&lt;h2 id="-kubernetes-scheduler-이해하기"&gt;
 ☸️ Kubernetes Scheduler 이해하기
 &lt;a class="heading-anchor" href="#-kubernetes-scheduler-%ec%9d%b4%ed%95%b4%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes에서 &lt;strong&gt;Scheduler는 Pod를 어떤 Node에서 실행할지 결정하는 핵심 컴포넌트&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;Scheduler를 이해하면 다음을 알 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod가 Pending 상태로 멈춘 이유&lt;/li&gt;
&lt;li&gt;특정 Node에 Pod를 배치하는 방법&lt;/li&gt;
&lt;li&gt;Taints/Tolerations와 Node Affinity 활용법&lt;/li&gt;
&lt;li&gt;리소스 활용 최적화 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="scheduler-동작-개요"&gt;
 Scheduler 동작 개요
 &lt;a class="heading-anchor" href="#scheduler-%eb%8f%99%ec%9e%91-%ea%b0%9c%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Scheduler는 &lt;strong&gt;Pending 상태 Pod를 감지&lt;/strong&gt;하고 Node를 선택합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pending Pod]

B[Scheduler]

C[Node Selection]

D[Bind Pod to Node]

A --&amp;gt; B
B --&amp;gt; C
C --&amp;gt; D&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="node-selection-과정"&gt;
 Node Selection 과정
 &lt;a class="heading-anchor" href="#node-selection-%ea%b3%bc%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Scheduler는 다음 단계를 거쳐 Node를 선택합니다.&lt;/p&gt;
&lt;p&gt;1️⃣ &lt;strong&gt;Filter&lt;/strong&gt; - 스케줄 가능한 Node 후보 선별
2️⃣ &lt;strong&gt;Score&lt;/strong&gt; - 후보 Node 점수 계산
3️⃣ &lt;strong&gt;Select&lt;/strong&gt; - 최종 Node 선택
4️⃣ &lt;strong&gt;Bind&lt;/strong&gt; - Pod와 Node 연결&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pending Pod]

B[Filter]

C[Score]

D[Select]

E[Bind]

A --&amp;gt; B --&amp;gt; C --&amp;gt; D --&amp;gt; E&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="filter-단계"&gt;
 Filter 단계
 &lt;a class="heading-anchor" href="#filter-%eb%8b%a8%ea%b3%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Filter 단계에서는 다음 조건을 확인합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node 리소스 충분 여부(CPU, Memory)&lt;/li&gt;
&lt;li&gt;Taints/Tolerations 일치 여부&lt;/li&gt;
&lt;li&gt;Node Affinity/Anti-affinity 조건&lt;/li&gt;
&lt;li&gt;Pod Affinity/Anti-affinity 조건&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="score-단계"&gt;
 Score 단계
 &lt;a class="heading-anchor" href="#score-%eb%8b%a8%ea%b3%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Score 단계에서는 후보 Node에 &lt;strong&gt;점수 계산&lt;/strong&gt;을 합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;리소스 사용률 균형&lt;/li&gt;
&lt;li&gt;Pod 배치 최적화&lt;/li&gt;
&lt;li&gt;Node 선호도 반영&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Node1]

B[Node2]

C[Node3]

A --&amp;gt;|score 80| D[Candidate]

B --&amp;gt;|score 95| D

C --&amp;gt;|score 60| D&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="bind-단계"&gt;
 Bind 단계
 &lt;a class="heading-anchor" href="#bind-%eb%8b%a8%ea%b3%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;최종 Node를 선택한 후 Scheduler는 &lt;strong&gt;API Server를 통해 Pod와 Node를 바인딩&lt;/strong&gt;합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Scheduler]

B[Kubernetes API Server]

C[Node]

D[Pod]

A --&amp;gt; B --&amp;gt; C

B --&amp;gt; D&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="taints--tolerations"&gt;
 Taints / Tolerations
 &lt;a class="heading-anchor" href="#taints--tolerations" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Taints&lt;/strong&gt;: Node에 표시, Pod가 배치되지 않도록 함
&lt;strong&gt;Tolerations&lt;/strong&gt;: Pod가 Taint를 허용하도록 설정&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Node with Taint]

B[Pod with Toleration]

A --&amp;gt; B&lt;/pre&gt;
&lt;h3 id="예시"&gt;
 예시
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Node Taint&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="l"&gt;kubectl taint nodes node1 key=value:NoSchedule&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Pod Toleration&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;tolerations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Equal&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;effect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;NoSchedule&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="node-affinity"&gt;
 Node Affinity
 &lt;a class="heading-anchor" href="#node-affinity" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Node Affinity를 통해 특정 Node에 Pod를 배치할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;affinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeAffinity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nodeSelectorTerms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;matchExpressions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kubernetes.io/region&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;In&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;us-east-1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="scheduler-전체-아키텍처"&gt;
 Scheduler 전체 아키텍처
 &lt;a class="heading-anchor" href="#scheduler-%ec%a0%84%ec%b2%b4-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pending Pod]

B[Scheduler]

C[Filter Phase]

D[Score Phase]

E[Select Node]

F[Bind]

G[Node]

A --&amp;gt; B --&amp;gt; C --&amp;gt; D --&amp;gt; E --&amp;gt; F --&amp;gt; G&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="정리"&gt;
 정리
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Scheduler 핵심&lt;/p&gt;
&lt;h3 id="역할"&gt;
 역할
 &lt;a class="heading-anchor" href="#%ec%97%ad%ed%95%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pending Pod 감지&lt;/li&gt;
&lt;li&gt;Node 선택&lt;/li&gt;
&lt;li&gt;Pod 바인딩&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="스케줄링-과정"&gt;
 스케줄링 과정
 &lt;a class="heading-anchor" href="#%ec%8a%a4%ec%bc%80%ec%a4%84%eb%a7%81-%ea%b3%bc%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Filter → Score → Select → Bind&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="고급-기능"&gt;
 고급 기능
 &lt;a class="heading-anchor" href="#%ea%b3%a0%ea%b8%89-%ea%b8%b0%eb%8a%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Taints / Tolerations&lt;/li&gt;
&lt;li&gt;Node Affinity / Anti-affinity&lt;/li&gt;
&lt;li&gt;Resource 기반 스케줄링&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Pod Lifecycle 완벽 정리 (Pod 상태, Restart 정책, Health Check)</title><link>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-pod-lifecycle-guide/</link><pubDate>Fri, 15 Feb 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-pod-lifecycle-guide/</guid><description>&lt;h2 id="-kubernetes-pod-lifecycle-이해하기"&gt;
 ☸️ Kubernetes Pod Lifecycle 이해하기
 &lt;a class="heading-anchor" href="#-kubernetes-pod-lifecycle-%ec%9d%b4%ed%95%b4%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes에서 &lt;strong&gt;Pod는 가장 작은 배포 단위&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;하지만 Pod는 단순히 생성되고 종료되는 것이 아니라 &lt;strong&gt;여러 상태를 거치며 생명주기(Lifecycle)&lt;/strong&gt; 를 가지게 됩니다.&lt;/p&gt;
&lt;p&gt;Pod Lifecycle을 이해하면 다음과 같은 문제를 해결할 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod가 왜 재시작되는지&lt;/li&gt;
&lt;li&gt;Pod가 Pending 상태에서 멈춘 이유&lt;/li&gt;
&lt;li&gt;서비스가 트래픽을 받지 못하는 이유&lt;/li&gt;
&lt;li&gt;Health Check 설정 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="pod-lifecycle-전체-흐름"&gt;
 Pod Lifecycle 전체 흐름
 &lt;a class="heading-anchor" href="#pod-lifecycle-%ec%a0%84%ec%b2%b4-%ed%9d%90%eb%a6%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Pod는 다음과 같은 상태를 거칩니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph LR

A[Pending]

B[Running]

C[Succeeded]

D[Failed]

E[Unknown]

A --&amp;gt; B
B --&amp;gt; C
B --&amp;gt; D
B --&amp;gt; E&lt;/pre&gt;
&lt;hr&gt;
&lt;h1 id="pod-phase"&gt;
 Pod Phase
 &lt;a class="heading-anchor" href="#pod-phase" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Pod 상태는 &lt;strong&gt;Pod Phase&lt;/strong&gt;로 표현됩니다.&lt;/p&gt;
&lt;p&gt;대표적으로 5가지 상태가 있습니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Phase&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Pending&lt;/td&gt;
					&lt;td&gt;Pod가 생성되었지만 실행 준비 중&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Running&lt;/td&gt;
					&lt;td&gt;Pod가 정상 실행 중&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Succeeded&lt;/td&gt;
					&lt;td&gt;작업이 성공적으로 완료&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Failed&lt;/td&gt;
					&lt;td&gt;실행 실패&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Unknown&lt;/td&gt;
					&lt;td&gt;상태 확인 불가&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id="pending-상태"&gt;
 Pending 상태
 &lt;a class="heading-anchor" href="#pending-%ec%83%81%ed%83%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Pod가 생성되었지만 아직 실행되지 않은 상태입니다.&lt;/p&gt;
&lt;p&gt;주요 원인&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node 스케줄링 실패&lt;/li&gt;
&lt;li&gt;이미지 다운로드 중&lt;/li&gt;
&lt;li&gt;볼륨 마운트 문제&lt;/li&gt;
&lt;li&gt;리소스 부족&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;구조&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod Created]

B[Scheduler]

C[Node Assigned]

D[Image Pull]

A --&amp;gt; B
B --&amp;gt; C
C --&amp;gt; D&lt;/pre&gt;
&lt;hr&gt;
&lt;h1 id="running-상태"&gt;
 Running 상태
 &lt;a class="heading-anchor" href="#running-%ec%83%81%ed%83%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Pod가 정상적으로 실행되고 있는 상태입니다.&lt;/p&gt;
&lt;p&gt;조건&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;최소 하나의 컨테이너가 실행 중&lt;/li&gt;
&lt;li&gt;컨테이너 프로세스가 정상 작동&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod]

B[Container]

C[Application Process]

A --&amp;gt; B
B --&amp;gt; C&lt;/pre&gt;
&lt;hr&gt;
&lt;h1 id="succeeded-상태"&gt;
 Succeeded 상태
 &lt;a class="heading-anchor" href="#succeeded-%ec%83%81%ed%83%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Pod의 작업이 정상적으로 완료된 상태입니다.&lt;/p&gt;
&lt;p&gt;주로 &lt;strong&gt;Batch 작업&lt;/strong&gt;에서 발생합니다.&lt;/p&gt;
&lt;p&gt;예&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;데이터 처리&lt;/li&gt;
&lt;li&gt;ETL 작업&lt;/li&gt;
&lt;li&gt;CronJob&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="failed-상태"&gt;
 Failed 상태
 &lt;a class="heading-anchor" href="#failed-%ec%83%81%ed%83%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;컨테이너가 오류로 종료된 경우입니다.&lt;/p&gt;
&lt;p&gt;대표적인 원인&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;애플리케이션 오류&lt;/li&gt;
&lt;li&gt;메모리 부족(OOM)&lt;/li&gt;
&lt;li&gt;CrashLoop&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id="pod-상태-확인"&gt;
 Pod 상태 확인
 &lt;a class="heading-anchor" href="#pod-%ec%83%81%ed%83%9c-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Pod 상태는 다음 명령어로 확인할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl get pods&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;예시&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;NAME READY STATUS RESTARTS
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;web-pod 1/1 Running &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;batch-job 0/1 Completed &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;api-pod 0/1 CrashLoopBackOff &lt;span class="m"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="restart-policy"&gt;
 Restart Policy
 &lt;a class="heading-anchor" href="#restart-policy" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Pod는 컨테이너가 종료되면 &lt;strong&gt;Restart Policy&lt;/strong&gt;에 따라 재시작됩니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Policy&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Always&lt;/td&gt;
					&lt;td&gt;항상 재시작&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;OnFailure&lt;/td&gt;
					&lt;td&gt;실패 시 재시작&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Never&lt;/td&gt;
					&lt;td&gt;재시작하지 않음&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="restart-구조"&gt;
 Restart 구조
 &lt;a class="heading-anchor" href="#restart-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Container Crash]

B[Restart Policy]

C[Restart Container]

D[Stop]

A --&amp;gt; B
B --&amp;gt; C
B --&amp;gt; D&lt;/pre&gt;
&lt;hr&gt;
&lt;h1 id="liveness-probe"&gt;
 Liveness Probe
 &lt;a class="heading-anchor" href="#liveness-probe" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Liveness Probe는 &lt;strong&gt;컨테이너가 살아있는지 확인&lt;/strong&gt;하는 기능입니다.&lt;/p&gt;
&lt;p&gt;애플리케이션이 &lt;strong&gt;deadlock 상태&lt;/strong&gt;가 되면 자동으로 재시작합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="liveness-구조"&gt;
 Liveness 구조
 &lt;a class="heading-anchor" href="#liveness-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Kubelet]

B[Liveness Probe]

C[Container]

D[Restart]

A --&amp;gt; B
B --&amp;gt; C
C --&amp;gt; D&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="liveness-probe-예시"&gt;
 Liveness Probe 예시
 &lt;a class="heading-anchor" href="#liveness-probe-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;livenessProbe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;httpGet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/health&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;periodSeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="readiness-probe"&gt;
 Readiness Probe
 &lt;a class="heading-anchor" href="#readiness-probe" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Readiness Probe는 &lt;strong&gt;Pod가 트래픽을 받을 준비가 되었는지 확인&lt;/strong&gt;합니다.&lt;/p&gt;
&lt;p&gt;준비되지 않은 경우 Service에서 제외됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="readiness-구조"&gt;
 Readiness 구조
 &lt;a class="heading-anchor" href="#readiness-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Service]

B[Readiness Probe]

C[Pod]

A --&amp;gt; B
B --&amp;gt; C&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="readiness-probe-예시"&gt;
 Readiness Probe 예시
 &lt;a class="heading-anchor" href="#readiness-probe-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;readinessProbe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;httpGet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/ready&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;periodSeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id="liveness-vs-readiness"&gt;
 Liveness vs Readiness
 &lt;a class="heading-anchor" href="#liveness-vs-readiness" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;두 Probe는 목적이 다릅니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Probe&lt;/th&gt;
					&lt;th&gt;역할&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Liveness&lt;/td&gt;
					&lt;td&gt;컨테이너 재시작&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Readiness&lt;/td&gt;
					&lt;td&gt;트래픽 제어&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="probe-구조"&gt;
 Probe 구조
 &lt;a class="heading-anchor" href="#probe-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod]

B[Liveness Probe]

C[Readiness Probe]

D[Restart]

E[Service Traffic]

A --&amp;gt; B
A --&amp;gt; C

B --&amp;gt; D
C --&amp;gt; E&lt;/pre&gt;
&lt;hr&gt;
&lt;h1 id="pod-lifecycle-전체-아키텍처"&gt;
 Pod Lifecycle 전체 아키텍처
 &lt;a class="heading-anchor" href="#pod-lifecycle-%ec%a0%84%ec%b2%b4-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod Created]

B[Scheduler]

C[Node Assigned]

D[Container Start]

E[Running]

F[Liveness Probe]

G[Readiness Probe]

H[Restart]

A --&amp;gt; B
B --&amp;gt; C
C --&amp;gt; D
D --&amp;gt; E

E --&amp;gt; F
E --&amp;gt; G

F --&amp;gt; H&lt;/pre&gt;
&lt;hr&gt;
&lt;h1 id="정리"&gt;
 정리
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Pod Lifecycle 핵심&lt;/p&gt;
&lt;h3 id="pod-phase-1"&gt;
 Pod Phase
 &lt;a class="heading-anchor" href="#pod-phase-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pending&lt;/li&gt;
&lt;li&gt;Running&lt;/li&gt;
&lt;li&gt;Succeeded&lt;/li&gt;
&lt;li&gt;Failed&lt;/li&gt;
&lt;li&gt;Unknown&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="restart-policy-1"&gt;
 Restart Policy
 &lt;a class="heading-anchor" href="#restart-policy-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Always&lt;/li&gt;
&lt;li&gt;OnFailure&lt;/li&gt;
&lt;li&gt;Never&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="health-check"&gt;
 Health Check
 &lt;a class="heading-anchor" href="#health-check" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Liveness Probe&lt;/li&gt;
&lt;li&gt;Readiness Probe&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Persistent Volume(PV)과 PVC 완벽 이해 (Kubernetes Storage)</title><link>https://kyungryeol-yoon.github.io/kubernetes/storage/kubernetes-pv-pvc-storage-guide/</link><pubDate>Tue, 12 Feb 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/storage/kubernetes-pv-pvc-storage-guide/</guid><description>&lt;h2 id="-kubernetes-storage-이해하기"&gt;
 ☸️ Kubernetes Storage 이해하기
 &lt;a class="heading-anchor" href="#-kubernetes-storage-%ec%9d%b4%ed%95%b4%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;컨테이너 기반 애플리케이션을 운영할 때 가장 많이 발생하는 문제 중 하나는 &lt;strong&gt;데이터 저장(Storage)&lt;/strong&gt; 입니다.&lt;/p&gt;
&lt;p&gt;컨테이너는 기본적으로 &lt;strong&gt;Ephemeral Storage(휘발성 스토리지)&lt;/strong&gt; 를 사용합니다.&lt;/p&gt;
&lt;p&gt;즉 컨테이너가 종료되면 데이터도 함께 사라집니다.&lt;/p&gt;
&lt;p&gt;예를 들어 다음과 같은 경우 문제가 발생합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;데이터베이스&lt;/li&gt;
&lt;li&gt;로그 파일&lt;/li&gt;
&lt;li&gt;업로드 파일&lt;/li&gt;
&lt;li&gt;캐시 데이터&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 문제를 해결하기 위해 Kubernetes에서는 &lt;strong&gt;Persistent Volume(PV)&lt;/strong&gt; 과 &lt;strong&gt;Persistent Volume Claim(PVC)&lt;/strong&gt; 을 제공합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="kubernetes-storage-구조"&gt;
 Kubernetes Storage 구조
 &lt;a class="heading-anchor" href="#kubernetes-storage-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes 스토리지 구조는 다음과 같이 동작합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Storage Backend]

B[Persistent Volume]

C[Persistent Volume Claim]

D[Pod]

A --&amp;gt; B
B --&amp;gt; C
C --&amp;gt; D&lt;/pre&gt;
&lt;p&gt;즉 흐름은 다음과 같습니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Storage
 → PV
 → PVC
 → Pod&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="persistent-volume-pv"&gt;
 Persistent Volume (PV)
 &lt;a class="heading-anchor" href="#persistent-volume-pv" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Persistent Volume은 &lt;strong&gt;클러스터에서 사용할 수 있는 스토리지 리소스&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;예를 들어 다음과 같은 스토리지를 사용할 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AWS EBS&lt;/li&gt;
&lt;li&gt;GCP Persistent Disk&lt;/li&gt;
&lt;li&gt;NFS&lt;/li&gt;
&lt;li&gt;Ceph&lt;/li&gt;
&lt;li&gt;Local Disk&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;PV는 &lt;strong&gt;Cluster 관리자가 생성&lt;/strong&gt;합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="pv-구조"&gt;
 PV 구조
 &lt;a class="heading-anchor" href="#pv-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Storage System]

A --&amp;gt; B[Persistent Volume]

B --&amp;gt; C[Kubernetes Cluster]&lt;/pre&gt;
&lt;p&gt;PV는 실제 스토리지를 Kubernetes에서 사용할 수 있도록 &lt;strong&gt;추상화한 리소스&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="pv-yaml-예시"&gt;
 PV YAML 예시
 &lt;a class="heading-anchor" href="#pv-yaml-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PersistentVolume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pv-example&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteOnce&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/data/storage&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;주요 필드&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Field&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;capacity&lt;/td&gt;
					&lt;td&gt;스토리지 크기&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;accessModes&lt;/td&gt;
					&lt;td&gt;접근 방식&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;hostPath&lt;/td&gt;
					&lt;td&gt;로컬 디스크 경로&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="persistent-volume-claim-pvc"&gt;
 Persistent Volume Claim (PVC)
 &lt;a class="heading-anchor" href="#persistent-volume-claim-pvc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;PVC는 &lt;strong&gt;사용자가 요청하는 스토리지 리소스&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;Pod는 PV를 직접 사용하는 것이 아니라 &lt;strong&gt;PVC를 통해 스토리지를 요청합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="pvc-구조"&gt;
 PVC 구조
 &lt;a class="heading-anchor" href="#pvc-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Persistent Volume]

B[Persistent Volume Claim]

C[Pod]

A --&amp;gt; B
B --&amp;gt; C&lt;/pre&gt;
&lt;p&gt;PVC는 다음 정보를 요청합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;스토리지 크기&lt;/li&gt;
&lt;li&gt;access mode&lt;/li&gt;
&lt;li&gt;storage class&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="pvc-yaml-예시"&gt;
 PVC YAML 예시
 &lt;a class="heading-anchor" href="#pvc-yaml-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PersistentVolumeClaim&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pvc-example&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;accessModes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ReadWriteOnce&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;5Gi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이 PVC가 생성되면 Kubernetes는 &lt;strong&gt;조건에 맞는 PV를 자동으로 연결합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="pod에서-pvc-사용"&gt;
 Pod에서 PVC 사용
 &lt;a class="heading-anchor" href="#pod%ec%97%90%ec%84%9c-pvc-%ec%82%ac%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Pod는 Volume을 통해 PVC를 사용합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod]

B[Volume]

C[PVC]

D[PV]

A --&amp;gt; B
B --&amp;gt; C
C --&amp;gt; D&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="pod-yaml-예시"&gt;
 Pod YAML 예시
 &lt;a class="heading-anchor" href="#pod-yaml-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;storage-pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;mountPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/data&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;storage-volume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;storage-volume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;persistentVolumeClaim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;claimName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pvc-example&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이렇게 하면 &lt;code&gt;/data&lt;/code&gt; 경로에 스토리지가 마운트됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="access-mode"&gt;
 Access Mode
 &lt;a class="heading-anchor" href="#access-mode" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;PV는 여러 접근 방식을 지원합니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Mode&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;ReadWriteOnce&lt;/td&gt;
					&lt;td&gt;하나의 Node에서 읽기/쓰기&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ReadOnlyMany&lt;/td&gt;
					&lt;td&gt;여러 Node에서 읽기&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ReadWriteMany&lt;/td&gt;
					&lt;td&gt;여러 Node에서 읽기/쓰기&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="storageclass"&gt;
 StorageClass
 &lt;a class="heading-anchor" href="#storageclass" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;StorageClass는 &lt;strong&gt;동적 스토리지 생성 기능&lt;/strong&gt;을 제공합니다.&lt;/p&gt;
&lt;p&gt;기존 방식&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;관리자 → PV 생성
사용자 → PVC 요청&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;StorageClass를 사용하면&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;PVC 생성
→ 자동으로 PV 생성&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="storageclass-구조"&gt;
 StorageClass 구조
 &lt;a class="heading-anchor" href="#storageclass-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[StorageClass]

B[PVC]

C[Dynamic PV]

D[Pod]

A --&amp;gt; B
B --&amp;gt; C
C --&amp;gt; D&lt;/pre&gt;
&lt;p&gt;즉 스토리지가 &lt;strong&gt;자동으로 프로비저닝&lt;/strong&gt;됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="kubernetes-storage-전체-구조"&gt;
 Kubernetes Storage 전체 구조
 &lt;a class="heading-anchor" href="#kubernetes-storage-%ec%a0%84%ec%b2%b4-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Storage Backend]

B[StorageClass]

C[Persistent Volume]

D[Persistent Volume Claim]

E[Pod]

A --&amp;gt; C
B --&amp;gt; C
C --&amp;gt; D
D --&amp;gt; E&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="정리"&gt;
 정리
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes Storage 핵심&lt;/p&gt;
&lt;h3 id="pv"&gt;
 PV
 &lt;a class="heading-anchor" href="#pv" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;클러스터 스토리지 리소스&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="pvc"&gt;
 PVC
 &lt;a class="heading-anchor" href="#pvc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;사용자 스토리지 요청&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="storageclass-1"&gt;
 StorageClass
 &lt;a class="heading-anchor" href="#storageclass-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;동적 스토리지 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="pod"&gt;
 Pod
 &lt;a class="heading-anchor" href="#pod" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Volume을 통해 스토리지 사용&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] ConfigMap과 Secret 완벽 이해 (환경변수, 설정 관리)</title><link>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-configmap-secret-guide/</link><pubDate>Mon, 11 Feb 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-configmap-secret-guide/</guid><description>&lt;h2 id="-kubernetes-configmap--secret-이해하기"&gt;
 ☸️ Kubernetes ConfigMap &amp;amp; Secret 이해하기
 &lt;a class="heading-anchor" href="#-kubernetes-configmap--secret-%ec%9d%b4%ed%95%b4%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;컨테이너 기반 애플리케이션을 운영하다 보면&lt;br&gt;
애플리케이션 코드와 **설정(Configuration)**을 분리해야 하는 상황이 자주 발생합니다.&lt;/p&gt;
&lt;p&gt;예를 들어 다음과 같은 설정들이 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;데이터베이스 주소&lt;/li&gt;
&lt;li&gt;API Endpoint&lt;/li&gt;
&lt;li&gt;환경 변수&lt;/li&gt;
&lt;li&gt;인증 키&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이러한 설정을 이미지에 포함시키면 문제가 발생합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;환경별 설정 관리 어려움&lt;/li&gt;
&lt;li&gt;이미지 재빌드 필요&lt;/li&gt;
&lt;li&gt;보안 문제 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kubernetes에서는 이 문제를 해결하기 위해 &lt;strong&gt;ConfigMap&lt;/strong&gt;과 &lt;strong&gt;Secret&lt;/strong&gt;을 제공합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="kubernetes-설정-관리-구조"&gt;
 Kubernetes 설정 관리 구조
 &lt;a class="heading-anchor" href="#kubernetes-%ec%84%a4%ec%a0%95-%ea%b4%80%eb%a6%ac-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;ConfigMap과 Secret은 &lt;strong&gt;Pod 외부에서 설정을 관리하는 리소스&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[ConfigMap]
B[Secret]

A --&amp;gt; C[Pod]
B --&amp;gt; C&lt;/pre&gt;
&lt;p&gt;Pod는 실행될 때 ConfigMap과 Secret 값을 &lt;strong&gt;주입받아 사용&lt;/strong&gt;합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="configmap"&gt;
 ConfigMap
 &lt;a class="heading-anchor" href="#configmap" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;ConfigMap은 &lt;strong&gt;일반적인 설정 데이터를 저장하는 Kubernetes 리소스&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;예를 들어&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;환경 변수&lt;/li&gt;
&lt;li&gt;설정 파일&lt;/li&gt;
&lt;li&gt;application.yml&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;등을 저장할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="configmap-생성-방법"&gt;
 ConfigMap 생성 방법
 &lt;a class="heading-anchor" href="#configmap-%ec%83%9d%ec%84%b1-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="cli-방식"&gt;
 CLI 방식
 &lt;a class="heading-anchor" href="#cli-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create configmap app-config &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; --from-literal&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;APP_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="yaml-방식"&gt;
 YAML 방식
 &lt;a class="heading-anchor" href="#yaml-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ConfigMap&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;APP_ENV&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;production&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;LOG_LEVEL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;info&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="configmap-사용-방법"&gt;
 ConfigMap 사용 방법
 &lt;a class="heading-anchor" href="#configmap-%ec%82%ac%ec%9a%a9-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;ConfigMap은 Pod에서 다음 방식으로 사용할 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;환경 변수&lt;/li&gt;
&lt;li&gt;파일 마운트&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="환경-변수로-사용"&gt;
 환경 변수로 사용
 &lt;a class="heading-anchor" href="#%ed%99%98%ea%b2%bd-%eb%b3%80%ec%88%98%eb%a1%9c-%ec%82%ac%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;example-pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;APP_ENV&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;valueFrom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configMapKeyRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;APP_ENV&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pod 실행 시 다음 환경 변수가 생성됩니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;APP_ENV=production&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="configmap-파일-마운트"&gt;
 ConfigMap 파일 마운트
 &lt;a class="heading-anchor" href="#configmap-%ed%8c%8c%ec%9d%bc-%eb%a7%88%ec%9a%b4%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;ConfigMap을 &lt;strong&gt;파일 형태로 마운트&lt;/strong&gt;할 수도 있습니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[ConfigMap]

A --&amp;gt; B[Volume]

B --&amp;gt; C[Pod Container]&lt;/pre&gt;
&lt;p&gt;YAML 예시&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;config-volume&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app-config&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="secret"&gt;
 Secret
 &lt;a class="heading-anchor" href="#secret" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Secret은 &lt;strong&gt;민감한 정보를 저장하는 Kubernetes 리소스&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;대표적인 예&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DB Password&lt;/li&gt;
&lt;li&gt;API Key&lt;/li&gt;
&lt;li&gt;TLS Certificate&lt;/li&gt;
&lt;li&gt;OAuth Token&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="configmap-vs-secret-차이"&gt;
 ConfigMap vs Secret 차이
 &lt;a class="heading-anchor" href="#configmap-vs-secret-%ec%b0%a8%ec%9d%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;ConfigMap&lt;/th&gt;
					&lt;th&gt;Secret&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;데이터&lt;/td&gt;
					&lt;td&gt;일반 설정&lt;/td&gt;
					&lt;td&gt;민감 정보&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;인코딩&lt;/td&gt;
					&lt;td&gt;평문&lt;/td&gt;
					&lt;td&gt;Base64&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;보안&lt;/td&gt;
					&lt;td&gt;낮음&lt;/td&gt;
					&lt;td&gt;상대적으로 높음&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="secret-생성-방법"&gt;
 Secret 생성 방법
 &lt;a class="heading-anchor" href="#secret-%ec%83%9d%ec%84%b1-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="cli-방식-1"&gt;
 CLI 방식
 &lt;a class="heading-anchor" href="#cli-%eb%b0%a9%ec%8b%9d-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;kubectl create secret generic db-secret &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; --from-literal&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mysecretpassword&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="yaml-방식-1"&gt;
 YAML 방식
 &lt;a class="heading-anchor" href="#yaml-%eb%b0%a9%ec%8b%9d-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Secret은 &lt;strong&gt;Base64 인코딩&lt;/strong&gt;을 사용합니다.&lt;/p&gt;
&lt;p&gt;예시&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -n &lt;span class="s2"&gt;&amp;#34;mypassword&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; base64&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;결과&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;bXlwYXNzd29yZA==&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;YAML 예시&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Secret&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;db-secret&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Opaque&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;bXlwYXNzd29yZA==&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="secret-사용-방법"&gt;
 Secret 사용 방법
 &lt;a class="heading-anchor" href="#secret-%ec%82%ac%ec%9a%a9-%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Secret도 ConfigMap과 동일하게 Pod에 주입할 수 있습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;valueFrom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secretKeyRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;db-secret&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;password&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="secret-파일-마운트"&gt;
 Secret 파일 마운트
 &lt;a class="heading-anchor" href="#secret-%ed%8c%8c%ec%9d%bc-%eb%a7%88%ec%9a%b4%ed%8a%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Secret을 파일 형태로도 사용할 수 있습니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Secret]

A --&amp;gt; B[Volume]

B --&amp;gt; C[Pod Container]&lt;/pre&gt;
&lt;p&gt;대표적인 사용 사례&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TLS 인증서&lt;/li&gt;
&lt;li&gt;SSH Key&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="kubernetes-설정-관리-흐름"&gt;
 Kubernetes 설정 관리 흐름
 &lt;a class="heading-anchor" href="#kubernetes-%ec%84%a4%ec%a0%95-%ea%b4%80%eb%a6%ac-%ed%9d%90%eb%a6%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;전체 구조는 다음과 같습니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[ConfigMap]
B[Secret]

A --&amp;gt; C[Pod]
B --&amp;gt; C

C --&amp;gt; D[Application]&lt;/pre&gt;
&lt;p&gt;즉 애플리케이션은 &lt;strong&gt;Pod 환경 변수나 파일을 통해 설정을 읽습니다.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="정리"&gt;
 정리
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes 설정 관리 핵심&lt;/p&gt;
&lt;h3 id="configmap-1"&gt;
 ConfigMap
 &lt;a class="heading-anchor" href="#configmap-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;일반 설정 데이터 저장&lt;/li&gt;
&lt;li&gt;환경 변수 / 파일 형태 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="secret-1"&gt;
 Secret
 &lt;a class="heading-anchor" href="#secret-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;민감 정보 저장&lt;/li&gt;
&lt;li&gt;Base64 인코딩 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용-목적"&gt;
 사용 목적
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9-%eb%aa%a9%ec%a0%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;애플리케이션 설정 분리&lt;/li&gt;
&lt;li&gt;보안 관리&lt;/li&gt;
&lt;li&gt;환경별 설정 관리&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Ingress 완벽 가이드 (Ingress Controller, HTTP Routing)</title><link>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-ingress-complete-guide/</link><pubDate>Thu, 07 Feb 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-ingress-complete-guide/</guid><description>&lt;h2 id="-kubernetes-ingress-이해하기"&gt;
 ☸️ Kubernetes Ingress 이해하기
 &lt;a class="heading-anchor" href="#-kubernetes-ingress-%ec%9d%b4%ed%95%b4%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;이전 글에서는 Kubernetes Service와 Networking 구조를 살펴봤습니다.&lt;/p&gt;
&lt;p&gt;Service를 사용하면 Pod에 접근할 수 있지만&lt;br&gt;
외부 트래픽을 처리하기에는 몇 가지 한계가 있습니다.&lt;/p&gt;
&lt;p&gt;예를 들어&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;여러 서비스에 대해 &lt;strong&gt;HTTP 라우팅&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;도메인 기반 접근&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTPS/TLS 처리&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이런 기능은 Service만으로는 처리하기 어렵습니다.&lt;/p&gt;
&lt;p&gt;이 문제를 해결하는 것이 &lt;strong&gt;Ingress&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="kubernetes-외부-트래픽-흐름"&gt;
 Kubernetes 외부 트래픽 흐름
 &lt;a class="heading-anchor" href="#kubernetes-%ec%99%b8%eb%b6%80-%ed%8a%b8%eb%9e%98%ed%94%bd-%ed%9d%90%eb%a6%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;외부에서 Kubernetes 서비스로 접근하는 기본 흐름은 다음과 같습니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[User]

A --&amp;gt; B[LoadBalancer]

B --&amp;gt; C[Service]

C --&amp;gt; D[Pod]
C --&amp;gt; E[Pod]&lt;/pre&gt;
&lt;p&gt;하지만 서비스가 여러 개라면 문제가 생깁니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;서비스마다 LoadBalancer 필요&lt;/li&gt;
&lt;li&gt;비용 증가&lt;/li&gt;
&lt;li&gt;관리 복잡&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이를 해결하기 위해 &lt;strong&gt;Ingress&lt;/strong&gt;가 등장합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="ingress-개념"&gt;
 Ingress 개념
 &lt;a class="heading-anchor" href="#ingress-%ea%b0%9c%eb%85%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Ingress는 &lt;strong&gt;외부 HTTP/HTTPS 트래픽을 내부 서비스로 라우팅하는 리소스&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[User]

A --&amp;gt; B[Ingress]

B --&amp;gt; C[Service A]
B --&amp;gt; D[Service B]

C --&amp;gt; E[Pod]
D --&amp;gt; F[Pod]&lt;/pre&gt;
&lt;p&gt;즉 Ingress는 &lt;strong&gt;HTTP 라우터 역할&lt;/strong&gt;을 합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="ingress-주요-기능"&gt;
 Ingress 주요 기능
 &lt;a class="heading-anchor" href="#ingress-%ec%a3%bc%ec%9a%94-%ea%b8%b0%eb%8a%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Ingress는 다음 기능을 제공합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTTP Routing&lt;/li&gt;
&lt;li&gt;Domain 기반 Routing&lt;/li&gt;
&lt;li&gt;TLS / HTTPS 지원&lt;/li&gt;
&lt;li&gt;Load Balancing&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="host-기반-routing"&gt;
 Host 기반 Routing
 &lt;a class="heading-anchor" href="#host-%ea%b8%b0%eb%b0%98-routing" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;도메인에 따라 서비스로 트래픽을 분리할 수 있습니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[User]

A --&amp;gt; B[Ingress]

B --&amp;gt; C[api.example.com]

B --&amp;gt; D[web.example.com]

C --&amp;gt; E[Service API]

D --&amp;gt; F[Service Web]&lt;/pre&gt;
&lt;p&gt;예시&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;api.example.com → API Service
web.example.com → Web Service&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="path-기반-routing"&gt;
 Path 기반 Routing
 &lt;a class="heading-anchor" href="#path-%ea%b8%b0%eb%b0%98-routing" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;URL 경로에 따라 서비스 분리도 가능합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[User]

A --&amp;gt; B[Ingress]

B --&amp;gt; C[/api]

B --&amp;gt; D[/web]

C --&amp;gt; E[API Service]

D --&amp;gt; F[Web Service]&lt;/pre&gt;
&lt;p&gt;예시&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;example.com/api → API Service
example.com/web → Web Service&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="ingress-controller"&gt;
 Ingress Controller
 &lt;a class="heading-anchor" href="#ingress-controller" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;중요한 점은 &lt;strong&gt;Ingress는 실제 트래픽을 처리하지 않는다는 것&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;Ingress는 &lt;strong&gt;설정 정보만 가진 리소스&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;실제 트래픽 처리는 &lt;strong&gt;Ingress Controller&lt;/strong&gt;가 수행합니다.&lt;/p&gt;
&lt;p&gt;대표적인 Controller&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nginx Ingress Controller&lt;/li&gt;
&lt;li&gt;Traefik&lt;/li&gt;
&lt;li&gt;HAProxy&lt;/li&gt;
&lt;li&gt;Kong&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="ingress-controller-아키텍처"&gt;
 Ingress Controller 아키텍처
 &lt;a class="heading-anchor" href="#ingress-controller-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[User]

A --&amp;gt; B[LoadBalancer]

B --&amp;gt; C[Ingress Controller]

C --&amp;gt; D[Service A]
C --&amp;gt; E[Service B]

D --&amp;gt; F[Pod]
E --&amp;gt; G[Pod]&lt;/pre&gt;
&lt;p&gt;즉 전체 흐름은 다음과 같습니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;User
 → LoadBalancer
 → Ingress Controller
 → Service
 → Pod&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="ingress-yaml-예시"&gt;
 Ingress YAML 예시
 &lt;a class="heading-anchor" href="#ingress-yaml-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;networking.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Ingress&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;example-ingress&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;example.com&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/api&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pathType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Prefix&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;backend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;api-service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이 설정은 다음 의미를 가집니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;example.com/api → api-service&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="tls--https-설정"&gt;
 TLS / HTTPS 설정
 &lt;a class="heading-anchor" href="#tls--https-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Ingress는 TLS 인증서를 통해 HTTPS를 지원합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[User HTTPS]

A --&amp;gt; B[Ingress TLS]

B --&amp;gt; C[Service]

C --&amp;gt; D[Pod]&lt;/pre&gt;
&lt;p&gt;YAML 예시&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;example.com&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secretName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tls-secret&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="ingress를-사용하는-이유"&gt;
 Ingress를 사용하는 이유
 &lt;a class="heading-anchor" href="#ingress%eb%a5%bc-%ec%82%ac%ec%9a%a9%ed%95%98%eb%8a%94-%ec%9d%b4%ec%9c%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Ingress의 장점&lt;/p&gt;
&lt;h3 id="1-비용-절감"&gt;
 1️⃣ 비용 절감
 &lt;a class="heading-anchor" href="#1-%eb%b9%84%ec%9a%a9-%ec%a0%88%ea%b0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;LoadBalancer를 서비스마다 만들 필요 없음&lt;/p&gt;
&lt;h3 id="2-중앙-라우팅"&gt;
 2️⃣ 중앙 라우팅
 &lt;a class="heading-anchor" href="#2-%ec%a4%91%ec%95%99-%eb%9d%bc%ec%9a%b0%ed%8c%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;모든 HTTP 트래픽을 한 곳에서 관리&lt;/p&gt;
&lt;h3 id="3-https-처리"&gt;
 3️⃣ HTTPS 처리
 &lt;a class="heading-anchor" href="#3-https-%ec%b2%98%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;TLS 인증서 관리 가능&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="정리"&gt;
 정리
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes Networking 구조&lt;/p&gt;
&lt;h3 id="service"&gt;
 Service
 &lt;a class="heading-anchor" href="#service" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pod 접근 엔드포인트&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ingress"&gt;
 Ingress
 &lt;a class="heading-anchor" href="#ingress" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;HTTP/HTTPS 라우팅&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ingress-controller-1"&gt;
 Ingress Controller
 &lt;a class="heading-anchor" href="#ingress-controller-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;실제 트래픽 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="전체-트래픽-흐름"&gt;
 전체 트래픽 흐름
 &lt;a class="heading-anchor" href="#%ec%a0%84%ec%b2%b4-%ed%8a%b8%eb%9e%98%ed%94%bd-%ed%9d%90%eb%a6%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[User]

A --&amp;gt; B[LoadBalancer]

B --&amp;gt; C[Ingress Controller]

C --&amp;gt; D[Service]

D --&amp;gt; E[Pod]&lt;/pre&gt;</description></item><item><title>[Kubernetes] Service와 Networking 구조 이해하기 (ClusterIP, NodePort, LoadBalancer)</title><link>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-service-networking-guide/</link><pubDate>Sun, 03 Feb 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/networking/kubernetes-service-networking-guide/</guid><description>&lt;h2 id="-kubernetes-service--networking-이해하기"&gt;
 ☸️ Kubernetes Service &amp;amp; Networking 이해하기
 &lt;a class="heading-anchor" href="#-kubernetes-service--networking-%ec%9d%b4%ed%95%b4%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes에서 Pod는 애플리케이션을 실행하는 가장 작은 단위입니다.&lt;/p&gt;
&lt;p&gt;하지만 Pod에는 한 가지 문제가 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pod는 생성되고 삭제될 때마다 IP가 변경됩니다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;즉 Pod에 직접 접근하는 방식은 안정적인 서비스 운영에 적합하지 않습니다.&lt;/p&gt;
&lt;p&gt;이 문제를 해결하기 위해 Kubernetes에서는 &lt;strong&gt;Service&lt;/strong&gt;라는 리소스를 제공합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="kubernetes-networking-기본-구조"&gt;
 Kubernetes Networking 기본 구조
 &lt;a class="heading-anchor" href="#kubernetes-networking-%ea%b8%b0%eb%b3%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes 네트워크의 핵심 원칙은 다음과 같습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;모든 Pod는 고유한 IP를 가진다&lt;/li&gt;
&lt;li&gt;Pod 간에는 NAT 없이 통신 가능&lt;/li&gt;
&lt;li&gt;Node가 달라도 Pod 간 통신 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;아키텍처 구조는 다음과 같습니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod - Node1]
B[Pod - Node2]
C[Pod - Node3]

A --&amp;gt; B
B --&amp;gt; C
A --&amp;gt; C&lt;/pre&gt;
&lt;p&gt;즉 Kubernetes에서는 &lt;strong&gt;Pod 간 직접 통신이 가능하도록 네트워크가 구성됩니다.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="service란-무엇인가"&gt;
 Service란 무엇인가
 &lt;a class="heading-anchor" href="#service%eb%9e%80-%eb%ac%b4%ec%97%87%ec%9d%b8%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Service는 &lt;strong&gt;Pod 집합에 대한 안정적인 네트워크 엔드포인트&lt;/strong&gt;를 제공합니다.&lt;/p&gt;
&lt;p&gt;Pod는 계속 변경되지만 Service는 &lt;strong&gt;고정된 접근 지점&lt;/strong&gt; 역할을 합니다.&lt;/p&gt;
&lt;p&gt;구조를 보면 다음과 같습니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Service]

A --&amp;gt; B[Pod]
A --&amp;gt; C[Pod]
A --&amp;gt; D[Pod]&lt;/pre&gt;
&lt;p&gt;Service는 내부적으로 &lt;strong&gt;Pod를 로드밸런싱&lt;/strong&gt;합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="service-동작-방식"&gt;
 Service 동작 방식
 &lt;a class="heading-anchor" href="#service-%eb%8f%99%ec%9e%91-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Service는 &lt;strong&gt;Label Selector&lt;/strong&gt;를 이용해 Pod를 찾습니다.&lt;/p&gt;
&lt;p&gt;예를 들어 다음과 같은 구조입니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Service가 이 label을 기준으로 Pod를 연결합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Service selector: app=nginx]

A --&amp;gt; B[Pod1 app=nginx]
A --&amp;gt; C[Pod2 app=nginx]
A --&amp;gt; D[Pod3 app=nginx]&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="kubernetes-service-종류"&gt;
 Kubernetes Service 종류
 &lt;a class="heading-anchor" href="#kubernetes-service-%ec%a2%85%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes Service는 크게 4가지 타입이 있습니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Type&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;ClusterIP&lt;/td&gt;
					&lt;td&gt;클러스터 내부 접근&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;NodePort&lt;/td&gt;
					&lt;td&gt;Node 포트를 통해 접근&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;LoadBalancer&lt;/td&gt;
					&lt;td&gt;외부 LoadBalancer 사용&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ExternalName&lt;/td&gt;
					&lt;td&gt;외부 DNS 연결&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="clusterip"&gt;
 ClusterIP
 &lt;a class="heading-anchor" href="#clusterip" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;ClusterIP는 &lt;strong&gt;기본 Service 타입&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;클러스터 내부에서만 접근 가능합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Client Pod]

A --&amp;gt; B[ClusterIP Service]

B --&amp;gt; C[Pod]
B --&amp;gt; D[Pod]
B --&amp;gt; E[Pod]&lt;/pre&gt;
&lt;p&gt;특징&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;기본 Service 타입&lt;/li&gt;
&lt;li&gt;내부 통신에 사용&lt;/li&gt;
&lt;li&gt;외부 접근 불가&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="nodeport"&gt;
 NodePort
 &lt;a class="heading-anchor" href="#nodeport" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;NodePort는 Node의 특정 포트를 통해 Service에 접근하는 방식입니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[External User]

A --&amp;gt; B[Node IP:Port]

B --&amp;gt; C[Service]

C --&amp;gt; D[Pod]
C --&amp;gt; E[Pod]&lt;/pre&gt;
&lt;p&gt;예시&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;http://NodeIP:30007&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;특징&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;외부 접근 가능&lt;/li&gt;
&lt;li&gt;테스트 환경에서 자주 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="loadbalancer"&gt;
 LoadBalancer
 &lt;a class="heading-anchor" href="#loadbalancer" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;LoadBalancer 타입은 클라우드 환경에서 많이 사용됩니다.&lt;/p&gt;
&lt;p&gt;클라우드 LoadBalancer가 생성되어 외부 트래픽을 처리합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[User]

A --&amp;gt; B[Cloud LoadBalancer]

B --&amp;gt; C[Service]

C --&amp;gt; D[Pod]
C --&amp;gt; E[Pod]&lt;/pre&gt;
&lt;p&gt;대표 사용 환경&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AWS&lt;/li&gt;
&lt;li&gt;GCP&lt;/li&gt;
&lt;li&gt;Azure&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="service-yaml-예시"&gt;
 Service YAML 예시
 &lt;a class="heading-anchor" href="#service-yaml-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx-service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;targetPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ClusterIP&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;핵심 필드&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Field&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;selector&lt;/td&gt;
					&lt;td&gt;연결할 Pod label&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;port&lt;/td&gt;
					&lt;td&gt;Service 포트&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;targetPort&lt;/td&gt;
					&lt;td&gt;Pod 포트&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;type&lt;/td&gt;
					&lt;td&gt;Service 타입&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="kubernetes-트래픽-흐름"&gt;
 Kubernetes 트래픽 흐름
 &lt;a class="heading-anchor" href="#kubernetes-%ed%8a%b8%eb%9e%98%ed%94%bd-%ed%9d%90%eb%a6%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;외부에서 Kubernetes 애플리케이션으로 접근하는 전체 흐름은 다음과 같습니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[User]

A --&amp;gt; B[LoadBalancer]

B --&amp;gt; C[Service]

C --&amp;gt; D[Pod]
C --&amp;gt; E[Pod]&lt;/pre&gt;
&lt;p&gt;이 구조 덕분에 Kubernetes는 &lt;strong&gt;자동 로드밸런싱과 확장성&lt;/strong&gt;을 제공합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="정리"&gt;
 정리
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes Networking 핵심&lt;/p&gt;
&lt;h3 id="pod"&gt;
 Pod
 &lt;a class="heading-anchor" href="#pod" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;고유 IP 보유&lt;/li&gt;
&lt;li&gt;Pod 간 직접 통신&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="service"&gt;
 Service
 &lt;a class="heading-anchor" href="#service" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pod 접근용 엔드포인트&lt;/li&gt;
&lt;li&gt;로드밸런싱 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="service-타입"&gt;
 Service 타입
 &lt;a class="heading-anchor" href="#service-%ed%83%80%ec%9e%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ClusterIP&lt;/li&gt;
&lt;li&gt;NodePort&lt;/li&gt;
&lt;li&gt;LoadBalancer&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Kubernetes] Controller, ReplicaSet, Deployment 구조 이해하기</title><link>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-controller-replicaset-deployment/</link><pubDate>Fri, 01 Feb 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-controller-replicaset-deployment/</guid><description>&lt;h2 id="-kubernetes-controller-구조-이해하기"&gt;
 ☸️ Kubernetes Controller 구조 이해하기
 &lt;a class="heading-anchor" href="#-kubernetes-controller-%ea%b5%ac%ec%a1%b0-%ec%9d%b4%ed%95%b4%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;이전 글에서는 Kubernetes의 기본 구성요소인&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cluster&lt;/li&gt;
&lt;li&gt;Pod&lt;/li&gt;
&lt;li&gt;Service&lt;/li&gt;
&lt;li&gt;Volume&lt;/li&gt;
&lt;li&gt;Deployment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;등의 개념을 정리했습니다.&lt;/p&gt;
&lt;p&gt;Kubernetes를 조금 더 깊게 이해하려면 &lt;strong&gt;Controller 개념&lt;/strong&gt;을 알아야 합니다.&lt;/p&gt;
&lt;p&gt;Kubernetes의 대부분 기능은 &lt;strong&gt;Controller 패턴&lt;/strong&gt;으로 동작합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="controller란-무엇인가"&gt;
 Controller란 무엇인가
 &lt;a class="heading-anchor" href="#controller%eb%9e%80-%eb%ac%b4%ec%97%87%ec%9d%b8%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Controller는 Kubernetes에서 &lt;strong&gt;클러스터 상태를 원하는 상태(Desired State)로 유지하는 컴포넌트&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;즉 Kubernetes는 다음 방식으로 동작합니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;사용자가 원하는 상태 선언
→ Kubernetes가 실제 상태를 확인
→ 차이가 있으면 자동 수정&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이를 &lt;strong&gt;Reconciliation Loop&lt;/strong&gt;라고 합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="controller-동작-방식"&gt;
 Controller 동작 방식
 &lt;a class="heading-anchor" href="#controller-%eb%8f%99%ec%9e%91-%eb%b0%a9%ec%8b%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Desired State - YAML]

B[Current State]

C[Controller]

A --&amp;gt; C
B --&amp;gt; C

C --&amp;gt; D[Create / Delete / Update Resources]&lt;/pre&gt;
&lt;p&gt;Controller는 다음 작업을 수행합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;리소스 생성&lt;/li&gt;
&lt;li&gt;리소스 삭제&lt;/li&gt;
&lt;li&gt;리소스 업데이트&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="kubernetes-주요-controller"&gt;
 Kubernetes 주요 Controller
 &lt;a class="heading-anchor" href="#kubernetes-%ec%a3%bc%ec%9a%94-controller" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes에는 다양한 Controller가 존재합니다.&lt;/p&gt;
&lt;p&gt;대표적인 Controller는 다음과 같습니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Controller&lt;/th&gt;
					&lt;th&gt;역할&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Deployment&lt;/td&gt;
					&lt;td&gt;Pod 배포 관리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ReplicaSet&lt;/td&gt;
					&lt;td&gt;Pod 개수 유지&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;StatefulSet&lt;/td&gt;
					&lt;td&gt;상태 기반 애플리케이션&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;DaemonSet&lt;/td&gt;
					&lt;td&gt;Node마다 Pod 실행&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Job&lt;/td&gt;
					&lt;td&gt;배치 작업 실행&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="replicaset"&gt;
 ReplicaSet
 &lt;a class="heading-anchor" href="#replicaset" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;ReplicaSet은 &lt;strong&gt;Pod의 개수를 유지하는 Controller&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;예를 들어 다음과 같은 상황을 생각해볼 수 있습니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Pod 3개 실행
→ Pod 1개 장애 발생
→ ReplicaSet이 자동으로 새 Pod 생성&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;즉 ReplicaSet의 역할은&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;항상 지정된 개수의 Pod가 실행되도록 유지하는 것&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="replicaset-아키텍처"&gt;
 ReplicaSet 아키텍처
 &lt;a class="heading-anchor" href="#replicaset-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[ReplicaSet]

A --&amp;gt; B[Pod]
A --&amp;gt; C[Pod]
A --&amp;gt; D[Pod]&lt;/pre&gt;
&lt;p&gt;ReplicaSet이 관리하는 핵심 값은 다음입니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;replicas: 3&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이 값이 유지되도록 Kubernetes가 자동으로 Pod를 생성합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="replicaset-yaml-예시"&gt;
 ReplicaSet YAML 예시
 &lt;a class="heading-anchor" href="#replicaset-yaml-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ReplicaSet&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx-rs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;중요한 부분은 &lt;strong&gt;selector&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;ReplicaSet은 &lt;strong&gt;label을 기준으로 Pod를 관리합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="deployment"&gt;
 Deployment
 &lt;a class="heading-anchor" href="#deployment" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;실제 Kubernetes 환경에서는 ReplicaSet을 직접 사용하는 경우는 많지 않습니다.&lt;/p&gt;
&lt;p&gt;대신 &lt;strong&gt;Deployment&lt;/strong&gt;를 사용합니다.&lt;/p&gt;
&lt;p&gt;Deployment는 다음 기능을 제공합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ReplicaSet 관리&lt;/li&gt;
&lt;li&gt;Rolling Update&lt;/li&gt;
&lt;li&gt;Rollback&lt;/li&gt;
&lt;li&gt;배포 전략 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="deployment-구조"&gt;
 Deployment 구조
 &lt;a class="heading-anchor" href="#deployment-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Deployment]

A --&amp;gt; B[ReplicaSet]

B --&amp;gt; C[Pod]
B --&amp;gt; D[Pod]
B --&amp;gt; E[Pod]&lt;/pre&gt;
&lt;p&gt;즉 구조는 다음과 같습니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Deployment
 ↓
ReplicaSet
 ↓
Pod&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Deployment가 새로운 버전을 배포하면
&lt;strong&gt;새로운 ReplicaSet이 생성됩니다.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="rolling-update-동작-과정"&gt;
 Rolling Update 동작 과정
 &lt;a class="heading-anchor" href="#rolling-update-%eb%8f%99%ec%9e%91-%ea%b3%bc%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Deployment는 기본적으로 &lt;strong&gt;Rolling Update 방식&lt;/strong&gt;을 사용합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph LR

A[Old Pod 1]
B[Old Pod 2]
C[Old Pod 3]

D[New Pod 1]
E[New Pod 2]
F[New Pod 3]

A --&amp;gt; D
B --&amp;gt; E
C --&amp;gt; F&lt;/pre&gt;
&lt;p&gt;업데이트 과정&lt;/p&gt;
&lt;p&gt;1️⃣ 새로운 Pod 생성
2️⃣ 기존 Pod 삭제
3️⃣ 점진적으로 교체&lt;/p&gt;
&lt;p&gt;이 방식 덕분에 &lt;strong&gt;서비스 중단 없이 배포가 가능합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="deployment-yaml-예시"&gt;
 Deployment YAML 예시
 &lt;a class="heading-anchor" href="#deployment-yaml-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx-deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx:1.25&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Deployment를 생성하면 내부적으로&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Deployment
→ ReplicaSet 생성
→ Pod 생성&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이 과정이 자동으로 진행됩니다.&lt;/p&gt;</description></item><item><title>[Kubernetes] ☸️ Pod, Service, Volume, Deployment 핵심 개념 정리</title><link>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-core-concepts-pod-service-deployment/</link><pubDate>Sun, 27 Jan 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/kubernetes/concepts/kubernetes-core-concepts-pod-service-deployment/</guid><description>&lt;blockquote&gt;
&lt;p&gt;이 글에서는 Kubernetes의 핵심 구성 요소인 Pod, Service, Volume, Deployment를 살펴보고, 이를 활용한 대표적인 배포 전략을 다룹니다. Kubernetes 클러스터의 구조와 각 오브젝트의 역할을 명확히 이해하여 실무 운영의 기반을 다질 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="-kubernetes-핵심-개념-정리"&gt;
 🏗️ Kubernetes 핵심 개념 정리
 &lt;a class="heading-anchor" href="#-kubernetes-%ed%95%b5%ec%8b%ac-%ea%b0%9c%eb%85%90-%ec%a0%95%eb%a6%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;쿠버네티스를 처음 접하면 가장 먼저 부딪히는 문제가 &lt;strong&gt;용어의 복잡함&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;Pod, Service, Deployment, ReplicaSet 등 다양한 개념이 등장하면서&lt;br&gt;
전체 구조를 이해하기 어려워지는 경우가 많습니다.&lt;/p&gt;
&lt;p&gt;하지만 Kubernetes는 몇 가지 &lt;strong&gt;핵심 구성요소만 이해하면 전체 구조가 자연스럽게 연결됩니다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;이 글에서는 Kubernetes를 이해하기 위한 가장 기본적인 개념들을 정리합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-kubernetes-cluster-구조"&gt;
 🏢 Kubernetes Cluster 구조
 &lt;a class="heading-anchor" href="#-kubernetes-cluster-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes는 &lt;strong&gt;Cluster 구조&lt;/strong&gt;로 동작합니다.&lt;/p&gt;
&lt;p&gt;클러스터는 크게 두 가지 영역으로 나뉩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Control Plane (Master)&lt;/li&gt;
&lt;li&gt;Worker Node&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Kubernetes Cluster]

A --&amp;gt; B[Control Plane]
A --&amp;gt; C[Worker Node 1]
A --&amp;gt; D[Worker Node 2]

B --&amp;gt; E[API Server]
B --&amp;gt; F[Scheduler]
B --&amp;gt; G[Controller Manager]
B --&amp;gt; H[etcd]

C --&amp;gt; I[Pod]
C --&amp;gt; J[Pod]

D --&amp;gt; K[Pod]&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="-control-plane-master"&gt;
 🧠 Control Plane (Master)
 &lt;a class="heading-anchor" href="#-control-plane-master" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Control Plane은 클러스터 전체를 관리하는 영역입니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Control Plane]

A --&amp;gt; B[API Server]
A --&amp;gt; C[Scheduler]
A --&amp;gt; D[Controller Manager]
A --&amp;gt; E[etcd]&lt;/pre&gt;
&lt;p&gt;주요 역할은 다음과 같습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;클러스터 상태 관리&lt;/li&gt;
&lt;li&gt;스케줄링&lt;/li&gt;
&lt;li&gt;API 제공&lt;/li&gt;
&lt;li&gt;컨테이너 배치 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;대표적인 컴포넌트&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Component&lt;/th&gt;
					&lt;th&gt;역할&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;API Server&lt;/td&gt;
					&lt;td&gt;Kubernetes API 제공&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Scheduler&lt;/td&gt;
					&lt;td&gt;Pod를 어느 Node에 배치할지 결정&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Controller Manager&lt;/td&gt;
					&lt;td&gt;클러스터 상태 유지&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;etcd&lt;/td&gt;
					&lt;td&gt;클러스터 상태 저장&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-worker-node"&gt;
 🖥️ Worker Node
 &lt;a class="heading-anchor" href="#-worker-node" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Worker Node는 &lt;strong&gt;실제로 컨테이너가 실행되는 서버&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Worker Node]

A --&amp;gt; B[kubelet]
A --&amp;gt; C[kube-proxy]
A --&amp;gt; D[Container Runtime]
A --&amp;gt; E[Pods]&lt;/pre&gt;
&lt;p&gt;각 Node에는 다음 구성요소가 포함됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;kubelet&lt;/li&gt;
&lt;li&gt;kube-proxy&lt;/li&gt;
&lt;li&gt;container runtime (Docker / containerd)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Node는 다음 환경에서 실행될 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;물리 서버&lt;/li&gt;
&lt;li&gt;가상 머신&lt;/li&gt;
&lt;li&gt;클라우드 인스턴스&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;각 구성요소&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Component&lt;/th&gt;
					&lt;th&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;kubelet&lt;/td&gt;
					&lt;td&gt;Node의 Pod 관리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;kube-proxy&lt;/td&gt;
					&lt;td&gt;네트워크 처리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Container Runtime&lt;/td&gt;
					&lt;td&gt;컨테이너 실행&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pods&lt;/td&gt;
					&lt;td&gt;실제 애플리케이션&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-kubernetes-object"&gt;
 📦 Kubernetes Object
 &lt;a class="heading-anchor" href="#-kubernetes-object" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes에서는 모든 리소스를 &lt;strong&gt;Object 형태로 관리합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;예를 들어&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod&lt;/li&gt;
&lt;li&gt;Service&lt;/li&gt;
&lt;li&gt;Deployment&lt;/li&gt;
&lt;li&gt;ConfigMap&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;모두 Kubernetes Object입니다.&lt;/p&gt;
&lt;p&gt;Object는 보통 &lt;strong&gt;YAML 파일로 정의&lt;/strong&gt;합니다.&lt;/p&gt;
&lt;p&gt;예시 구조&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;example&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Object에는 크게 두 가지 정보가 포함됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Metadata&lt;/strong&gt; → 이름, label 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Spec&lt;/strong&gt; → 원하는 상태 (Desired State)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-pod"&gt;
 🐳 Pod
 &lt;a class="heading-anchor" href="#-pod" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Pod는 Kubernetes에서 &lt;strong&gt;가장 작은 배포 단위&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;중요한 점은 Kubernetes가 &lt;strong&gt;컨테이너를 직접 배포하지 않는다는 것&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;대신 컨테이너를 &lt;strong&gt;Pod 안에서 실행합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="pod-특징"&gt;
 Pod 특징
 &lt;a class="heading-anchor" href="#pod-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;하나 이상의 컨테이너 포함&lt;/li&gt;
&lt;li&gt;동일한 네트워크 사용&lt;/li&gt;
&lt;li&gt;동일한 스토리지 공유 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pod 구조&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod]

A --&amp;gt; B[Container - App]
A --&amp;gt; C[Container - Sidecar]
A --&amp;gt; D[Shared Network]
A --&amp;gt; E[Shared Volume]&lt;/pre&gt;
&lt;p&gt;이 구조를 이용하면 다음과 같은 패턴이 가능합니다.&lt;/p&gt;
&lt;p&gt;예시&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Application Container&lt;/li&gt;
&lt;li&gt;Log Collector Container&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;애플리케이션이 생성한 로그를 &lt;strong&gt;Sidecar Container가 수집&lt;/strong&gt;하는 방식입니다.&lt;/p&gt;
&lt;h3 id="pod-networking"&gt;
 Pod Networking
 &lt;a class="heading-anchor" href="#pod-networking" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Pod는 각각 &lt;strong&gt;고유한 IP&lt;/strong&gt;를 가집니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph LR

A[Pod A] --&amp;gt; B[Pod B]
B --&amp;gt; C[Pod C]&lt;/pre&gt;
&lt;p&gt;Kubernetes 특징&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod 간 직접 통신 가능&lt;/li&gt;
&lt;li&gt;NAT 없이 Pod IP 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-volume"&gt;
 💾 Volume
 &lt;a class="heading-anchor" href="#-volume" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;컨테이너의 파일 시스템은 기본적으로 &lt;strong&gt;휘발성(Ephemeral)&lt;/strong&gt; 입니다.&lt;/p&gt;
&lt;p&gt;즉 컨테이너가 재시작되면 데이터가 사라집니다.&lt;/p&gt;
&lt;p&gt;이 문제를 해결하기 위해 사용하는 것이 &lt;strong&gt;Volume&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;Volume 특징&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod에 마운트되어 사용&lt;/li&gt;
&lt;li&gt;컨테이너 간 공유 가능&lt;/li&gt;
&lt;li&gt;데이터 유지 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;예시 구조&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Pod]

A --&amp;gt; B[Container 1]
A --&amp;gt; C[Container 2]

B --&amp;gt; D[Shared Volume]
C --&amp;gt; D&lt;/pre&gt;
&lt;p&gt;대표적인 Volume 타입&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;emptyDir&lt;/li&gt;
&lt;li&gt;hostPath&lt;/li&gt;
&lt;li&gt;Persistent Volume (PV)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-service"&gt;
 🌐 Service
 &lt;a class="heading-anchor" href="#-service" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Pod는 생성되고 삭제될 때마다 &lt;strong&gt;IP가 변경됩니다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;따라서 Pod에 직접 접근하는 방식은 안정적이지 않습니다.&lt;/p&gt;
&lt;p&gt;이 문제를 해결하는 것이 &lt;strong&gt;Service&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;Service는&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod 그룹에 대한 &lt;strong&gt;고정된 네트워크 엔드포인트&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;내부 &lt;strong&gt;로드밸런싱 기능&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;을 제공합니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Service]

A --&amp;gt; B[Pod]
A --&amp;gt; C[Pod]
A --&amp;gt; D[Pod]&lt;/pre&gt;
&lt;p&gt;즉 Service는 &lt;strong&gt;Pod 앞단에서 트래픽을 분산하는 역할&lt;/strong&gt;을 합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-deployment"&gt;
 🚀 Deployment
 &lt;a class="heading-anchor" href="#-deployment" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Pod는 직접 생성해서 사용할 수도 있지만
실무에서는 보통 &lt;strong&gt;Deployment&lt;/strong&gt;를 사용합니다.&lt;/p&gt;
&lt;p&gt;Deployment는 다음 기능을 제공합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod 자동 생성&lt;/li&gt;
&lt;li&gt;Replica 관리&lt;/li&gt;
&lt;li&gt;Rolling Update&lt;/li&gt;
&lt;li&gt;Rollback&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Deployment 구조&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[Deployment]

A --&amp;gt; B[ReplicaSet]

B --&amp;gt; C[Pod]
B --&amp;gt; D[Pod]
B --&amp;gt; E[Pod]&lt;/pre&gt;
&lt;p&gt;Deployment는 내부적으로 &lt;strong&gt;ReplicaSet을 생성하고 Pod를 관리합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-kubernetes-배포-전략"&gt;
 🔄 Kubernetes 배포 전략
 &lt;a class="heading-anchor" href="#-kubernetes-%eb%b0%b0%ed%8f%ac-%ec%a0%84%eb%9e%b5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Kubernetes에서는 다양한 배포 전략을 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;대표적인 방식 두 가지를 살펴보겠습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-blue-green-deployment"&gt;
 🔵🟢 Blue-Green Deployment
 &lt;a class="heading-anchor" href="#-blue-green-deployment" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Blue-Green 배포는 &lt;strong&gt;두 개의 환경을 동시에 운영하는 방식&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph LR

A[Blue Version - Old]

B[Green Version - New]

C[Load Balancer]

C --&amp;gt; A

C -. Switch .-&amp;gt; B&lt;/pre&gt;
&lt;p&gt;배포 과정&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;새로운 버전(Green) 배포&lt;/li&gt;
&lt;li&gt;트래픽을 Blue → Green으로 전환&lt;/li&gt;
&lt;li&gt;문제 없으면 Blue 제거&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;장점&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;롤백이 매우 빠름&lt;/li&gt;
&lt;li&gt;안정적인 배포 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="-rolling-update"&gt;
 🔁 Rolling Update
 &lt;a class="heading-anchor" href="#-rolling-update" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Rolling Update는 Pod를 &lt;strong&gt;하나씩 교체하는 방식&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph LR

A[Old Pod] --&amp;gt; B[New Pod]
A2[Old Pod] --&amp;gt; B2[New Pod]
A3[Old Pod] --&amp;gt; B3[New Pod]&lt;/pre&gt;
&lt;p&gt;특징&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;서비스 중단 없이 배포 가능&lt;/li&gt;
&lt;li&gt;점진적 업데이트&lt;/li&gt;
&lt;li&gt;문제 발생 시 롤백 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Deployment의 기본 배포 방식이기도 합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-kubernetes-networking-구조"&gt;
 🌐 Kubernetes Networking 구조
 &lt;a class="heading-anchor" href="#-kubernetes-networking-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;외부 트래픽은 다음 경로를 통해 Pod로 전달됩니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[User]

A --&amp;gt; B[Ingress]

B --&amp;gt; C[Service]

C --&amp;gt; D[Pod]
C --&amp;gt; E[Pod]&lt;/pre&gt;
&lt;p&gt;구성 요소&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Component&lt;/th&gt;
					&lt;th&gt;역할&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Ingress&lt;/td&gt;
					&lt;td&gt;HTTP 라우팅&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Service&lt;/td&gt;
					&lt;td&gt;로드밸런싱&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pod&lt;/td&gt;
					&lt;td&gt;애플리케이션&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="-kubernetes-전체-아키텍처"&gt;
 🏛️ Kubernetes 전체 아키텍처
 &lt;a class="heading-anchor" href="#-kubernetes-%ec%a0%84%ec%b2%b4-%ec%95%84%ed%82%a4%ed%85%8d%ec%b2%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;지금까지 설명한 구조를 하나로 합치면 다음과 같습니다.&lt;/p&gt;
&lt;pre class="mermaid" aria-label="diagram"&gt;graph TD

A[User]

A --&amp;gt; B[Ingress]

B --&amp;gt; C[Service]

C --&amp;gt; D[Pod]

D --&amp;gt; E[Worker Node]

E --&amp;gt; F[Kubernetes Cluster]

F --&amp;gt; G[Control Plane]&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="-자주-묻는-질문"&gt;
 ❓ 자주 묻는 질문
 &lt;a class="heading-anchor" href="#-%ec%9e%90%ec%a3%bc-%eb%ac%bb%eb%8a%94-%ec%a7%88%eb%ac%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="q-pod와-container의-차이는"&gt;
 Q. Pod와 Container의 차이는?
 &lt;a class="heading-anchor" href="#q-pod%ec%99%80-container%ec%9d%98-%ec%b0%a8%ec%9d%b4%eb%8a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Pod는 Kubernetes의 최소 배포 단위로, 하나 이상의 컨테이너를 포함합니다. 컨테이너가 Pod 안에서 실행되는 구조입니다.&lt;/p&gt;
&lt;h3 id="q-deployment를-왜-사용하나요"&gt;
 Q. Deployment를 왜 사용하나요?
 &lt;a class="heading-anchor" href="#q-deployment%eb%a5%bc-%ec%99%9c-%ec%82%ac%ec%9a%a9%ed%95%98%eb%82%98%ec%9a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Deployment는 Pod의 자동 생성, 복제본 관리, 무중단 배포(Rolling Update) 및 롤백 기능을 자동으로 제공하여 안정적인 운영을 돕습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-참고"&gt;
 📚 참고
 &lt;a class="heading-anchor" href="#-%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/"&gt;Kubernetes 공식 문서&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Spring Boot] Spring Boot Test</title><link>https://kyungryeol-yoon.github.io/backend/spring/spring-boot-test/</link><pubDate>Tue, 22 Jan 2019 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/spring/spring-boot-test/</guid><description>&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;Annotation&lt;/th&gt;
					&lt;th style="text-align: left"&gt;설명&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Bean&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;@SpringBootTest&lt;/td&gt;
					&lt;td style="text-align: left"&gt;통합 테스트, 전체&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Bean 전체&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;@WebMvcTest&lt;/td&gt;
					&lt;td style="text-align: left"&gt;단위 테스트, Mvc 테스트&lt;/td&gt;
					&lt;td style="text-align: left"&gt;MVC 관련된 Bean&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;@DataJpaTest&lt;/td&gt;
					&lt;td style="text-align: left"&gt;단위 테스트, Jpa 테스트&lt;/td&gt;
					&lt;td style="text-align: left"&gt;JPA 관련 Bean&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;@RestClientTest&lt;/td&gt;
					&lt;td style="text-align: left"&gt;단위 테스트, Rest API 테스트&lt;/td&gt;
					&lt;td style="text-align: left"&gt;일부 Bean&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;@JsonTest&lt;/td&gt;
					&lt;td style="text-align: left"&gt;단위 테스트, Json 테스트&lt;/td&gt;
					&lt;td style="text-align: left"&gt;일부 Bean&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="spring-boot-test"&gt;
 &lt;strong&gt;Spring Boot Test&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#spring-boot-test" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@SpringBootTest&lt;/code&gt;는 통합 테스트를 제공하는 기본적인 스프링 부트 테스트 Annotation이다.
&lt;ul&gt;
&lt;li&gt;애플리케이션이 실행 될 때의 설정을 임의로 바꾸어 테스트를 진행할 수 있으며 여러 단위 테스트를 하나의 통합된 테스트로 수행할 때 접합한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@SpringBootTest&lt;/code&gt;는 만능이다. 실제 구동되는 애플리케이션과 똑같이 애플리케이션 컨텍스트를 도르하여 테스트하기 때문에 하고 싶은 테스트를 모두수행할 수 있다.&lt;/li&gt;
&lt;li&gt;애플리케이션의 설정을 모두 로드하기 때문에 애플리케이션 규모가 클수록 느려진다. 이렇게되면 단위 테스트라는 의미가 희석된다.&lt;/li&gt;
&lt;li&gt;Test Scope Dependencies 아래의 의존성을 자동으로 갖는다.
&lt;ul&gt;
&lt;li&gt;JUnit: The de-facto standard for unit testing Java applications.&lt;/li&gt;
&lt;li&gt;Spring Test &amp;amp; Spring Boot Test: Utilities and integration test support for Spring Boot applications.&lt;/li&gt;
&lt;li&gt;AssertJ: A fluent assertion library.&lt;/li&gt;
&lt;li&gt;Hamcrest: A library of matcher objects (also known as constraints or predicates).&lt;/li&gt;
&lt;li&gt;Mockito: A Java mocking framework.&lt;/li&gt;
&lt;li&gt;JSONassert: An assertion library for JSON.&lt;/li&gt;
&lt;li&gt;JsonPath: XPath for JSON.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@RunWith&lt;/code&gt; 어노태이션을 사용하면 JUnit에 내장된 러너를 사용하는 대신 Annotation의 정의된 러너 클래스를 사용한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@SpringBootTest&lt;/code&gt; Annotation을 사용하려면 JUnit의 SpringJUnit4ClassRunner 클래스를 상속 받는 &lt;code&gt;@RunWith(SpringRynnver.class)&lt;/code&gt;를 꼭 붙여서 사용해야 정상동작한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RunWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SpringRunner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;property.value=propertyTest&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;value=test&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;classes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;TestApplication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;webEnvironment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SpringBootTest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;WebEnvironment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RANDOM_PORT&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestApplicationTests&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;${value}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;${property.value}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;propertyValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;contextLoads&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;test&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;propertyValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;propertyTest&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;properties&lt;/code&gt;: 테스트가 실행되기전에 &lt;code&gt;{key=value}&lt;/code&gt; 형식으로 프로퍼티를 추가할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;classes&lt;/code&gt;: 애플리케이션 컨텍스트에 로드할 클래스를 지정한다. 따로 지정하지 않으면 &lt;code&gt;@SprongBootConfiguration&lt;/code&gt;을 찾아서 로드한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;webEnvironment&lt;/code&gt;: 애플리케이션이 실행될 때의 웹 환경을 설정할 수 있다. 기본값은 Mock 서블릿을 로드하여 구동되며 예제에서는 랜덤 포트값을 지정&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;프로파일 환경을 갖는다면 &lt;code&gt;@ActiveProfiles(&amp;quot;test&amp;quot;)&lt;/code&gt;과 같은 방식으로 원하는 프로파일 환경값을 부여 가능&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;테스트에서 &lt;code&gt;@Transactional&lt;/code&gt;을 사용하면 테스트를 마치고 나서 수정된 데이터가 롤백된다. 다만 테스트가 서버의 다른 스레드에서 실행 중이라면 &lt;code&gt;WebEnvironment.RANDOM_PORT, DEFINED_PORT&lt;/code&gt;를 사용하여 테스트를 수행하면 트랜잭션이 롤백되지 않는다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;@Transactional&lt;/code&gt; Annotation을 붙여주면 자동으로 rollback 처리된다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="webmvctest"&gt;
 &lt;strong&gt;@WebMvcTest&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#webmvctest" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;MVC를 위한 테스트, 웹에서 테스트하기 힘든 Controller를 테스트하는데 적합하다.&lt;/li&gt;
&lt;li&gt;웹상에서 요청과 응답에 대한 테스트 진행&lt;/li&gt;
&lt;li&gt;Security 혹은 필터까지 자동으로 테스트하며 수동으로 추가/삭제 가능&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@WebMvcTest&lt;/code&gt; Annotation을 사용하면 MVC 관련된 설정인 &lt;code&gt;@Controller&lt;/code&gt;, &lt;code&gt;@ControllerAdvice&lt;/code&gt;, &lt;code&gt;@JsonCompoent&lt;/code&gt;와 &lt;code&gt;Filter&lt;/code&gt;, &lt;code&gt;WebMvcConfiguer&lt;/code&gt;, &lt;code&gt;HandlerMetohdAgumentResolver&lt;/code&gt;만 로드되기 때문에 &lt;code&gt;@SpringBootTest&lt;/code&gt; Annotation 보다 가볍게 테스트할수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RunWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SpringRunner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@WebMvcTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BookApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookApiTest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Autowired&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MockMvc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mvc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@MockBean&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BookService&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bookService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getBook_test&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//given&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;1L&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;1000D&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;given&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bookService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBook&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;willReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//when&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ResultActions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mvc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/books/{id}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;1L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MediaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON_UTF8&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andDo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//then&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andExpect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isOk&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andExpect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;1L&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andExpect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andExpect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;price&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;1000D&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@WebMvcTest&lt;/code&gt;를 사용하기 위해 테스트할 특정 Controller 클래스를 명시 해야한다.&lt;/li&gt;
&lt;li&gt;주입된 MockMvc는 Controller 테스트시 모든 의존성을 로드하는 것이아닌 BookApi 관련된 Bean만 로드하여 가벼운 MVC 테스트를 수행한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@Service&lt;/code&gt; Annotation은 &lt;code&gt;@WebMvcTest&lt;/code&gt; 적용대상입니다. &lt;code&gt;BookService&lt;/code&gt; 인터페이스를 구현한 구현체는 없지만 &lt;code&gt;@MockBean&lt;/code&gt;을 이용해서 &lt;code&gt;BookService&lt;/code&gt; Mock 객체로 대체했다.&lt;/li&gt;
&lt;li&gt;given에서 해당 객체를 생성한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;when&lt;/code&gt;에서 Mock 객체를 기반으로 미리 정의된 객체를 반환 받는다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;then&lt;/code&gt;에서 해당 객체의 응답값을 검사한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="datajpatest"&gt;
 &lt;strong&gt;@DataJpaTest&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#datajpatest" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@DataJpaTest&lt;/code&gt; Annotation은 JPA 관련된 설정만 로드한다.&lt;/li&gt;
&lt;li&gt;데이터소스의 설정이 정상적인지, JPA를 사용하서 데이터를 제대로 생성, 수정, 삭제하는지 등의 테스트가 가능하다.&lt;/li&gt;
&lt;li&gt;기본적으로 inMemory 데이터베이스를 이용한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@Entity&lt;/code&gt; 클래스를 스캔하여 스프링 데이터 JPA 저장소를 구성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RunWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SpringRunner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@DataJpaTest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@ActiveProfiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;test&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@AutoConfigureTestDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AutoConfigureTestDatabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Replace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NONE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookJpaTest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Autowired&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BookRepository&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bookRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;book_save_test&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;1000D&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;saveBook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bookRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;saveBook&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notNullValue&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;book_save_and_find&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;1000D&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;saveBook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bookRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;findBook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bookRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;saveBook&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;findBook&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notNullValue&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@AutoConfigureTestDatabase&lt;/code&gt; Annotation의 기본 설정값인 Replace.Any를 사용하면 기본적으로 내장된 데이터소스를 사용한다.&lt;/li&gt;
&lt;li&gt;위와 같이 &lt;code&gt;@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)&lt;/code&gt;을 지정하면 &lt;code&gt;@ActiveProfiles(&amp;quot;test&amp;quot;)&lt;/code&gt; 기준으로 프로파일이 설정된다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@DataJpaTest&lt;/code&gt;는 테스트가 끝날 때마다 자동으로 테스트에 사용한 데이터를 롤백한다.&lt;/li&gt;
&lt;li&gt;데이터 베이스의 종류도 선택할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="restclienttest"&gt;
 &lt;strong&gt;@RestClientTest&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#restclienttest" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@RestClientTest&lt;/code&gt;는 REST 관련 테스트를 도와주는 Annotation이다.&lt;/li&gt;
&lt;li&gt;REST 통신의 JSON 형식이 예상대로 응답을 반환하는지 등을 테스트 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RunWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SpringRunner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RestClientTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BookRestService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookRestServiceTest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Rule&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ExpectedException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thrown&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ExpectedException&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;none&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Autowired&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BookRestService&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bookRestService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Autowired&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MockRestServiceServer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;rest_test&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/rest/test&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andRespond&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;withSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ClassPathResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/test.json&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MediaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bookRestService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRestBook&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notNullValue&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTitle&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPrice&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;1000D&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;test.json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;price&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@RestClientTest&lt;/code&gt;는 테스트 대상이 되는 Bean을 주입받는다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@Rule&lt;/code&gt;로 지정한 필드 값은 &lt;code&gt;@Before&lt;/code&gt;, &lt;code&gt;@After&lt;/code&gt; Annotation에 상관없이 하나의 테스트가 Method가 끝날 때마다 정의한 값으로 초기화 시켜준다. 테스트에서 자체적으로 자체적으로 규칙을 정의하여 재사용할 때 유용하다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MockRestServiceServer&lt;/code&gt;는 클라이언트와 서버 사이의 REST 테스트를 위한 객체이다. 내부에서 RestTemplate를 바인딩하여 실제로 통신이 이루어지게끔 구성할 수도 있다. 이 코드에서는 Mock 객체와 같이 실제로 통신이 이루어지지는 않지만 지정한 결로에 예상되는 반환값을 명시한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rest_test()&lt;/code&gt; Method는 요청에 대한 응답과 기댓값이 같은지 테스트한다. 요청을 보내면 현지 리소스 폴더에 있는 &lt;code&gt;test.json&lt;/code&gt; 데이터로 응답을 주도록 설정한다
&lt;ul&gt;
&lt;li&gt;Mock 객체와 비슷한 개념이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="jsontest"&gt;
 &lt;strong&gt;@JsonTest&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#jsontest" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@JsonTest&lt;/code&gt;는 JSON의 직렬화, 역직렬화를 수행하는 Library인 Gson과 Jackson의 테스트를 제공합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RunWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SpringRunner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@JsonTest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookJsonTest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Autowired&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JacksonTester&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;json_test&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IOException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;1000D&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{\n&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34; \&amp;#34;id\&amp;#34;: 0,\n&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34; \&amp;#34;title\&amp;#34;: \&amp;#34;title\&amp;#34;,\n&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34; \&amp;#34;price\&amp;#34;: 1000\n&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parseObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getTitle&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;isEqualTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTitle&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;isEqualToJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/test.json&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;객체를 직렬화 테스트 / 역직렬화 테스트&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] tree Directory 구조 조회</title><link>https://kyungryeol-yoon.github.io/linux/system/linux-directory-tree/</link><pubDate>Sun, 11 Nov 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/system/linux-directory-tree/</guid><description>&lt;h2 id="tree란"&gt;
 tree란?
 &lt;a class="heading-anchor" href="#tree%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;터미널에서 Directory 구조 조회를 용이하게 해준다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ls 명령어를 사용해서 Directory 내부를 확인할 수 있기는 하지만, 서브 Directory 내부에 포함된 파일을 확인하려면 다시 cd, ls 명령어를 중복 사용해야 하는 불편함이 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이럴 때 tree 명령어를 활용하면 한 눈에 Directory 구조를 파악할 수 있어 매우 유용하다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tree-설치"&gt;
 tree 설치
 &lt;a class="heading-anchor" href="#tree-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;기본적으로 tree 명령은 설치되지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rhel--centos--fedora-linux-환경에서-yum-으로-설치"&gt;
 RHEL / CentOS / Fedora Linux 환경에서 yum 으로 설치
 &lt;a class="heading-anchor" href="#rhel--centos--fedora-linux-%ed%99%98%ea%b2%bd%ec%97%90%ec%84%9c-yum-%ec%9c%bc%eb%a1%9c-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;yum install tree&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="debian--mint--ubuntu-linux-환경에서-apt-get-으로-설치"&gt;
 Debian / Mint / Ubuntu Linux 환경에서 apt-get 으로 설치
 &lt;a class="heading-anchor" href="#debian--mint--ubuntu-linux-%ed%99%98%ea%b2%bd%ec%97%90%ec%84%9c-apt-get-%ec%9c%bc%eb%a1%9c-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get install tree&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="mac-os-환경-에서-homebrew로-설치"&gt;
 Mac OS 환경 에서 homebrew로 설치
 &lt;a class="heading-anchor" href="#mac-os-%ed%99%98%ea%b2%bd-%ec%97%90%ec%84%9c-homebrew%eb%a1%9c-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;brew install tree
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;Updating Homebrew...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;==&lt;/span&gt;&amp;gt; Downloading https://homebrew.bintray.com/bottles/tree-1.7.0.yosemite.bottle.1.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;######################################################################## 100.0%&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;==&lt;/span&gt;&amp;gt; Pouring tree-1.7.0.yosemite.bottle.1.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;/usr/local/Cellar/tree/1.7.0: &lt;span class="m"&gt;7&lt;/span&gt; files, 113.4KB&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="tree-사용법"&gt;
 tree 사용법
 &lt;a class="heading-anchor" href="#tree-%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;tree &lt;span class="o"&gt;(&lt;/span&gt;옵션&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="directory-구조-조회"&gt;
 Directory 구조 조회
 &lt;a class="heading-anchor" href="#directory-%ea%b5%ac%ec%a1%b0-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;tree
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;├── build.gradle
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;├── gradle
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;│ └── wrapper
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;│ ├── gradle-wrapper.jar
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;│ └── gradle-wrapper.properties
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;├── gradlew
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;├── gradlew.bat
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;├── settings.gradle
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;└── src
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; ├── main
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; │ └── java
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; │ └── Library.java
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; └── &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; └── java
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; └── LibraryTest.java
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;7&lt;/span&gt; directories, &lt;span class="m"&gt;8&lt;/span&gt; files&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="tree-옵션"&gt;
 tree 옵션
 &lt;a class="heading-anchor" href="#tree-%ec%98%b5%ec%85%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;옵션&lt;/th&gt;
					&lt;th style="text-align: left"&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-a&lt;/td&gt;
					&lt;td style="text-align: left"&gt;숨겨진 파일 포함 모두 표시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-d&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Directory 구조만 표시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-l&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Directory와 같은 기호 링크를 따라 가서 표시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-f&lt;/td&gt;
					&lt;td style="text-align: left"&gt;상대 경로로 표시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-i&lt;/td&gt;
					&lt;td style="text-align: left"&gt;들여쓰기를 적용하지 않고 표시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-q&lt;/td&gt;
					&lt;td style="text-align: left"&gt;출력할 수 없는 &amp;lsquo;?&amp;rsquo; 문자까지 표시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-N&lt;/td&gt;
					&lt;td style="text-align: left"&gt;출력할 수 없는 문자까지 모두 표시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-p&lt;/td&gt;
					&lt;td style="text-align: left"&gt;퍼미션(권한) 설정까지 표시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-u&lt;/td&gt;
					&lt;td style="text-align: left"&gt;파일 권한자 또는 UID 숫자 표시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-g&lt;/td&gt;
					&lt;td style="text-align: left"&gt;각 파일의 용량(Bytes) 표시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-h&lt;/td&gt;
					&lt;td style="text-align: left"&gt;각 파일의 용량 크기를 사람이 보기 편하게 표시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-D&lt;/td&gt;
					&lt;td style="text-align: left"&gt;수정한 날짜 표시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-F&lt;/td&gt;
					&lt;td style="text-align: left"&gt;뒤에 &amp;lsquo;/&amp;rsquo;, &amp;lsquo;=&amp;rsquo;, &amp;lsquo;*&amp;rsquo;, 또는 `&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-v&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Directory 내 파일을 알파벳 순으로 정렬&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-r&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Directory 내 파일을 알파벳 역순으로 정렬&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-t&lt;/td&gt;
					&lt;td style="text-align: left"&gt;최근 수정한 파일 순으로 정렬&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-x&lt;/td&gt;
					&lt;td style="text-align: left"&gt;현재 파일 시스템만 놔둠&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-n&lt;/td&gt;
					&lt;td style="text-align: left"&gt;컬러 모드 표시 Off&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;-C&lt;/td&gt;
					&lt;td style="text-align: left"&gt;컬러 모드 표시 On&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;</description></item><item><title>[Linux] alias 명령어 치환</title><link>https://kyungryeol-yoon.github.io/linux/system/linux-alias/</link><pubDate>Thu, 25 Oct 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/system/linux-alias/</guid><description>&lt;h2 id="alias-명령어"&gt;
 alias 명령어
 &lt;a class="heading-anchor" href="#alias-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;복잡한 명령어와 옵션을 간단히 입력할 수 있는 문자열로 치환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;단축키&lt;span class="o"&gt;]=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;[명령어]&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="alias-명령어-사용-예제"&gt;
 alias 명령어 사용 예제
 &lt;a class="heading-anchor" href="#alias-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%82%ac%ec%9a%a9-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="예제-1"&gt;
 예제 1)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;alias로 지정된 명령어 확인한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;alias&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-2"&gt;
 예제 2)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;clear 명령어 대신 c를 입력해도 같은 기능을 하게 만든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;c&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;clear&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-3"&gt;
 예제 3)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-3" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;mkdir -p a/b/c 명령어 대신 m을 입력해도 같은 기능을 하게 만든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;m&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mkdir -p a/b/c&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="alias-명령어-영구-저장"&gt;
 alias 명령어 영구 저장
 &lt;a class="heading-anchor" href="#alias-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%98%81%ea%b5%ac-%ec%a0%80%ec%9e%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;설정 해 놓은 alias는 창이 꺼지면 다 사라진다.&lt;/li&gt;
&lt;li&gt;영구적으로 저장 하고 싶을땐 &lt;code&gt;.bashrc&lt;/code&gt;에 저장 하면 된다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.bashrc&lt;/code&gt;의 위치는 &lt;code&gt;~계정명/.bashrc&lt;/code&gt; 이다.&lt;/li&gt;
&lt;li&gt;A라는 계정에서 저장한 alias명령어는 B라는 계정에서 사용 불가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="저장법"&gt;
 저장법
 &lt;a class="heading-anchor" href="#%ec%a0%80%ec%9e%a5%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;cat &amp;gt;&amp;gt; ~root/.bashrc&lt;/code&gt; 입력&lt;/li&gt;
&lt;li&gt;자신이 저장 할 alias 입력&lt;/li&gt;
&lt;li&gt;Enter 후 &lt;code&gt;Ctrl + C&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;창을 껐다가 키거나, 아래 명령어을 입력한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chsh -s /bin/bash&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Linux] Vi Editor</title><link>https://kyungryeol-yoon.github.io/linux/system/linux-vi/</link><pubDate>Thu, 11 Oct 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/system/linux-vi/</guid><description>&lt;h2 id="vi-vimvi-improved향상된-vi"&gt;
 Vi, VIM(Vi IMproved=향상된 VI)
 &lt;a class="heading-anchor" href="#vi-vimvi-improved%ed%96%a5%ec%83%81%eb%90%9c-vi" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;빠른 편집 속도가 특징인 리눅스의 대표적인 에디터이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;vi&lt;/code&gt;는 &lt;code&gt;Visual&lt;/code&gt;의 약자이다&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;명령어&lt;/th&gt;
					&lt;th style="text-align: left"&gt;설명&lt;/th&gt;
					&lt;th style="text-align: left"&gt;예제&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;vi {파일명}&lt;/td&gt;
					&lt;td style="text-align: left"&gt;파일열기, 작성&lt;/td&gt;
					&lt;td style="text-align: left"&gt;vi test.txt&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;vi +{행번호} {파일명}&lt;/td&gt;
					&lt;td style="text-align: left"&gt;파일을 열고, 입력한 행으로 커서 이동&lt;/td&gt;
					&lt;td style="text-align: left"&gt;vi -100 test.txt&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;vi +/“{검색 문자열}” {파일명}&lt;/td&gt;
					&lt;td style="text-align: left"&gt;“문자열”의 처음발생 단어부터 열기&lt;/td&gt;
					&lt;td style="text-align: left"&gt;vi -/&amp;ldquo;adc&amp;rdquo; test.txt&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;vi –r {파일명}&lt;/td&gt;
					&lt;td style="text-align: left"&gt;손상된 파일 회복&lt;/td&gt;
					&lt;td style="text-align: left"&gt;vi -r test.txt&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;view {파일명}&lt;/td&gt;
					&lt;td style="text-align: left"&gt;읽기 전용으로 열기기&lt;/td&gt;
					&lt;td style="text-align: left"&gt;view test.txt&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="수정-파일-열기"&gt;
 수정 파일 열기
 &lt;a class="heading-anchor" href="#%ec%88%98%ec%a0%95-%ed%8c%8c%ec%9d%bc-%ec%97%b4%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;vi {파일명}&lt;/code&gt; 명령어로 입력했을 때, 입력한 파일명이 실제 존재 한 경우 파일을 수정.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="신규-파일-생성"&gt;
 신규 파일 생성
 &lt;a class="heading-anchor" href="#%ec%8b%a0%ea%b7%9c-%ed%8c%8c%ec%9d%bc-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;vi {파일명}&lt;/code&gt; 명령어로 입력했을 때, 입력한 파일명이 실제 존재 하지 않는 경우 파일을 생성.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="vi-커서-이동"&gt;
 vi 커서 이동
 &lt;a class="heading-anchor" href="#vi-%ec%bb%a4%ec%84%9c-%ec%9d%b4%eb%8f%99" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;커서&lt;/th&gt;
					&lt;th style="text-align: left"&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;h (←)&lt;/td&gt;
					&lt;td style="text-align: left"&gt;왼쪽으로 커서 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;j (↓)&lt;/td&gt;
					&lt;td style="text-align: left"&gt;아래로 커서 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;k (↑)&lt;/td&gt;
					&lt;td style="text-align: left"&gt;위로 커서 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;l (→)&lt;/td&gt;
					&lt;td style="text-align: left"&gt;오른쪽으로 커서 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;w&lt;/td&gt;
					&lt;td style="text-align: left"&gt;오른쪽 한 단어의 끝 부분으로 커서 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;e&lt;/td&gt;
					&lt;td style="text-align: left"&gt;오른쪽 한 단어의 앞 부분으로 커서 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;b&lt;/td&gt;
					&lt;td style="text-align: left"&gt;왼쪽 한 단어의 앞 부분으로 커서 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;Enter&lt;/td&gt;
					&lt;td style="text-align: left"&gt;한 행 아래로 커서 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;Back space&lt;/td&gt;
					&lt;td style="text-align: left"&gt;한 문자 왼쪽으로 커서 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;Space Bar&lt;/td&gt;
					&lt;td style="text-align: left"&gt;한 문자 오른쪽으로 커서 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;^&lt;/td&gt;
					&lt;td style="text-align: left"&gt;행의 맨 왼쪽으로 커서 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;$&lt;/td&gt;
					&lt;td style="text-align: left"&gt;행의 맨 오른쪽으로 커서 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;H&lt;/td&gt;
					&lt;td style="text-align: left"&gt;화면의 맨 위로 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;M&lt;/td&gt;
					&lt;td style="text-align: left"&gt;화면의 중간으로 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;L&lt;/td&gt;
					&lt;td style="text-align: left"&gt;화면의 맨 아래로 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;숫자G&lt;/td&gt;
					&lt;td style="text-align: left"&gt;‘숫자’ 만큼 지정한 줄로 커서 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;Ctrl + i&lt;/td&gt;
					&lt;td style="text-align: left"&gt;한 화면 위로 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;Ctrl + b&lt;/td&gt;
					&lt;td style="text-align: left"&gt;한 화면 아래로 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;Ctrl + d&lt;/td&gt;
					&lt;td style="text-align: left"&gt;반 화면 위로 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;Ctrl + u&lt;/td&gt;
					&lt;td style="text-align: left"&gt;반 화면 아래로 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;Ctrl + e&lt;/td&gt;
					&lt;td style="text-align: left"&gt;한 줄씩 위로 이동&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;Ctrl + y&lt;/td&gt;
					&lt;td style="text-align: left"&gt;한 줄씩 아래로 이동&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="문자-행--삽입-명령어"&gt;
 문자, 행 , 삽입 명령어
 &lt;a class="heading-anchor" href="#%eb%ac%b8%ec%9e%90-%ed%96%89--%ec%82%bd%ec%9e%85-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;커서&lt;/th&gt;
					&lt;th style="text-align: left"&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;a&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서 오른쪽에 문자 삽입&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;A&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서 오른쪽, 행의 끝에 문자 삽입&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;i&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서 왼쪽에 문자 삽입&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;I&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서 왼쪽, 행의 처음에 문자 삽입&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;o&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서 아래에 행 삽입&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;O&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서 위에 행 삽입&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;ESC&lt;/td&gt;
					&lt;td style="text-align: left"&gt;종료&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="텍스트-변경-명령어"&gt;
 텍스트 변경 명령어
 &lt;a class="heading-anchor" href="#%ed%85%8d%ec%8a%a4%ed%8a%b8-%eb%b3%80%ea%b2%bd-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;명령어&lt;/th&gt;
					&lt;th style="text-align: left"&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;cw&lt;/td&gt;
					&lt;td style="text-align: left"&gt;단어 변경&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;cc&lt;/td&gt;
					&lt;td style="text-align: left"&gt;행 변경&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;C&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서 오른쪽의 행 변경&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;s&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서가 위치한 문자열 대체&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;S&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서가 위치한 라인의 문자열 대체&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;r&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서 위치 문자를 다른 문자로 대체&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;r-Enter&lt;/td&gt;
					&lt;td style="text-align: left"&gt;행 분리&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;J&lt;/td&gt;
					&lt;td style="text-align: left"&gt;현재 행과 아래 행 결합&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;xp&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서 위치 문자와 오른쪽 문자 교환&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;~&lt;/td&gt;
					&lt;td style="text-align: left"&gt;문자형(대, 소문자) 변경&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;u&lt;/td&gt;
					&lt;td style="text-align: left"&gt;이전 명령 취소&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;U&lt;/td&gt;
					&lt;td style="text-align: left"&gt;행 변경 사항 취소, 이전의 최종 행 취소&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;.&lt;/td&gt;
					&lt;td style="text-align: left"&gt;이전 최종 명령 반복&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="텍스트-삭제-명령어"&gt;
 텍스트 삭제 명령어
 &lt;a class="heading-anchor" href="#%ed%85%8d%ec%8a%a4%ed%8a%b8-%ec%82%ad%ec%a0%9c-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;명령어&lt;/th&gt;
					&lt;th style="text-align: left"&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;x&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서가 있는 문자 삭제&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;nx&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서가 있는 위치부터 n개의 문자를 삭제&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;dw&lt;/td&gt;
					&lt;td style="text-align: left"&gt;현재 커서에 있는 한 단어 삭제&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;dd&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서가 있는 라인 삭제&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;ndd&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서가 있는 라인부터 n개의 라인 삭제&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;db&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서의 위치에서 거꾸로 한 단어 삭제&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;D&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서 오른쪽 행 삭제&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:5,10d&lt;/td&gt;
					&lt;td style="text-align: left"&gt;5~10번째 행 삭제&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="복사-및-이동-명령어"&gt;
 복사 및 이동 명령어
 &lt;a class="heading-anchor" href="#%eb%b3%b5%ec%82%ac-%eb%b0%8f-%ec%9d%b4%eb%8f%99-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;명령어&lt;/th&gt;
					&lt;th style="text-align: left"&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;yy&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서가 위치한 줄 복사&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;Y&lt;/td&gt;
					&lt;td style="text-align: left"&gt;행 yank 또는 복사&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;yh&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서의 왼쪽 문자 복사&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;yl&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서에 위치한 문자 복사&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;yi&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서가 위치한 줄과 그 아랫줄 복사&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;yk&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서가 위치한 줄과 그 윗줄 복사&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;P&lt;/td&gt;
					&lt;td style="text-align: left"&gt;yank 되거나 삭제된 행 현재 행 위로 삽입&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;p&lt;/td&gt;
					&lt;td style="text-align: left"&gt;yank 되거나 삭제된 행 현재 행 아래에 삽입&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:1,2 co 3&lt;/td&gt;
					&lt;td style="text-align: left"&gt;1~2행을 3행 다음으로 복사&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:4,5 m 6&lt;/td&gt;
					&lt;td style="text-align: left"&gt;4~5행을 6행 위로 이동&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;yank&lt;/code&gt; : 홱 잡아당기다&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="한줄복사"&gt;
 한줄복사
 &lt;a class="heading-anchor" href="#%ed%95%9c%ec%a4%84%eb%b3%b5%ec%82%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;해당 라인에서 &amp;lsquo;yy&amp;rsquo;, 즉 y를 두번 누르면 캐시에 저장이 된다.&lt;/li&gt;
&lt;li&gt;붙여넣기를 원하는 곳으로 이동하여 &amp;lsquo;p&amp;rsquo;를 누르면 커서 다음 라인에 붙여넣기가 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="블럭복사"&gt;
 블럭복사
 &lt;a class="heading-anchor" href="#%eb%b8%94%eb%9f%ad%eb%b3%b5%ec%82%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;v&lt;/code&gt;키를 누른 후 커서를 이동하여 블력을 설정한다.&lt;/li&gt;
&lt;li&gt;putty의 경우 블럭이 설정되는 모습이 보이나, ssh의 경우 블럭 모습이 나타나지 않으나 실제로는 설정되고 있다.&lt;/li&gt;
&lt;li&gt;원하는 부분을 블럭으로 설정한 뒤(설정 완료키는 없다) &amp;lsquo;y&amp;rsquo;키를 누르면 캐시에 복사가 된다.&lt;/li&gt;
&lt;li&gt;같은 방법으로 원하는 곳으로 이동하여 &amp;lsquo;p&amp;rsquo;를 누르면 커서 다음 라인에 붙여넣기가 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="행-번호-설정-명령어"&gt;
 행 번호 설정 명령어
 &lt;a class="heading-anchor" href="#%ed%96%89-%eb%b2%88%ed%98%b8-%ec%84%a4%ec%a0%95-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;명령어&lt;/th&gt;
					&lt;th style="text-align: left"&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:set nu 또는 :set number&lt;/td&gt;
					&lt;td style="text-align: left"&gt;에디터의 각 행의 좌측에 행 번호 표시&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:set nonu&lt;/td&gt;
					&lt;td style="text-align: left"&gt;에디터의 각 행의 좌측 행 번호 숨기기&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="행-찾기-명령어"&gt;
 행 찾기 명령어
 &lt;a class="heading-anchor" href="#%ed%96%89-%ec%b0%be%ea%b8%b0-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;명령어&lt;/th&gt;
					&lt;th style="text-align: left"&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;G&lt;/td&gt;
					&lt;td style="text-align: left"&gt;파일의 마지막 행으로 가기&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;21G&lt;/td&gt;
					&lt;td style="text-align: left"&gt;파일의 21번째 행으로 가기&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;Ctrl + G&lt;/td&gt;
					&lt;td style="text-align: left"&gt;현재 File name과 커서의 라인 정보&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="탐색-및-대체-명령어"&gt;
 탐색 및 대체 명령어
 &lt;a class="heading-anchor" href="#%ed%83%90%ec%83%89-%eb%b0%8f-%eb%8c%80%ec%b2%b4-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;명령어&lt;/th&gt;
					&lt;th style="text-align: left"&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;/{검색할 문자열}&lt;/td&gt;
					&lt;td style="text-align: left"&gt;오른쪽 아래 방향으로 문자열 검색&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;?{검색할 문자열}&lt;/td&gt;
					&lt;td style="text-align: left"&gt;왼쪽 위 방향으로 문자열 검색&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;n&lt;/td&gt;
					&lt;td style="text-align: left"&gt;문자열의 다음으로 계속 검색&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;N&lt;/td&gt;
					&lt;td style="text-align: left"&gt;문자열의 이전으로 계속 검색&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:g/search-string/s/&lt;/td&gt;
					&lt;td style="text-align: left"&gt;각 발생 탐색 후 확인하고 대체&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:s/string/rep&lt;/td&gt;
					&lt;td style="text-align: left"&gt;현재 행의 str을 rep로 대체&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:1,.s/string/rep/&lt;/td&gt;
					&lt;td style="text-align: left"&gt;1부터 현재 행의 str을 rep로 대체&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:%s/string/rep/g&lt;/td&gt;
					&lt;td style="text-align: left"&gt;파일 전체 str을 rep로 전부대체&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:.$/aaa/bbb&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서의 위치로부터 파일의 끝까지 있는 모든 aaa를 bbb로 대체&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="화면-정리-명령어"&gt;
 화면 정리 명령어
 &lt;a class="heading-anchor" href="#%ed%99%94%eb%a9%b4-%ec%a0%95%eb%a6%ac-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;명령어&lt;/th&gt;
					&lt;th style="text-align: left"&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;Ctrl + l&lt;/td&gt;
					&lt;td style="text-align: left"&gt;불필요한 화면정리 후 다시 표시&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="파일-명령어"&gt;
 파일 명령어
 &lt;a class="heading-anchor" href="#%ed%8c%8c%ec%9d%bc-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;명령어&lt;/th&gt;
					&lt;th style="text-align: left"&gt;설명&lt;/th&gt;
					&lt;th style="text-align: left"&gt;예제&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:r {파일명}&lt;/td&gt;
					&lt;td style="text-align: left"&gt;커서 다음에 파일 삽입&lt;/td&gt;
					&lt;td style="text-align: left"&gt;:r test.txt&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:{행번호} r {파일명}&lt;/td&gt;
					&lt;td style="text-align: left"&gt;입력한 파일을 입력한 행번호 다음에 삽입&lt;/td&gt;
					&lt;td style="text-align: left"&gt;:10 r test.txt&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="보관-및-종료-명령어"&gt;
 보관 및 종료 명령어
 &lt;a class="heading-anchor" href="#%eb%b3%b4%ea%b4%80-%eb%b0%8f-%ec%a2%85%eb%a3%8c-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;명령어&lt;/th&gt;
					&lt;th style="text-align: left"&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:w&lt;/td&gt;
					&lt;td style="text-align: left"&gt;변경사항 저장&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:w {파일명}&lt;/td&gt;
					&lt;td style="text-align: left"&gt;변경사항 입력한 파일명으로 저장&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:wq&lt;/td&gt;
					&lt;td style="text-align: left"&gt;변경사항 보관 후 vi 종료. ZZ 명령과 같음. :w(기록)과 :q(종료) 를 연속적으로 수행&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;ZZ&lt;/td&gt;
					&lt;td style="text-align: left"&gt;변경사항 보관 후 vi 종료. 임시 버퍼의 내용을 vi로 호출할때 사용되었던 파일에 기록한 후 vi를 빠져나옴&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;:q!&lt;/td&gt;
					&lt;td style="text-align: left"&gt;변경사항 보관하지 않고 종료&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;q&lt;/td&gt;
					&lt;td style="text-align: left"&gt;수정한 파일을 저장하지 않고 vi 종료&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;e!&lt;/td&gt;
					&lt;td style="text-align: left"&gt;수정한 것을 무시하고 다시 편집상태로&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="기타"&gt;
 기타
 &lt;a class="heading-anchor" href="#%ea%b8%b0%ed%83%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;문자&lt;/th&gt;
					&lt;th style="text-align: left"&gt;설명&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;.&lt;/td&gt;
					&lt;td style="text-align: left"&gt;현재 line&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;%&lt;/td&gt;
					&lt;td style="text-align: left"&gt;전체 line&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;$&lt;/td&gt;
					&lt;td style="text-align: left"&gt;파일 맨끝 line&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;1,$&lt;/td&gt;
					&lt;td style="text-align: left"&gt;%&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;2,3&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2 ~ 3 line&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;</description></item><item><title>[Linux] 네트워크 - wget 웹 다운로드</title><link>https://kyungryeol-yoon.github.io/linux/network-commands/linux-network-wget/</link><pubDate>Tue, 25 Sep 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/network-commands/linux-network-wget/</guid><description>&lt;ul&gt;
&lt;li&gt;리눅스에서 wget는 웹 상에 존재하는 파일을 쉽게 다운로드 할 때 사용하는 명령어이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="웹-파일-다운로드"&gt;
 웹 파일 다운로드
 &lt;a class="heading-anchor" href="#%ec%9b%b9-%ed%8c%8c%ec%9d%bc-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;wget --help&lt;/code&gt; 라고 치시면 매우 다양한 옵션을 제공한다.&lt;/li&gt;
&lt;li&gt;웹 상에 있는 특정 파일을 다운로드 할 때 주로 사용하고 있다.&lt;/li&gt;
&lt;li&gt;예를 들어, &lt;code&gt;http://{URL}/file.tar.gz&lt;/code&gt; 이라는 주소에 파일이 위치하고 있다고 가정했을 때,&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;wget http://&lt;span class="o"&gt;{&lt;/span&gt;URL&lt;span class="o"&gt;}&lt;/span&gt;/file.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;위와 같이 명령어를 입력하면, 현재 폴더에 &lt;code&gt;file.tar.gz&lt;/code&gt;이 다운로드 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="웹-파일을-특정-파일명으로-다운로드"&gt;
 웹 파일을 특정 파일명으로 다운로드
 &lt;a class="heading-anchor" href="#%ec%9b%b9-%ed%8c%8c%ec%9d%bc%ec%9d%84-%ed%8a%b9%ec%a0%95-%ed%8c%8c%ec%9d%bc%eb%aa%85%ec%9c%bc%eb%a1%9c-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;특정 이름으로 저장하고 싶으면 영어 대문자으로 &lt;code&gt;-O&lt;/code&gt; 옵션을 주시면 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;O&lt;/code&gt;는 Output의 &lt;code&gt;O&lt;/code&gt;이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;예를 들어, &lt;code&gt;http://{URL}/file.tar.gz&lt;/code&gt; 을 &lt;code&gt;ddd.tar.gz&lt;/code&gt; 으로 저장하고 싶다면&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;wget http://&lt;span class="o"&gt;{&lt;/span&gt;URL&lt;span class="o"&gt;}&lt;/span&gt;/file.tar.gz -O ddd.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;위와 같이 입력하여 &lt;code&gt;ddd.tar.gz&lt;/code&gt;으로 다운로드할 수 있다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] 네트워크 - scp 서버간 파일 복사</title><link>https://kyungryeol-yoon.github.io/linux/network-commands/linux-network-scp/</link><pubDate>Tue, 11 Sep 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/network-commands/linux-network-scp/</guid><description>&lt;h2 id="scp-명령어"&gt;
 scp 명령어
 &lt;a class="heading-anchor" href="#scp-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;리눅스에서 서버 간에 파일 복사에 사용되는 명령어이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="명령어"&gt;
 명령어
 &lt;a class="heading-anchor" href="#%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;scp &lt;span class="o"&gt;{&lt;/span&gt;복사하려는 파일명&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;서버 사용자 아이디&lt;span class="o"&gt;}&lt;/span&gt;@&lt;span class="o"&gt;{&lt;/span&gt;서버 주소&lt;span class="o"&gt;}&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;서버의 복사 경로 위치&lt;span class="o"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="참고"&gt;
 참고
 &lt;a class="heading-anchor" href="#%ec%b0%b8%ea%b3%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;서버의 아이디 및 비밀번호를 알고 있어야 한다.&lt;/li&gt;
&lt;li&gt;서버의 복사 경로 위치 앞에 : (콜론)을 꼭 붙어야 한다.&lt;/li&gt;
&lt;li&gt;서버의 복사 경로 위치는 기입한 서버의 아이디 계정의 쓰기 권한이 있어야 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="scp-명령어-사용-예제"&gt;
 scp 명령어 사용 예제
 &lt;a class="heading-anchor" href="#scp-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%82%ac%ec%9a%a9-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="예제-파일-복사"&gt;
 예제) 파일 복사
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-%ed%8c%8c%ec%9d%bc-%eb%b3%b5%ec%82%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;로컬에 있는 test.txt 라는 파일을 서버에 /home/kryoon 의 Directory에 복사한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;scp ./test.txt kryoon@192.168.0.10:/home/kryoon&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-directory-복사"&gt;
 예제) Directory 복사
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-directory-%eb%b3%b5%ec%82%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;로컬에 있는 test_dir Directory를 서버에 /home/kryoon 의 Directory에 복사한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;scp -r ./test_dir kryoon@192.168.0.10:/home/kryoon&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;파일을 복사할 때와 다른 점은 옵션 -r이 추가되었다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] 네트워크 - nslookup 도메인 정보 확인</title><link>https://kyungryeol-yoon.github.io/linux/network-commands/linux-network-nslookup/</link><pubDate>Fri, 07 Sep 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/network-commands/linux-network-nslookup/</guid><description>&lt;h2 id="nslookup-명령어"&gt;
 nslookup 명령어
 &lt;a class="heading-anchor" href="#nslookup-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;네임 서버에 질의하는 프로그램이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IP 주소를 아는데 도메인을 모르거나, 도메인은 아는데 IP 주소를 모를 때 알기 위해 쓴다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DNS 정보와 연관된 도메인 정보를 확인할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;nslookup &lt;span class="o"&gt;[&lt;/span&gt;도메인 또는 아이피 입력&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="nslookup-명령어-사용-예제"&gt;
 nslookup 명령어 사용 예제
 &lt;a class="heading-anchor" href="#nslookup-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%82%ac%ec%9a%a9-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="예제-구글-조회"&gt;
 예제) 구글 조회
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-%ea%b5%ac%ea%b8%80-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;nslookup www.google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Linux] 네트워크 - netstat 네트워크 상태 확인</title><link>https://kyungryeol-yoon.github.io/linux/network-commands/linux-network-netstat/</link><pubDate>Sun, 02 Sep 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/network-commands/linux-network-netstat/</guid><description>&lt;h2 id="netstat-명령어"&gt;
 netstat 명령어
 &lt;a class="heading-anchor" href="#netstat-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;포트와 네트워크 상태를 보여준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;netstat [옵션] [| grep 포트 번호 or 서비스 명]&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="option"&gt;
 option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-l&lt;/code&gt; (listen) : 연결 가능한 상태&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-n&lt;/code&gt; (number port) : 포트 넘버&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-t&lt;/code&gt; (tcp) : tcp&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-u&lt;/code&gt; (udp) : udp&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt; (Program name / PID) : 프로그램 이름 / PID&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-a&lt;/code&gt; (all) : 모두&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;PORT : 서버에 열린 문을 의미하며 숫자로 표현된다. IP를 타고 서버에 접속할 때 서버에 여러 포트가 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;TCP&lt;/code&gt; : 속도↓, 상호 통신(신뢰성↑), 질의응답 o, stream&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UDP&lt;/code&gt; : 속도↑, 일방 통신(신뢰성↓), 질의응답 x, datagram(dgram)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;netstat 옵션은 주로 &lt;code&gt;-lntup&lt;/code&gt;를 쓴다. 그 외에 &lt;code&gt;-antup&lt;/code&gt;, &lt;code&gt;-ltup&lt;/code&gt;, &lt;code&gt;-atup&lt;/code&gt; 등을 쓴다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;/etc/services는 서비스 명 및 포트 정의 파일이고 포트 넘버를 확인 가능하다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Linux] 네트워크 - ifconfig 네트워크 정보 확인</title><link>https://kyungryeol-yoon.github.io/linux/network-commands/linux-network-ifconfig/</link><pubDate>Sat, 01 Sep 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/network-commands/linux-network-ifconfig/</guid><description>&lt;h2 id="ifconfig-명령어"&gt;
 ifconfig 명령어
 &lt;a class="heading-anchor" href="#ifconfig-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;네트워크 인터페이스 정보 확인한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ifconfig&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ifconfig -a&lt;/code&gt; : 비 활성화 장치 포함하여 모두 보기&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ifconfig&lt;/code&gt; [interface] [up / down] : 지정한 장치를 활성화 혹은 비 활성화할 때 사용&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] 프로세스 관리 - top 실시간 프로세스 모니터링</title><link>https://kyungryeol-yoon.github.io/linux/process/linux-process-top/</link><pubDate>Wed, 25 Jul 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/process/linux-process-top/</guid><description>&lt;h2 id="top-명령어"&gt;
 top 명령어
 &lt;a class="heading-anchor" href="#top-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;실시간 프로세스 모니터링 프로그램&lt;/li&gt;
&lt;li&gt;기본적으로 3초마다 화면이 갱신되고 스페이스바를 누르면 바로 갱신된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;top &lt;span class="o"&gt;(&lt;/span&gt;option&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="option"&gt;
 option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-d&lt;/code&gt; [시간] : 화면 갱신 시간 설정&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-i&lt;/code&gt; : idle 상태와 좀비 프로세스 무시&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="top-실행중-사용-가능-명령어"&gt;
 top 실행중 사용 가능 명령어
 &lt;a class="heading-anchor" href="#top-%ec%8b%a4%ed%96%89%ec%a4%91-%ec%82%ac%ec%9a%a9-%ea%b0%80%eb%8a%a5-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;k&lt;/code&gt; : kill 명령&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r&lt;/code&gt; : nice값 변경&lt;/li&gt;
&lt;li&gt;&lt;code&gt;l&lt;/code&gt; : top 맨 윗줄 항목 on/off&lt;/li&gt;
&lt;li&gt;&lt;code&gt;m&lt;/code&gt; : 메모리 항목 on/off&lt;/li&gt;
&lt;li&gt;&lt;code&gt;t&lt;/code&gt; : 프로세스와 CPU 항목 on/off&lt;/li&gt;
&lt;li&gt;&lt;code&gt;c&lt;/code&gt; : command line의 옵션 on/off&lt;/li&gt;
&lt;li&gt;&lt;code&gt;q&lt;/code&gt; : 프로그램 종료&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] 프로세스 관리 - kill 프로세스 종료</title><link>https://kyungryeol-yoon.github.io/linux/process/linux-process-kill/</link><pubDate>Sat, 07 Jul 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/process/linux-process-kill/</guid><description>&lt;h2 id="kill"&gt;
 kill
 &lt;a class="heading-anchor" href="#kill" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;프로세스 종료시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;option&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;PID:프로세스 아이디&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="optionsignal"&gt;
 option(signal)
 &lt;a class="heading-anchor" href="#optionsignal" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-1&lt;/code&gt; : 재실행(HUP)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-9&lt;/code&gt; : 강제종료(KILL)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-15&lt;/code&gt; : 기다렸다 정상 종료(TERM)&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] 프로세스 관리 - ps 프로세스 목록</title><link>https://kyungryeol-yoon.github.io/linux/process/linux-process-list-ps/</link><pubDate>Sun, 01 Jul 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/process/linux-process-list-ps/</guid><description>&lt;h2 id="ps-명령어"&gt;
 ps 명령어
 &lt;a class="heading-anchor" href="#ps-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;현재 작동하는 프로세스의 목록을 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ps &lt;span class="o"&gt;(&lt;/span&gt;옵션&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="option"&gt;
 option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-e&lt;/code&gt; : 모든 프로세스 정보 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt; : 프로세스의 다양한 정보 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-a&lt;/code&gt; : 실행중인 전체 사용자의 모든 프로세스 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-u&lt;/code&gt; : 프로세스를 실행한 사용자 정보와 프로세스 시작시간 등 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-x&lt;/code&gt; : 제어 터미널을 갖지 않는 프로세스 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ps-명령어-사용예제"&gt;
 ps 명령어 사용예제
 &lt;a class="heading-anchor" href="#ps-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%82%ac%ec%9a%a9%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="예제-1"&gt;
 예제 1)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;PID와 PPID를 확인할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ps -ef &lt;span class="p"&gt;|&lt;/span&gt;grep *** &lt;span class="o"&gt;(&lt;/span&gt;동작중인 프로세스&lt;span class="o"&gt;)&lt;/span&gt; : &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-2"&gt;
 예제 2)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;USER, PID, %CPU, %MEM, RSS, TTY, STAT, START를 확인할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;-&amp;gt; ps -aux &lt;span class="p"&gt;|&lt;/span&gt;grep *** &lt;span class="o"&gt;(&lt;/span&gt;동작된 프로세스&lt;span class="o"&gt;)&lt;/span&gt; : &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;USER&lt;/code&gt; : 프로세스를 실행시킨 사용자&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PID&lt;/code&gt; : 프로세스 ID&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%CPU&lt;/code&gt; : 최근 1분간 프로세스가 사용한 CPU시간 백분율&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%MEM&lt;/code&gt; : 최근 1분간 프로세스가 사용한 실제 메모리의 백분율&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RSS&lt;/code&gt; : 현재 프로세스가 사용하고 있는 실제 메모리 크기&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TTY&lt;/code&gt; : 프로세스를 제어하고 있는 터미널&lt;/li&gt;
&lt;li&gt;&lt;code&gt;STAT&lt;/code&gt; : 프로세스 상태 코드&lt;/li&gt;
&lt;li&gt;&lt;code&gt;START&lt;/code&gt; : 프로세스의 시작 시간&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] 7z 압축 및 해제</title><link>https://kyungryeol-yoon.github.io/linux/package/linux-file-compress-7z/</link><pubDate>Fri, 25 May 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/package/linux-file-compress-7z/</guid><description>&lt;h2 id="p7zip-설치하기"&gt;
 p7zip 설치하기
 &lt;a class="heading-anchor" href="#p7zip-%ec%84%a4%ec%b9%98%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="우분투ubuntu에서-p7zip-설치하기"&gt;
 우분투(Ubuntu)에서 p7zip 설치하기
 &lt;a class="heading-anchor" href="#%ec%9a%b0%eb%b6%84%ed%88%acubuntu%ec%97%90%ec%84%9c-p7zip-%ec%84%a4%ec%b9%98%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get install p7zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;위 명령어로 설치가 안되면 아래 명령어로 검색하셔서 설치하시길 바란다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;apt-cache search 7z&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;페도라(Fedora)에서 p7zip 설치하기&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;yum install p7zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;위 명령어로 설치가 안되면 아래 명령어로 검색하셔서 설치하시길 바란다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;yum search 7z&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="7z-압축하기"&gt;
 7z 압축하기
 &lt;a class="heading-anchor" href="#7z-%ec%95%95%ec%b6%95%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="명령어"&gt;
 명령어
 &lt;a class="heading-anchor" href="#%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;7zr a &lt;span class="o"&gt;{&lt;/span&gt;압축 파일명&lt;span class="o"&gt;}&lt;/span&gt;.zip &lt;span class="o"&gt;{&lt;/span&gt;압축할 파일 혹은 Directory1&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;압축할 파일 혹은 Directory2&lt;span class="o"&gt;}&lt;/span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="파일-압축하기"&gt;
 파일 압축하기
 &lt;a class="heading-anchor" href="#%ed%8c%8c%ec%9d%bc-%ec%95%95%ec%b6%95%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;test1, test2, test3 파일을 라고 test.7z 파일명으로 압축을 하는 명령어는 다음과 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;7zr a test.7z test1 test2 test3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="7z-압축-풀기"&gt;
 7z 압축 풀기
 &lt;a class="heading-anchor" href="#7z-%ec%95%95%ec%b6%95-%ed%92%80%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="명령어-1"&gt;
 명령어
 &lt;a class="heading-anchor" href="#%eb%aa%85%eb%a0%b9%ec%96%b4-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;7zr x &lt;span class="o"&gt;{&lt;/span&gt;압축 파일명&lt;span class="o"&gt;}&lt;/span&gt;.zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;test.7z 압축 파일을 푸는 명령어를 다음과 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;7zr x test.7z&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Linux] gz 압축 및 해제</title><link>https://kyungryeol-yoon.github.io/linux/package/linux-file-compress-gz/</link><pubDate>Wed, 09 May 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/package/linux-file-compress-gz/</guid><description>&lt;h2 id="gzip-설치하기"&gt;
 gzip 설치하기
 &lt;a class="heading-anchor" href="#gzip-%ec%84%a4%ec%b9%98%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;gzip은 리눅스에 기본으로 설치되어 있으나, 혹시 gzip 명령어를 찾을 수 없다고 나오면 아래 명령어로 설치하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ubuntu에서-unzip-설치"&gt;
 Ubuntu에서 unzip 설치
 &lt;a class="heading-anchor" href="#ubuntu%ec%97%90%ec%84%9c-unzip-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get install gzip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="gz-압축-하기"&gt;
 gz 압축 하기
 &lt;a class="heading-anchor" href="#gz-%ec%95%95%ec%b6%95-%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="명령어"&gt;
 명령어
 &lt;a class="heading-anchor" href="#%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;gzip &lt;span class="o"&gt;{&lt;/span&gt;압축 파일명&lt;span class="o"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="파일-압축하기"&gt;
 파일 압축하기
 &lt;a class="heading-anchor" href="#%ed%8c%8c%ec%9d%bc-%ec%95%95%ec%b6%95%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;aaa.jpg를 gz으로 압축한다면 아래와 같은 명령어를 사용하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;gzip aaa.jpg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;수행 결과로 aaa.jpg는 없어지고, aaa.gz 압축 파일이 생성된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;gz은 여러개의 파일을 하나로 압축하는 용도가 아니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;여러개의 파일을 압축하시려면 tar, zip, 7z 압축을 사용하시길 바란다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="gz-압축-풀기"&gt;
 gz 압축 풀기
 &lt;a class="heading-anchor" href="#gz-%ec%95%95%ec%b6%95-%ed%92%80%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="명령어-1"&gt;
 명령어
 &lt;a class="heading-anchor" href="#%eb%aa%85%eb%a0%b9%ec%96%b4-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;gzip -d &lt;span class="o"&gt;{&lt;/span&gt;압축 파일명&lt;span class="o"&gt;}&lt;/span&gt;.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;gzip으로 압축을 푸는 옵션으로 &lt;code&gt;-d&lt;/code&gt; 를 주면 된다. &lt;code&gt;-d&lt;/code&gt;는 decompress의 줄임 표현이다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] zip 압축 및 해제</title><link>https://kyungryeol-yoon.github.io/linux/package/linux-file-compress-zip/</link><pubDate>Mon, 07 May 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/package/linux-file-compress-zip/</guid><description>&lt;h2 id="zip-unzip-설치하기"&gt;
 zip, unzip 설치하기
 &lt;a class="heading-anchor" href="#zip-unzip-%ec%84%a4%ec%b9%98%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="ubuntu에서-zip-unzip-설치"&gt;
 Ubuntu에서 zip, unzip 설치
 &lt;a class="heading-anchor" href="#ubuntu%ec%97%90%ec%84%9c-zip-unzip-%ec%84%a4%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;zip, unzip이 설치되지 않은 Ubuntu에서는 아래 명령어로 설치할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="명령어"&gt;
 명령어
 &lt;a class="heading-anchor" href="#%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt-get install zip unzip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="zip-압축하기"&gt;
 zip 압축하기
 &lt;a class="heading-anchor" href="#zip-%ec%95%95%ec%b6%95%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="명령어-1"&gt;
 명령어
 &lt;a class="heading-anchor" href="#%eb%aa%85%eb%a0%b9%ec%96%b4-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;zip &lt;span class="o"&gt;{&lt;/span&gt;압축 파일명&lt;span class="o"&gt;}&lt;/span&gt;.zip &lt;span class="o"&gt;{&lt;/span&gt;압축할 파일 혹은 Directory1&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;압축할 파일 혹은 Directory2&lt;span class="o"&gt;}&lt;/span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="파일-압축하기"&gt;
 파일 압축하기
 &lt;a class="heading-anchor" href="#%ed%8c%8c%ec%9d%bc-%ec%95%95%ec%b6%95%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;특정 Directory에 모든 파일(./*)를 test.zip으로 압축한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;zip test.zip ./*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="파일-및-directory-압축하기"&gt;
 파일 및 Directory 압축하기
 &lt;a class="heading-anchor" href="#%ed%8c%8c%ec%9d%bc-%eb%b0%8f-directory-%ec%95%95%ec%b6%95%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;현재 폴더에 여러 하위 폴더가 있는데, 그것도 다 같이 압축하기 위해서는 &lt;code&gt;-r&lt;/code&gt; 이라는 옵션을 추가한다.&lt;/li&gt;
&lt;li&gt;특정 Directory에 모든 파일 및 Directory(./*)를 test.zip으로 압축한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;zip -r test.zip ./*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="zip-압축풀기"&gt;
 zip 압축풀기
 &lt;a class="heading-anchor" href="#zip-%ec%95%95%ec%b6%95%ed%92%80%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;zip파일을 압축을 푸는 명령어는 아래와 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="명령어-2"&gt;
 명령어
 &lt;a class="heading-anchor" href="#%eb%aa%85%eb%a0%b9%ec%96%b4-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;unzip &lt;span class="o"&gt;{&lt;/span&gt;압축 파일명&lt;span class="o"&gt;}&lt;/span&gt;.zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="파일-압축풀기"&gt;
 파일 압축풀기
 &lt;a class="heading-anchor" href="#%ed%8c%8c%ec%9d%bc-%ec%95%95%ec%b6%95%ed%92%80%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;test.zip 파일의 압축을 푸는 명령어는 아래와 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;unzip test.zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="특정-directory에-파일-압축풀기"&gt;
 특정 Directory에 파일 압축풀기
 &lt;a class="heading-anchor" href="#%ed%8a%b9%ec%a0%95-directory%ec%97%90-%ed%8c%8c%ec%9d%bc-%ec%95%95%ec%b6%95%ed%92%80%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;test.zip 파일을 /home/kryoon Directory에 압축을 푸는 명령어는 아래와 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;unzip test.zip -d /home/kryoon&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Linux] 파일 관리 - chown 파일/Directory 소유권 변경</title><link>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-chown/</link><pubDate>Sat, 05 May 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-chown/</guid><description>&lt;h2 id="소유권-확인"&gt;
 소유권 확인
 &lt;a class="heading-anchor" href="#%ec%86%8c%ec%9c%a0%ea%b6%8c-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;먼저 소유권을 확인하기 위해서는 아래 명령어로 확인이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ls -al&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;위 명령어를 입력하면 아래와 같은 형태로 결과물이 나온다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;-rw-r--r-- &lt;span class="m"&gt;1&lt;/span&gt; kryoon staff &lt;span class="m"&gt;36864&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="m"&gt;2017&lt;/span&gt; Currency.db&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;여기서 소유권자가 kryoon이고, 그룹 식별자가 staff이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="파일-소유권-변경"&gt;
 파일 소유권 변경
 &lt;a class="heading-anchor" href="#%ed%8c%8c%ec%9d%bc-%ec%86%8c%ec%9c%a0%ea%b6%8c-%eb%b3%80%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;root 권한에에서 아래 명령어를 실행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="명령어"&gt;
 명령어
 &lt;a class="heading-anchor" href="#%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chown &lt;span class="o"&gt;{&lt;/span&gt;소유권자&lt;span class="o"&gt;}&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;그룹식별자&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;소유권을 변경하고 싶은 파일명&lt;span class="o"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;test.sh 파일명의 소유권자를 aaa로 하고, 그룹식별자를 bbb로 변경하는 명령어는 아래와 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="예제"&gt;
 예제
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chown aaa:bbb test.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="directory-소유권-변경"&gt;
 Directory 소유권 변경
 &lt;a class="heading-anchor" href="#directory-%ec%86%8c%ec%9c%a0%ea%b6%8c-%eb%b3%80%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;root 권한에에서 아래 명령어를 실행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="명령어-1"&gt;
 명령어
 &lt;a class="heading-anchor" href="#%eb%aa%85%eb%a0%b9%ec%96%b4-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chown &lt;span class="o"&gt;{&lt;/span&gt;소유권자&lt;span class="o"&gt;}&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;그룹식별자&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;소유권을 변경하고 싶은 Directory명&lt;span class="o"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/home/test&lt;/code&gt; Directory만 소유권자를 aaa로 하고, 그룹식별자를 bbb로 변경하는 명령어는 아래와 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="예제-1"&gt;
 예제
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chown aaa:bbb /home/test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;위 명령어로 Directory 소유권은 변경하게 되면 /home/test Directory만 소유권이 변경되고, 이하 Directory는 소유권이 변경되지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="하위-directory까지-모두-소유권-변경"&gt;
 하위 Directory까지 모두 소유권 변경
 &lt;a class="heading-anchor" href="#%ed%95%98%ec%9c%84-directory%ea%b9%8c%ec%a7%80-%eb%aa%a8%eb%91%90-%ec%86%8c%ec%9c%a0%ea%b6%8c-%eb%b3%80%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;root 권한에에서 아래 명령어를 실행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="명령어-2"&gt;
 명령어
 &lt;a class="heading-anchor" href="#%eb%aa%85%eb%a0%b9%ec%96%b4-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chown -R &lt;span class="o"&gt;{&lt;/span&gt;소유권자&lt;span class="o"&gt;}&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;그룹식별자&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;소유권을 변경하고 싶은 Directory명&lt;span class="o"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/home/test&lt;/code&gt; Directory와 이하 모든 Directory 및 파일들의 소유권자를 aaa로 하고, 그룹식별자를 bbb로 변경하는 명령어는 아래와 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="예제-2"&gt;
 예제
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chown -R aaa:bbb /home/test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;위 명령어로 Directory 소유권은 변경하게 되면 &lt;code&gt;/home/test Directory&lt;/code&gt;는 물론 이하 모든 Directory 소유권이 변경된다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] 파일 관리 - chmod 파일/Directory 권한 변경</title><link>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-chmod/</link><pubDate>Tue, 01 May 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-chmod/</guid><description>&lt;h2 id="chmod-명령어"&gt;
 chmod 명령어
 &lt;a class="heading-anchor" href="#chmod-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;파일의 권한을 변경한다.&lt;/li&gt;
&lt;li&gt;chmod는 change mod의 약자이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;chmod &lt;span class="o"&gt;[&lt;/span&gt;option &lt;span class="o"&gt;(&lt;/span&gt;ex.744&lt;span class="o"&gt;)]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;변경할 파일 위치/이름&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;권한은 숫자로 표현되며 읽기(4), 쓰기(2), 실행(1)으로 나뉜다.&lt;/li&gt;
&lt;li&gt;읽고쓰기=4+2=6, 읽고실행=4+1=5, 쓰고실행=2+1=3, 읽고쓰고실행=4+2+1=7&lt;/li&gt;
&lt;li&gt;권한은 총 3구역으로 설정되며, 나 / 내가 속한 그룹 / 다른 그룹 으로 나뉜다.&lt;/li&gt;
&lt;li&gt;나는 읽고 / 내가 속한 그룹은 쓰고 / 다른 그룹은 실행 = 421&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>[Linux] 파일 관리 - touch 빈 파일 생성</title><link>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-touch/</link><pubDate>Sun, 25 Mar 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-touch/</guid><description>&lt;h2 id="touch-명령어"&gt;
 touch 명령어
 &lt;a class="heading-anchor" href="#touch-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;크기가 0 byte인 파일 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;touch &lt;span class="o"&gt;[&lt;/span&gt;파일명&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="touch-명령어-사용-예제"&gt;
 touch 명령어 사용 예제
 &lt;a class="heading-anchor" href="#touch-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%82%ac%ec%9a%a9-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="예제-1"&gt;
 예제 1)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/backup&lt;/code&gt;에 1이라는 파일 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;touch /backup/1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-2"&gt;
 예제 2)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/backup&lt;/code&gt;에 2와 3이라 파일 생성, &lt;code&gt;/test&lt;/code&gt;에 1이라는 파일 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;touch /backup/2 &lt;span class="m"&gt;3&lt;/span&gt; /test &lt;span class="m"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>객체지향 설계 5원칙 SOLID</title><link>https://kyungryeol-yoon.github.io/cs/sw-theory/object-oriented-solid/</link><pubDate>Sun, 25 Mar 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/cs/sw-theory/object-oriented-solid/</guid><description>&lt;h2 id="solid란"&gt;
 SOLID란?
 &lt;a class="heading-anchor" href="#solid%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;객체지향 설계는 긴 세월과 수많은 시행착오를 거치며 5가지 원칙이 정리되었다. 이것은 객체지향 설계의 5원칙이라고 하며, 앞글자를 따서 SOLID라고 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SPR(Single Responsibility Principle) : 단일 책임 원칙&lt;/li&gt;
&lt;li&gt;OCP(Open Closed Principle) : 개방 폐쇄 원칙&lt;/li&gt;
&lt;li&gt;LSP(Liskov Substitution Principle) : 리스코프 치환 원칙&lt;/li&gt;
&lt;li&gt;ISP(Interface Segregation Principle) : 인터페이스 분리 원칙&lt;/li&gt;
&lt;li&gt;DIP(Dependency Inversion Principle) : 의존 역전 원칙&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이 원칙들은 응집도는 높이고 결합도는 낮추자는 고전 원칙을 객체 지향의 관점에서 재정립한 것으로 볼 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="srp--단일-책임-원칙"&gt;
 SRP = 단일 책임 원칙
 &lt;a class="heading-anchor" href="#srp--%eb%8b%a8%ec%9d%bc-%ec%b1%85%ec%9e%84-%ec%9b%90%ec%b9%99" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;어떤 클래스를 변경해야 하는 이유는 오직 하나 뿐이어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="srp가-안지켜진-사례"&gt;
 SRP가 안지켜진 사례
 &lt;a class="heading-anchor" href="#srp%ea%b0%80-%ec%95%88%ec%a7%80%ec%bc%9c%ec%a7%84-%ec%82%ac%eb%a1%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;변수레벨
&lt;ul&gt;
&lt;li&gt;하나의 속성이 여러 의미를 갖는 경우&lt;/li&gt;
&lt;li&gt;어떤 곳에서는 쓰고, 어떤 곳에선 안쓰는 속성이 있는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;메소드레벨
&lt;ul&gt;
&lt;li&gt;분기처리를 위한 if문이 많을 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ocp--개방-폐쇄-원칙"&gt;
 OCP = 개방 폐쇄 원칙
 &lt;a class="heading-anchor" href="#ocp--%ea%b0%9c%eb%b0%a9-%ed%8f%90%ec%87%84-%ec%9b%90%ec%b9%99" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;소프트웨어 엔티티(클래스, 모듈, 함수 등)는 확장에 대해서는 열려 있어야 하지만 변경에 대해서는 닫혀 있어야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;즉, 자신의 확장에는 열려있고, 주변의 변화에 대해서는 닫혀 있어야 한다는 것이다.&lt;/li&gt;
&lt;li&gt;이것은 interface 를 통해 구현하여 해결한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;현실의 예를들면 상점직원이 아무리 바뀐다고해서 손님이 상품을 구매하는 데는 지장이 없다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이는 직원은 판매 인터페이스를 구현해야하기 때문이다.&lt;/li&gt;
&lt;li&gt;손님은 판매인터페이스와 소통하기 때문에 직원이 누구든 지장이 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="lsp--리스코프-치환-원칙"&gt;
 LSP = 리스코프 치환 원칙
 &lt;a class="heading-anchor" href="#lsp--%eb%a6%ac%ec%8a%a4%ec%bd%94%ed%94%84-%ec%b9%98%ed%99%98-%ec%9b%90%ec%b9%99" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;서브타입은 언제나 자신의 기반타입으로 교체할 수 있어야 한다.&lt;/li&gt;
&lt;li&gt;즉, 하위 클래스의 인스턴스는 상위형 객체 참조 변수에 대입해 상위 클래스의 인스턴스 역할을 수행하는 데 문제가 없어야 한다.&lt;/li&gt;
&lt;li&gt;이것은 OOP 4대 특성의 상속, 인터페이스 원칙이 잘 지켜진 다면 LSP는 자동으로 잘 적용된 것이다.
&lt;ul&gt;
&lt;li&gt;주로 조직도, 계층도 관점에서의 상속이 LSP를 위배하는 문제가 생긴다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="isp--인터페이스-분리-원칙"&gt;
 ISP = 인터페이스 분리 원칙
 &lt;a class="heading-anchor" href="#isp--%ec%9d%b8%ed%84%b0%ed%8e%98%ec%9d%b4%ec%8a%a4-%eb%b6%84%eb%a6%ac-%ec%9b%90%ec%b9%99" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;클라이언트는 자신이 사용하지 않는 메소드에 의존 관계를 맺으면 안된다.&lt;/li&gt;
&lt;li&gt;ISP는 SRP와 비슷하지만 인터페이스를 통한 다른 해결책을 제안하고 있다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;예를 들어 class 사람 implements 군인 이면 군인 홍길동 = new 사람() 을 통해 군인 인터페이스의 메소드만을 사용하도록 제한하는 것이다.&lt;/code&gt; SRP였다면 class를 나눠버렸겠지만.. 일반적으론 ISP보다 SRP 할 것이 권장된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="dip--의존-역전-원칙"&gt;
 DIP = 의존 역전 원칙
 &lt;a class="heading-anchor" href="#dip--%ec%9d%98%ec%a1%b4-%ec%97%ad%ec%a0%84-%ec%9b%90%ec%b9%99" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;고차원 모듈은 저차원 모듈에 의존하면 안된다.&lt;/li&gt;
&lt;li&gt;추상화된 것은 구체적인 것에 의존하면 안된다.&lt;/li&gt;
&lt;li&gt;구체적인 것이 추상화된 것에 의존해야 한다.&lt;/li&gt;
&lt;li&gt;자주 변경되는 클래스에 의존하지 말자. 로 요약될 수 있다.&lt;/li&gt;
&lt;li&gt;즉, 자신보다 변하기 쉬운 것에 의존하지 말라는 것이다.&lt;/li&gt;
&lt;li&gt;해결방법은 OCP와 비슷한데, 구체적인 class가 아닌, 인터페이스에 의존함으로써 DIP를 해결한다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] 파일 관리 - find 파일/Directory 검색</title><link>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-find/</link><pubDate>Sun, 11 Mar 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-find/</guid><description>&lt;h2 id="find-명령어"&gt;
 find 명령어
 &lt;a class="heading-anchor" href="#find-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;파일 및 Directory 검색한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;find &lt;span class="o"&gt;[&lt;/span&gt;경로&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;-name&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;파일 및 Directory 명&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;-type d/f&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-1"&gt;
 예제 1)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc&lt;/code&gt; 안에서 이름이 config인 파일 및 Directory 검색&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;find /etc/ -name config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-2"&gt;
 예제 2)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;최상위에서 이름이 home이고 타입이 Directory인 것만 검색한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;find / -name home -type d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-3"&gt;
 예제 3)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-3" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;최상위에서 이름이 passwd이고 타입이 파일인 것만 검색한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;find / -name passwd -type f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="find-고급-명령어"&gt;
 find 고급 명령어
 &lt;a class="heading-anchor" href="#find-%ea%b3%a0%ea%b8%89-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="예제-1-1"&gt;
 예제 1)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-1-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;파일에 접근한지 n일 이상 검색한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;find &lt;span class="o"&gt;[&lt;/span&gt;경로&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;-atime&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;+n&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;-n일 경우 n일 이내&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-2-1"&gt;
 예제 2)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-2-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;파일을 생성한지 n일 이상 검색한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;find &lt;span class="o"&gt;[&lt;/span&gt;경로&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;-ctime&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;+n&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;-n일 경우 n일 이내&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-3-1"&gt;
 예제 3)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-3-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;파일을 변경한지 n일 이상 검색한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;find &lt;span class="o"&gt;[&lt;/span&gt;경로&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;-mtime&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;+n&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;-n일 경우 n일 이내&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-4"&gt;
 예제 4)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;파일에 접근한지 n분 이상 검색한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;find &lt;span class="o"&gt;[&lt;/span&gt;경로&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;-amin&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;+n&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;-n일 경우 n분 이내&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-5"&gt;
 예제 5)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;파일을 생성한지 n분 이상 검색한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;find &lt;span class="o"&gt;[&lt;/span&gt;경로&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;-cmin&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;+n&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;-n일 경우 n분 이내&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-6"&gt;
 예제 6)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-6" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;파일을 변경한지 n분 이상 검색한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;find &lt;span class="o"&gt;[&lt;/span&gt;경로&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;-mmin&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;+n&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;-n일 경우 n분 이내&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-7"&gt;
 예제 7)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-7" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[파일 및 Directory 명]&lt;/code&gt;이 생성후 수정된 모든 파일 및 Directory 검색한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;find &lt;span class="o"&gt;[&lt;/span&gt;경로&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;-newer&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;파일 및 Directory 명&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-8"&gt;
 예제 8)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;여러 명령어를 한줄에 줄 수도 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;find / -name a
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;find / -name b
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;find / -name a -o -name b &lt;span class="c1"&gt;## 이렇게 한줄로 줄여서 쓸수도 있음.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Linux] 파일 관리 - cat 파일 내용 출력</title><link>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-cat/</link><pubDate>Fri, 02 Mar 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-cat/</guid><description>&lt;h2 id="cat-명령어"&gt;
 cat 명령어
 &lt;a class="heading-anchor" href="#cat-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;파일 내용 출력한다.&lt;/li&gt;
&lt;li&gt;입/출력 리다이렉션(&amp;gt;, &amp;raquo;)을 같이 사용해서 파일 생성 및 파일 내용 입력한다.&lt;/li&gt;
&lt;li&gt;cat는 catch의 약자이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="문법"&gt;
 문법
 &lt;a class="heading-anchor" href="#%eb%ac%b8%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cat &lt;span class="o"&gt;[&lt;/span&gt;옵션&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;파일명&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-1"&gt;
 예제 1)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc/passwd&lt;/code&gt; 파일 내용 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cat /etc/passwd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-2"&gt;
 예제 2)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;좌측에 줄 번호를 출력하여 &lt;code&gt;/etc/passwd&lt;/code&gt; 파일 내용 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cat -n /etc/passwd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;#&lt;/code&gt;는 주석을 의미한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="예제-3"&gt;
 예제 3)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-3" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cat &amp;gt; &lt;span class="o"&gt;[&lt;/span&gt;파일명&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;[&lt;/span&gt;파일 내용 입력&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;ctrl + d를 누르면 입력 완료&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;파일이 있으면 내용을 덮어쓰고 없으면 생성한뒤 내용을 입력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="예제-4"&gt;
 예제 4)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cat &amp;gt;&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt;파일명&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;[&lt;/span&gt;추가할 내용 입력&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;파일이 있으면 내용을 추가하고 없으면 생성한뒤 내용을 입력한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&lt;/code&gt; (쓰기) : 1. 파일생성 , 2. 덮어쓰기&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; (추가) : 1. 파일생성 , 2. 내용 추가&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] 파일 관리 - tail 파일 내용 제일 아래줄부터 출력</title><link>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-tail/</link><pubDate>Thu, 22 Feb 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-tail/</guid><description>&lt;h2 id="tail-명령어"&gt;
 tail 명령어
 &lt;a class="heading-anchor" href="#tail-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;파일의 내용을 제일 아래 라인부터 화면에 출력한다.&lt;/li&gt;
&lt;li&gt;파일 내용을 아래에서 부터 기본 10라인 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;tail &lt;span class="o"&gt;(&lt;/span&gt;옵션&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;보고 싶은 파일 위치/이름&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="option"&gt;
 option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-[숫자]&lt;/code&gt; : 지정한 숫자만큼 행을 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-c&lt;/code&gt; (&amp;ndash;bytes=K) : 지정한 바이트 수 만큼 파일의 마지막 부분을 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt; : 지정한 파일의 추가된 데이터를 실시간으로 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-F&lt;/code&gt; : 로그 파일 rotation이 일어나도 끊기지 않고 조회가 가능&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-n&lt;/code&gt; (&amp;ndash;lines=K) : 파일의 마지막 부분을 지정한 라인만큼 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-q&lt;/code&gt; (&amp;ndash;quiet, &amp;ndash;silent) : 내용을 출력하기 전 항상 파일명을 출력하지 않는다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-s&lt;/code&gt; (&amp;ndash;sleep-interal=N) : 지정한 파일을 n초 만큼 sleep 상태였다가 다시 확인 (with -f)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v&lt;/code&gt; (&amp;ndash;verbose) : 내용을 출력하기 전 항상 파일명을 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;error_log 파일을 &lt;code&gt;tail -f error_log&lt;/code&gt; 명령으로 모니터링하고 있다. 이 error_log 파일은 특정 시간에 로테이션(현재까지 로그는 다른 파일명으로 변경되고 새롭게 error_log 파일이 생성)된다고 하자. 로테이션이 이뤄지게 되면, &lt;code&gt;tail -f&lt;/code&gt; 명령을 다시 실행해서 모니터링해야 한다. 그러나 &lt;code&gt;-F&lt;/code&gt; 옵션은 같은 파일명으로 새로 생성된 파일을 자동으로 파악하여 재실행없이 계속 모니터링할 수 있다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="tail-명령어-사용-예제"&gt;
 tail 명령어 사용 예제
 &lt;a class="heading-anchor" href="#tail-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%82%ac%ec%9a%a9-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="예제-1"&gt;
 예제 1)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc/passwd&lt;/code&gt; 파일 내용을 아래줄부터 5라인 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;tail -5 /etc/passwd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-2"&gt;
 예제 2)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc/passwd&lt;/code&gt; 파일 내용을 아래줄부터 10라인 출력하고, 좌측에 라인 번호를 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;tail /etc/passwd &lt;span class="p"&gt;|&lt;/span&gt; cat -n&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Linux] 파일 관리 - head 파일 내용 윗줄부터 출력</title><link>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-head/</link><pubDate>Sun, 11 Feb 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-head/</guid><description>&lt;h2 id="head-명령어"&gt;
 head 명령어
 &lt;a class="heading-anchor" href="#head-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;파일 내용을 위에서 부터 기본 10라인 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;head &lt;span class="o"&gt;(&lt;/span&gt;-숫자&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;파일명&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="option"&gt;
 option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-[숫자]&lt;/code&gt; : 지정한 숫자만큼 행을 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-c&lt;/code&gt; (&amp;ndash;bytes=[-]K) : 지정한 바이트만큼 출력 (지정한 바이트 앞에 &amp;lsquo;-&amp;lsquo;가 붙으면 지정한만큼 마지막부터 제외하고 출력)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-n&lt;/code&gt; (&amp;ndash;lines=[-]K) : 기본적으로 10줄의 출력 대신 지정한 행만큼 출력 (지정한 숫자 앞에 &amp;lsquo;-&amp;lsquo;가 붙으면 지정한만큼 마지막부터 제외하고 출력)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-q&lt;/code&gt; (&amp;ndash;quiet, &amp;ndash;silent) : 내용을 출력하기 전 항상 파일명을 출력하지 않는다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v&lt;/code&gt; (&amp;ndash;verbose) : 내용을 출력하기 전 항상 파일명을 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="head-명령어-사용-예제"&gt;
 head 명령어 사용 예제
 &lt;a class="heading-anchor" href="#head-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%82%ac%ec%9a%a9-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="예제1"&gt;
 예제1)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc/passwd&lt;/code&gt; 파일 내용을 윗라인부터 5라인 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;head -5 /etc/passwd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;head -n &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;파일명&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;-n&lt;/code&gt; 옵션은 생략이 가능
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="예제2"&gt;
 예제2)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;byte 단위로 내용을 보고자 한다면 아래와 같이 -c 옵션을 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;head -c &lt;span class="m"&gt;100&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제3"&gt;
 예제3)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c3" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc/passwd&lt;/code&gt; 파일 내용을 윗줄부터 10라인 출력하고, 좌측에 라인 번호를 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;head /etc/passwd &lt;span class="p"&gt;|&lt;/span&gt; cat -n&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제4"&gt;
 예제4)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;파일 명이 입력되지 않으면 표준입력을 읽어들이며, &amp;gt; 를 이용하여 다음과 같이 화면의 내용을 다른 파일로 저장할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;head file.txt &amp;gt; head_file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Linux] 파일 관리 - mv 파일/Directory 이동</title><link>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-move/</link><pubDate>Wed, 07 Feb 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-move/</guid><description>&lt;h2 id="mv-명령어"&gt;
 mv 명령어
 &lt;a class="heading-anchor" href="#mv-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;파일/Directory를 이동시키거나 이름을 바꿔준다. mv는 move의 약자이다.
&lt;ul&gt;
&lt;li&gt;이동하고 싶은 위치에 같은 이름의 파일명이 존재 하지 않을 경우 이동&lt;/li&gt;
&lt;li&gt;이동하고 싶은 위치에 같은 이름의 파일명이 존재 할 경우 이름 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mv &lt;span class="o"&gt;[&lt;/span&gt;대상 파일의 위치/이름&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;이동하고 싶은 위치/이름&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="mv-명령어-사용-예제"&gt;
 mv 명령어 사용 예제
 &lt;a class="heading-anchor" href="#mv-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%82%ac%ec%9a%a9-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="예제-1"&gt;
 예제 1
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;test1 파일을 /backup 으로 이동한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mv /test/test1 /backup&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="예제-2"&gt;
 예제 2
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;passwd 파일을 pw로 이름 변경한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mv /backup/passwd /backup/pw&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] 파일 관리 - cp 파일/Directory 복사</title><link>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-copy/</link><pubDate>Mon, 05 Feb 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-copy/</guid><description>&lt;h2 id="cp-명령어"&gt;
 cp 명령어
 &lt;a class="heading-anchor" href="#cp-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;파일/Directory을 복사한다.&lt;/li&gt;
&lt;li&gt;cp는 copy의 약자이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cp &lt;span class="o"&gt;(&lt;/span&gt;옵션&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;대상 파일의 위치/이름&lt;span class="o"&gt;(&lt;/span&gt;여러 개 가능&lt;span class="o"&gt;)]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;복사하고 싶은 위치/이름&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="option"&gt;
 option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-r&lt;/code&gt; : 하위 Directory와 파일 전체를 복사&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt; : 소유주, 그룹, 권한, 시간 정보를 보존하여 복사&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;복사하고 싶은 위치에 같은 이름의 파일명이 존재 할 경우 덮어쓰기(y/n?, y=yes)를 묻는다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="cp-명령어-사용-예제"&gt;
 CP 명령어 사용 예제
 &lt;a class="heading-anchor" href="#cp-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%82%ac%ec%9a%a9-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="예제-1"&gt;
 예제 1)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;inittab파일과 passwd파일과 grub.conf파일을 /backup Directory에 복사한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cp /etc/inittab /etc/passwd /boot/grub/grub.conf /backup&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-2"&gt;
 예제 2)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;skel 폴더(하위 Directory 및 파일 전체 포함)를 /backup 안에 복사한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cp -r /etc/skel /backup&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-3"&gt;
 예제 3)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-3" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;passwd 파일을 /backup Directory로 보존 복사한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cp -p /etc/passwd /backup&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-4"&gt;
 예제 4)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;inittab 파일을 init로 이름 변경 복사한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cp /etc/inittab /backup/init&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Linux] tar, gz 압축 및 해제</title><link>https://kyungryeol-yoon.github.io/linux/package/linux-file-compress-tar-gz/</link><pubDate>Fri, 02 Feb 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/package/linux-file-compress-tar-gz/</guid><description>&lt;h2 id="tar로-압축하기"&gt;
 tar로 압축하기
 &lt;a class="heading-anchor" href="#tar%eb%a1%9c-%ec%95%95%ec%b6%95%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;tar -cvf &lt;span class="o"&gt;[&lt;/span&gt;파일명.tar&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;폴더명&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;ex&lt;span class="o"&gt;)&lt;/span&gt; abc라는 폴더를 aaa.tar로 압축하고자 한다면
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &amp;gt; tar -cvf aaa.tar abc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="tar-압축-풀기"&gt;
 tar 압축 풀기
 &lt;a class="heading-anchor" href="#tar-%ec%95%95%ec%b6%95-%ed%92%80%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;tar -xvf &lt;span class="o"&gt;[&lt;/span&gt;파일명.tar&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;ex&lt;span class="o"&gt;)&lt;/span&gt; aaa.tar라는 tar파일 압축을 풀고자 한다면
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &amp;gt; tar -xvf aaa.tar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="targz로-압축하기"&gt;
 tar.gz로 압축하기
 &lt;a class="heading-anchor" href="#targz%eb%a1%9c-%ec%95%95%ec%b6%95%ed%95%98%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&amp;gt; tar -zcvf &lt;span class="o"&gt;[&lt;/span&gt;파일명.tar.gz&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;폴더명&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;ex&lt;span class="o"&gt;)&lt;/span&gt; abc라는 폴더를 aaa.tar.gz로 압축하고자 한다면
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &amp;gt; tar -zcvf aaa.tar.gz abc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="targz-압축-풀기"&gt;
 tar.gz 압축 풀기
 &lt;a class="heading-anchor" href="#targz-%ec%95%95%ec%b6%95-%ed%92%80%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;tar -zxvf &lt;span class="o"&gt;[&lt;/span&gt;파일명.tar.gz&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;ex&lt;span class="o"&gt;)&lt;/span&gt; aaa.tar.gz라는 tar.gz파일 압축을 풀고자 한다면
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &amp;gt; tar -zxvf aaa.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;위의 옵션들을 포함한 그나마 자주 사용되는 tar 명령어의 옵션들은 아래와 같다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;옵션&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-c&lt;/code&gt; : 파일을 tar로 묶음&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt; : 파일 권한을 저장&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v&lt;/code&gt; : 묶거나 파일을 풀 때 과정을 화면으로 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt; : 파일 이름을 지정&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-C&lt;/code&gt; : 경로를 지정&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-x&lt;/code&gt; : tar 압축을 풂&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-z&lt;/code&gt; : gzip으로 압축하거나 해제함&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] 파일 관리 - rmdir, rm</title><link>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-remove/</link><pubDate>Mon, 15 Jan 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-remove/</guid><description>&lt;h2 id="rmdir-명령어"&gt;
 rmdir 명령어
 &lt;a class="heading-anchor" href="#rmdir-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;비어있는 Directory 삭제한다.&lt;/li&gt;
&lt;li&gt;rmdir는 remove directory의 약자이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="문법"&gt;
 문법
 &lt;a class="heading-anchor" href="#%eb%ac%b8%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;rmdir &lt;span class="o"&gt;(&lt;/span&gt;옵션&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;삭제할 Directory 이름&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="option"&gt;
 option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;p&lt;/code&gt; : 상위 Directory도 삭제&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="예제-1"&gt;
 예제 1)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;rmdir aaa&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;빈 Directory aaa 삭제한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="예제-2"&gt;
 예제 2)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;rmdir -p /a/b/c&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;빈 Directory a, b, c,를 한 번에 삭제한다.&lt;/li&gt;
&lt;li&gt;파일이 존재할 경우 서브 Directory는 그대로 존재한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="파일-삭제"&gt;
 파일 삭제
 &lt;a class="heading-anchor" href="#%ed%8c%8c%ec%9d%bc-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;rm &lt;span class="o"&gt;[&lt;/span&gt;option&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;삭제할 파일 위치/이름&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;remove : 파일을 삭제한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="option-1"&gt;
 option
 &lt;a class="heading-anchor" href="#option-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-r&lt;/code&gt; : Directory와 그 하부 파일까지 삭제 (하부파일이 있는 Directory는 한번에 삭제불가)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt; : 삭제 여부를 묻지 않고 바로 삭제&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-rf&lt;/code&gt; : 삭제 여부를 묻지 않으며 하부 파일이 있는 Directory까지 삭제&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="rm-명령어"&gt;
 rm 명령어
 &lt;a class="heading-anchor" href="#rm-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;파일 및 Directory 삭제한다.&lt;/li&gt;
&lt;li&gt;rm은 remove의 약자이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;rm &lt;span class="o"&gt;(&lt;/span&gt;옵션&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;삭제할 파일 명 및 Directory 명&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="option-2"&gt;
 option
 &lt;a class="heading-anchor" href="#option-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-r&lt;/code&gt; : 일반 파일은 그냥 지우고 Directory면 Directory를 포함한 하위 경로와 파일 모두를 지운다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-i&lt;/code&gt; : 지울 것인지 확인을 한다 (y,n)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt; : 물어보지 않고 지운다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-rf&lt;/code&gt; : 삭제 여부를 묻지 않으며 하부 파일이 있는 Directory까지 삭제&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;주로 &lt;code&gt;rm -rf&lt;/code&gt; 옵션을 쓴다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="rm-명령어-사용-예제"&gt;
 rm 명령어 사용 예제
 &lt;a class="heading-anchor" href="#rm-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%82%ac%ec%9a%a9-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="예제-파일-삭제"&gt;
 예제) 파일 삭제
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-%ed%8c%8c%ec%9d%bc-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="test-파일을-삭제한다"&gt;
 test 파일을 삭제한다.
 &lt;a class="heading-anchor" href="#test-%ed%8c%8c%ec%9d%bc%ec%9d%84-%ec%82%ad%ec%a0%9c%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;rm test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="test-파일-삭제시-정말로-지울것인지-질의를-한다"&gt;
 test 파일 삭제시 정말로 지울것인지 질의를 한다.
 &lt;a class="heading-anchor" href="#test-%ed%8c%8c%ec%9d%bc-%ec%82%ad%ec%a0%9c%ec%8b%9c-%ec%a0%95%eb%a7%90%eb%a1%9c-%ec%a7%80%ec%9a%b8%ea%b2%83%ec%9d%b8%ec%a7%80-%ec%a7%88%ec%9d%98%eb%a5%bc-%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;rm -i test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="test-파일-삭제시-강제-실행한다"&gt;
 test 파일 삭제시 강제 실행한다.
 &lt;a class="heading-anchor" href="#test-%ed%8c%8c%ec%9d%bc-%ec%82%ad%ec%a0%9c%ec%8b%9c-%ea%b0%95%ec%a0%9c-%ec%8b%a4%ed%96%89%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;rm -f test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-directory-삭제"&gt;
 예제) Directory 삭제
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-directory-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="test-dir-directory를-삭제한다"&gt;
 test-dir Directory를 삭제한다.
 &lt;a class="heading-anchor" href="#test-dir-directory%eb%a5%bc-%ec%82%ad%ec%a0%9c%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;rm -r testdir&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="testdir-directory의-안에-파일이-있던-없던-무시하고-무조건-지운다"&gt;
 testdir Directory의 안에 파일이 있던 없던 무시하고 무조건 지운다.
 &lt;a class="heading-anchor" href="#testdir-directory%ec%9d%98-%ec%95%88%ec%97%90-%ed%8c%8c%ec%9d%bc%ec%9d%b4-%ec%9e%88%eb%8d%98-%ec%97%86%eb%8d%98-%eb%ac%b4%ec%8b%9c%ed%95%98%ea%b3%a0-%eb%ac%b4%ec%a1%b0%ea%b1%b4-%ec%a7%80%ec%9a%b4%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;rm -rf testdir&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Spring] Annotation &amp; Reflection이란?</title><link>https://kyungryeol-yoon.github.io/backend/spring/spring-annotation-reflection/</link><pubDate>Sat, 13 Jan 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/spring/spring-annotation-reflection/</guid><description>&lt;h2 id="annotation이란"&gt;
 Annotation이란?
 &lt;a class="heading-anchor" href="#annotation%ec%9d%b4%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;코드 사이에 주석처럼 쓰이며 특별한 의미, 기능을 수행하도록 하는 기술이다.\
프로그램에게 추가적인 정보를 제공해주는 메타데이터라고 볼 수 있다.\
&lt;strong&gt;meta data&lt;/strong&gt; : 데이터를 위한 데이터&lt;/p&gt;
&lt;h3 id="다음은-어노테이션의-용도를-나타낸-것이다"&gt;
 다음은 어노테이션의 용도를 나타낸 것이다.
 &lt;a class="heading-anchor" href="#%eb%8b%a4%ec%9d%8c%ec%9d%80-%ec%96%b4%eb%85%b8%ed%85%8c%ec%9d%b4%ec%85%98%ec%9d%98-%ec%9a%a9%eb%8f%84%eb%a5%bc-%eb%82%98%ed%83%80%eb%82%b8-%ea%b2%83%ec%9d%b4%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;컴파일러에게 코드 작성 문법 에러를 체크하도록 정보를 제공한다.\
소프트웨어 개발 툴이 빌드나 배치시 코드를 자동으로 생성할 수 있도록 정보를 제공한다.\
실행시(런타임시)특정 기능을 실행하도록 정보를 제공한다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;코드가 실행되는 중에 Reflection을 이용하여 추가 정보를 획득하여 기능을 실시한다.&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="reflection이란"&gt;
 Reflection이란?
 &lt;a class="heading-anchor" href="#reflection%ec%9d%b4%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Heap 영역에 로드된 Class 타입의 객체를 통해, 원하는 클래스의 인스턴스를 생성할 수 있도록 지원하고, 인스턴스의 필드와 메소드를 접근 제어자와 상관 없이 사용할 수 있도록 지원하는 API\
Java와 같은 객체 지향 프로그래밍 언어에서 Reflection을 사용하면 컴파일 타임에 인터페이스, 필드, 메소드의 이름을 알지 못해도 실행 중에 클래스, 인터페이스, 필드 및 메소드에 접근할 수 있다.&lt;/p&gt;
&lt;h3 id="방법"&gt;
 방법
 &lt;a class="heading-anchor" href="#%eb%b0%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;클래스.class로 가져오기&lt;/li&gt;
&lt;li&gt;인스턴스.getClass()로 가져오기&lt;/li&gt;
&lt;li&gt;Class.forName(&amp;ldquo;클래스명&amp;rdquo;)으로 가져오기&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Member&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;protected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nickname&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Member&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Member&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nickname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nickname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nickname&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;speak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;비밀번호 486 입니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Member{&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;name=&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;\&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;, age=&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;, nickname=&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nickname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;\&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;}&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ClassNotFoundException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;memberClass&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;identityHashCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memberClass&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;KyungRyeol&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Chris&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;memberClass2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;identityHashCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memberClass2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;memberClass3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{패키지명}.Member&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;identityHashCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memberClass3&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="getconstructor를-통해-생성자를-얻어-오고-newinstance를-통해-member-인스턴스를-동적으로-생성해-줄-수-있다"&gt;
 getConstructor()를 통해 생성자를 얻어 오고, newInstance()를 통해 Member 인스턴스를 동적으로 생성해 줄 수 있다.
 &lt;a class="heading-anchor" href="#getconstructor%eb%a5%bc-%ed%86%b5%ed%95%b4-%ec%83%9d%ec%84%b1%ec%9e%90%eb%a5%bc-%ec%96%bb%ec%96%b4-%ec%98%a4%ea%b3%a0-newinstance%eb%a5%bc-%ed%86%b5%ed%95%b4-member-%ec%9d%b8%ec%8a%a4%ed%84%b4%ec%8a%a4%eb%a5%bc-%eb%8f%99%ec%a0%81%ec%9c%bc%eb%a1%9c-%ec%83%9d%ec%84%b1%ed%95%b4-%ec%a4%84-%ec%88%98-%ec%9e%88%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Member의 모든 생성자 출력&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;memberClass&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Arrays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memberClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConstructors&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Member의 기본 생성자를 통한 인스턴스 생성&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Constructor&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;constructor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;memberClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConstructor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;member2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newInstance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;member2 = &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;member2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Member의 다른 생성자를 통한 인스턴스 생성&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Constructor&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fullConstructor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;memberClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConstructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;member3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fullConstructor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;KyungRyeol&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;dev doodles&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;member3 = &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;member3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="인스턴스의-필드와-메소드를-접근-제어자와-상관-없이-접근"&gt;
 인스턴스의 필드와 메소드를 접근 제어자와 상관 없이 접근
 &lt;a class="heading-anchor" href="#%ec%9d%b8%ec%8a%a4%ed%84%b4%ec%8a%a4%ec%9d%98-%ed%95%84%eb%93%9c%ec%99%80-%eb%a9%94%ec%86%8c%eb%93%9c%eb%a5%bc-%ec%a0%91%ea%b7%bc-%ec%a0%9c%ec%96%b4%ec%9e%90%ec%99%80-%ec%83%81%ea%b4%80-%ec%97%86%ec%9d%b4-%ec%a0%91%ea%b7%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;getDeclaredFileds()를 통해 클래스의 인스턴스 변수를 모두 가져올 수 있고, get()을 통해 필드 값을 반환받을 수 있고, set() 을 통해 필드 값을 수정할 수 있는 것을 알 수 있다.\
이때 주의할 점은 private 접근 제어자가 있는 필드에 접근할 때는 setAccessible()의 인자를 true로 넘겨주어야 한다.\
메소드도 getDeclaredMethod()를 통해 메소드를 가져올 수 있다.\
이때 메소드의 이름과 파라미터의 타입을 같이 인자로 넘겨줘야 한다.\
마찬가지로 private 접근 제어자가 있는 메소드에 접근할 때는 setAccessible()의 인자를 true로 설정해야 한다.\
마지막으로 invoke() 메소드를 통해 리플렉션 API로 얻어 온 메소드를 호출할 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;KyungRyeol&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;dev doodles&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Member&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;memberClass&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 필드 접근&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;memberClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDeclaredFields&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAccessible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;KyungRyeol&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 메소드 접근&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;speakMethod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;memberClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDeclaredMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;speak&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;speakMethod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Reflection Test&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;secretMethod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;memberClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDeclaredMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;secret&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;secretMethod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAccessible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;secretMethod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="장점"&gt;
 장점
 &lt;a class="heading-anchor" href="#%ec%9e%a5%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;런타임 시점에서 클래스의 인스턴스를 생성하고, 접근 제어자와 관계 없이 필드와 메소드에 접근하여 필요한 작업을 수행할 수 있는 유연성을 가지고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="단점"&gt;
 단점
 &lt;a class="heading-anchor" href="#%eb%8b%a8%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;캡슐화를 저해한다.&lt;/li&gt;
&lt;li&gt;런타임 시점에서 인스턴스를 생성하므로 컴파일 시점에서 해당 타입을 체크할 수 없다.&lt;/li&gt;
&lt;li&gt;런타임 시점에서 인스턴스를 생성하므로 구체적인 동작 흐름을 파악하기 어렵다.&lt;/li&gt;
&lt;li&gt;단순히 필드 및 메소드를 접근할 때보다 Reflection을 사용하여 접근할 때 성능이 느리다. (모든 상황에서 성능이 느리지는 않음)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Reflection API를 통해 런타임 중, 클래스 정보에 접근하여 클래스를 원하는 대로 조작할 수 있다.\
심지어 private 접근 제어자로 선언한 필드나 메소드까지 조작이 가능하다.\
프레임워크와 같이 큰 규모의 개발 단계에서는 수많은 객체와 의존 관계를 파악하기 어렵다.\
이때 Reflection을 사용하면 동적으로 클래스를 만들어서 의존 관계를 맺어줄 수 있다.\&lt;/p&gt;
&lt;p&gt;가령, Spring의 Bean Factory를 보면, @Controller, @Service, @Repository 등의 Annotation만 붙이면 Bean Factory에서 알아서 해당 Annotation이 붙은 클래스를 생성하고 관리해 주는 것을 알 수 있다.\
개발자는 Bean Factory에 해당 클래스를 알려준 적이 없는데, 이것이 가능한 이유는 바로 Reflection 덕분이다.\
런타임에 해당 Annotation이 붙은 클래스를 탐색하고 발견한다면, Reflection을 통해 해당 클래스의 인스턴스를 생성하고 필요한 필드를 주입하여 Bean Factory에 저장하는 식으로 사용이 된다.\
물론, 캡슐화를 저해하므로 꼭 필요한 상황에서만 사용하는 것이 좋다.&lt;/p&gt;</description></item><item><title>[Linux] 파일 관리 - mkdir Directory 생성</title><link>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-mkdir/</link><pubDate>Thu, 11 Jan 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-mkdir/</guid><description>&lt;h2 id="mkdir-명령어"&gt;
 mkdir 명령어
 &lt;a class="heading-anchor" href="#mkdir-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Directory 생성한다.&lt;/li&gt;
&lt;li&gt;mkdir는 make directory의 약자이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mkdir &lt;span class="o"&gt;[&lt;/span&gt;생성할 Directory 이름&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="option"&gt;
 option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt; : 상위 Directory까지 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="mkdir-명령어-사용예제"&gt;
 mkdir 명령어 사용예제
 &lt;a class="heading-anchor" href="#mkdir-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%82%ac%ec%9a%a9%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="예제-1"&gt;
 예제 1)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;최상위 Directory에 test Directory를 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mkdir /test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;이 명령어는 root 권한이 없다면 생성되지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;kryoon@localhost ~&lt;span class="o"&gt;]&lt;/span&gt;$ mkdir /test
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;mkdir: /test: Permission denied&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;최상위 Directory에 Directory를 생성하려면 root 권한이 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="예제-2"&gt;
 예제 2)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;현재 Directory에서 a Directory 안에 b라는 Directory 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mkdir a/b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;이 명령어는 현재 Directory에서 aDirectory가 존재하지 않는다면 생성되지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;kryoon@localhost ~&lt;span class="o"&gt;]&lt;/span&gt;$ mkdir a/b
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;mkdir: a: No such file or directory&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;여러 경로(a/b) 존재시에 항상 마지막 경로(b)가 타겟이 된다.&lt;/li&gt;
&lt;li&gt;위의 명령어는 aDirectory와 그 안에 bDirectory를 생성하라는 것이 아니라, aDirectory가 존재할 경우 그 안에 b라는 Directory를 생성하라는 뜻이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="예제-3"&gt;
 예제 3)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-3" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;현재 Directory에서 a Directory를 생성한뒤 그안에 b라는 Directory 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mkdir -p a/b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Linux] 파일 관리 - pwd, cd</title><link>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-directory/</link><pubDate>Tue, 09 Jan 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-directory/</guid><description>&lt;h2 id="pwd-명령어"&gt;
 pwd 명령어
 &lt;a class="heading-anchor" href="#pwd-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;현재 위치의 절대경로를 조회한다.&lt;/li&gt;
&lt;li&gt;pwd는 print working directory의 약자이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;pwd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제"&gt;
 예제
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;kryoon@localhost ~&lt;span class="o"&gt;]&lt;/span&gt;$ &lt;span class="nb"&gt;pwd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;/home/kryoon&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cd-명령어"&gt;
 cd 명령어
 &lt;a class="heading-anchor" href="#cd-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;다른 Directory로 이동한다.&lt;/li&gt;
&lt;li&gt;cd는 change directory의 약자이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법-1"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;이동할 Directory의 위치 &lt;span class="o"&gt;(&lt;/span&gt;상대경로 or 절대경로&lt;span class="o"&gt;)]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cd-명령어-사용-예제"&gt;
 cd 명령어 사용 예제
 &lt;a class="heading-anchor" href="#cd-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%82%ac%ec%9a%a9-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="예제-1"&gt;
 예제 1)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;로그인된 사용자의 홈 Directory로 이동한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;cd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-2"&gt;
 예제 2)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/home&lt;/code&gt; Directory로 이동한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /home&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-3"&gt;
 예제 3)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-3" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;현재 Directory로 이동한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-4"&gt;
 예제 4)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;상위 Directory로 이동한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ..&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-5"&gt;
 예제 5)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;로그인된 사용자의 홈 Directory로 이동한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-6"&gt;
 예제 6)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-6" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;지정된 계정의 홈 Directory로 이동한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~계정명&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;NOTE&lt;/code&gt; : 홈 Directory&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;계정 전용 공간&lt;/li&gt;
&lt;li&gt;계정 접속 위치&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Linux] 파일 관리 -ls 파일 목록 조회</title><link>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-list/</link><pubDate>Fri, 05 Jan 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/file-commands/linux-file-manage-list/</guid><description>&lt;h2 id="ls-명령어"&gt;
 ls 명령어
 &lt;a class="heading-anchor" href="#ls-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;현재 위치 혹은 원하는 위치에 있는 모든 파일 목록을 보여준다.&lt;/li&gt;
&lt;li&gt;ls는 list의 약자이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ls &lt;span class="o"&gt;(&lt;/span&gt;옵션&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;경로:생략하면 현재 위치&lt;span class="o"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="option"&gt;
 Option
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-l&lt;/code&gt; : long의 줄임말로 파일 출력 형식을 긴 목록 형식으로 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-a&lt;/code&gt; : 모든 파일 보기 (숨김파일까지)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-b&lt;/code&gt; : c-style 알파벳 순으로 파일 및 Directory를 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-r&lt;/code&gt; : 역순으로 보기&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-R&lt;/code&gt; : 하위 Directory 끝까지 보기&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-t&lt;/code&gt; : 시간순으로 보기&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-n&lt;/code&gt; : 소유자와 소유자 그룹을 UDI와 GID로 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-m&lt;/code&gt; : 파일의 출력 형식이 Directory 및 파일을 쉽표로 구분&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-i&lt;/code&gt; : 각 파일의 인덱스 값을 첫 번째 열에 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-I&lt;/code&gt; : 지정한 파일 및 Directory를 제외하고 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-L&lt;/code&gt; : 심볼릭 링크의 정보를 출력할 때 원본 파일의 정보를 출력&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-lrt&lt;/code&gt; : 위에서 아래로 시간순으로 자세히 보기&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Linux는 대소문자를 구분하므로 &lt;code&gt;-r&lt;/code&gt;이 아닌 &lt;code&gt;-R&lt;/code&gt;로 써야 한다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="ls-명령어-사용-예제"&gt;
 ls 명령어 사용 예제
 &lt;a class="heading-anchor" href="#ls-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%82%ac%ec%9a%a9-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="예제-1"&gt;
 예제 1)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;현재 Directory(pwd를 입력했을때 나온 위치)의 목록 보여준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ls&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-2"&gt;
 예제 2)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/home/devkuma&lt;/code&gt; Directory 내용을 자세히 보여준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ls -l /home/devkuma
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;kryoon@localhost ~&lt;span class="o"&gt;]&lt;/span&gt;$ ls -l /home/devkuma
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;합계 &lt;span class="m"&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;drwxr-x---. &lt;span class="m"&gt;6&lt;/span&gt; root root &lt;span class="m"&gt;49&lt;/span&gt; 6월 &lt;span class="m"&gt;6&lt;/span&gt; 08:06 data
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;-rwx------. &lt;span class="m"&gt;1&lt;/span&gt; devkuma devkuma &lt;span class="m"&gt;198&lt;/span&gt; 6월 &lt;span class="m"&gt;1&lt;/span&gt; 11:20 deploy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;목록 내용에서 앞에 표시되는 문자열(예:&lt;code&gt;drwxr-x---&lt;/code&gt;)의 의미는 아래와 같다.
&lt;ul&gt;
&lt;li&gt;d로 시작하는것 = Directory&lt;/li&gt;
&lt;li&gt;-로 시작하는 것 = 파일&lt;/li&gt;
&lt;li&gt;l로 시작하는 것 = 링크 파일(바로 가기)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="예제-3"&gt;
 예제 3)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-3" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc Directory&lt;/code&gt;의 숨김 파일 포함해서 보여준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ls -a /etc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;(.)으로 시작되는 파일은 숨김파일이다. (예: .ssh)
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="예제-4"&gt;
 예제 4)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc&lt;/code&gt;의 하위 Directory 끝까지 보여준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ls -R /etc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="예제-5"&gt;
 예제 5)
 &lt;a class="heading-anchor" href="#%ec%98%88%ec%a0%9c-5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc&lt;/code&gt;의 숨김 파일 포함해서, 하위 Directory 끝까지 자세히 보여준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;ls -alR /etc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;명령어의 옵션은 조합이 가능하다. 순서는 상관없다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Linux] Network - ping 상대 호스트와 연결 가능 여부 확인</title><link>https://kyungryeol-yoon.github.io/linux/network-commands/linux-network-ping/</link><pubDate>Tue, 02 Jan 2018 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/linux/network-commands/linux-network-ping/</guid><description>&lt;h2 id="ping-명령어"&gt;
 ping 명령어
 &lt;a class="heading-anchor" href="#ping-%eb%aa%85%eb%a0%b9%ec%96%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;상대 호스트와 연결 가능 여부 확인한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="사용법"&gt;
 사용법
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%eb%b2%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ping (option) [연결 가능 여부 IP 및 도메인]&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="option"&gt;
 option:
 &lt;a class="heading-anchor" href="#option" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-c (count)&lt;/code&gt; : ping을 보낼 횟수&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-i (interval)&lt;/code&gt; : ping을 보낼 간격&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-s (size)&lt;/code&gt; : ping의 크기(최대 65507)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-f (fast)&lt;/code&gt; : 최대 속도&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ping-명령어-사용-예제"&gt;
 ping 명령어 사용 예제
 &lt;a class="heading-anchor" href="#ping-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%82%ac%ec%9a%a9-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;kryoon@localhost ~&lt;span class="o"&gt;]&lt;/span&gt;$ ping -c &lt;span class="m"&gt;3&lt;/span&gt; www.google.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;PING www.google.com &lt;span class="o"&gt;(&lt;/span&gt;172.217.24.196&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="m"&gt;56&lt;/span&gt; data bytes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;64&lt;/span&gt; bytes from 172.217.24.196: &lt;span class="nv"&gt;icmp_seq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nv"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;49&lt;/span&gt; &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;68.258 ms
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;64&lt;/span&gt; bytes from 172.217.24.196: &lt;span class="nv"&gt;icmp_seq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="nv"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;49&lt;/span&gt; &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;70.593 ms
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;64&lt;/span&gt; bytes from 172.217.24.196: &lt;span class="nv"&gt;icmp_seq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="nv"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;49&lt;/span&gt; &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;68.935 ms
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;--- www.google.com ping statistics ---
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;3&lt;/span&gt; packets transmitted, &lt;span class="m"&gt;3&lt;/span&gt; packets received, 0.0% packet loss
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;round-trip min/avg/max/stddev &lt;span class="o"&gt;=&lt;/span&gt; 68.258/69.262/70.593/0.981 ms&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="ping-트래픽"&gt;
 ping 트래픽
 &lt;a class="heading-anchor" href="#ping-%ed%8a%b8%eb%9e%98%ed%94%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ping 기본 값: 8byte&lt;/li&gt;
&lt;li&gt;ping 최댓값: 65515byte (65507 + 8)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ping-고급-설정"&gt;
 ping 고급 설정
 &lt;a class="heading-anchor" href="#ping-%ea%b3%a0%ea%b8%89-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="ping-막기icmf-막기"&gt;
 ping 막기(ICMF 막기)
 &lt;a class="heading-anchor" href="#ping-%eb%a7%89%ea%b8%b0icmf-%eb%a7%89%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &amp;gt; /proc/sys/net/ipv4/icmp_echo_ignore_all&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="ping-허용icmf-허용"&gt;
 ping 허용(ICMF 허용)
 &lt;a class="heading-anchor" href="#ping-%ed%97%88%ec%9a%a9icmf-%ed%97%88%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &amp;gt; /proc/sys/net/ipv4/icmp_echo_ignore_all&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Mac OS] Setting Alias Mac OS</title><link>https://kyungryeol-yoon.github.io/environment/macos/setting-alias-mac/</link><pubDate>Fri, 01 Dec 2017 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/environment/macos/setting-alias-mac/</guid><description>&lt;h3 id="alias-등록"&gt;
 alias 등록
 &lt;a class="heading-anchor" href="#alias-%eb%93%b1%eb%a1%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;맥북은 bash쉘이 아닌 zsh쉘을 기본으로 사용한다.&lt;/li&gt;
&lt;li&gt;그렇기 때문에 &lt;code&gt;~/.bashrc&lt;/code&gt;가 아닌 &lt;code&gt;~/.zshrc&lt;/code&gt; 파일을 열어 수정을 해줘야 한다.&lt;/li&gt;
&lt;li&gt;zshrc 파일로 영구 등록&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;vi ~/.zshrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;원하는 alias를 등록해준다.&lt;/li&gt;
&lt;li&gt;alias [별명]=[linux 명령어]&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;문서의 맨 처음으로 이동: &lt;code&gt;gg&lt;/code&gt; 또는 &lt;code&gt;1G&lt;/code&gt;
{: .prompt-tip }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;문서의 맨 마지막으로 이동: &lt;code&gt;G&lt;/code&gt;
{: .prompt-tip }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-conf" data-lang="conf"&gt;# k3s alias
alias k3sctl=&amp;#34;kubectl --kubeconfig=${HOME}/.kube/k3s.yaml&amp;#34;

# istio 환경변수
export PATH=/Users/kyungryeol.yoon/istio-1.15.0/bin:/Users/kyungryeol.yoon/istio-1.15.0/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;esc -&amp;gt; :wq 로 저장한다.&lt;/li&gt;
&lt;li&gt;터미널을 끄고 다시 시작한다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Network] RESTful란?</title><link>https://kyungryeol-yoon.github.io/networking/restful/</link><pubDate>Sun, 22 Oct 2017 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/networking/restful/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/rest-api/"&gt;REST API 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/rest/"&gt;REST 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="restful의-개념"&gt;
 &lt;strong&gt;RESTful의 개념&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#restful%ec%9d%98-%ea%b0%9c%eb%85%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="restful이란"&gt;
 &lt;strong&gt;RESTful이란?&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#restful%ec%9d%b4%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;RESTful은 일반적으로 REST라는 아키텍처를 구현하는 웹 서비스를 나타내기 위해 사용되는 용어이다.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;REST API&lt;/strong&gt;를 제공하는 웹 서비스를 &lt;strong&gt;RESTful&lt;/strong&gt;하다고 할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RESTful은 REST를 REST답게 쓰기 위한 방법으로, 누군가가 공식적으로 발표한 것이 아니다.
&lt;ul&gt;
&lt;li&gt;즉, REST 원리를 따르는 시스템은 RESTful이란 용어로 지칭된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="restful의-목적"&gt;
 &lt;strong&gt;RESTful의 목적&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#restful%ec%9d%98-%eb%aa%a9%ec%a0%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;이해하기 쉽고 사용하기 쉬운 REST API를 만드는 것&lt;/li&gt;
&lt;li&gt;RESTful한 API를 구현하는 근본적인 목적이 성능 향상에 있는 것이 아니라 일관적인 컨벤션을 통한 API의 이해도 및 호환성을 높이는 것이 주 동기이니, 성능이 중요한 상황에서는 굳이 RESTful한 API를 구현할 필요는 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="restful-하지-못한-경우"&gt;
 &lt;strong&gt;RESTful 하지 못한 경우&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#restful-%ed%95%98%ec%a7%80-%eb%aa%bb%ed%95%9c-%ea%b2%bd%ec%9a%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ex1) CRUD 기능을 모두 POST로만 처리하는 API&lt;/li&gt;
&lt;li&gt;Ex2) route에 resource, id 외의 정보가 들어가는 경우(/students/updateName)&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Network] REST API란?</title><link>https://kyungryeol-yoon.github.io/networking/rest-api/</link><pubDate>Sun, 15 Oct 2017 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/networking/rest-api/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/restful/"&gt;RESTful 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/rest/"&gt;REST 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="rest-api의-개념"&gt;
 &lt;strong&gt;REST API의 개념&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#rest-api%ec%9d%98-%ea%b0%9c%eb%85%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="rest-api란"&gt;
 &lt;strong&gt;REST API란?&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#rest-api%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="apiapplication-programming-interface란"&gt;
 &lt;strong&gt;API(Application Programming Interface)란?&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#apiapplication-programming-interface%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;데이터와 기능의 집합을 제공하여 컴퓨터 프로그램간 상호작용을 촉진하며, 서로 정보를 교환가능 하도록 하는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="rest-api의-정의"&gt;
 &lt;strong&gt;REST API의 정의&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#rest-api%ec%9d%98-%ec%a0%95%ec%9d%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;REST 기반으로 서비스 API를 구현한 것&lt;/li&gt;
&lt;li&gt;최근 OpenAPI(누구나 사용할 수 있도록 공개된 API: 구글 맵, 공공 데이터 등), 마이크로 서비스(하나의 큰 애플리케이션을 여러 개의 작은 애플리케이션으로 쪼개어 변경과 조합이 가능하도록 만든 아키텍처) 등을 제공하는 업체 대부분은 REST API를 제공한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rest-api의-특징"&gt;
 &lt;strong&gt;REST API의 특징&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#rest-api%ec%9d%98-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;사내 시스템들도 REST 기반으로 시스템을 분산해 확장성과 재사용성을 높여 유지보수 및 운용을 편리하게 할 수 있다.&lt;/li&gt;
&lt;li&gt;REST는 HTTP 표준을 기반으로 구현하므로, HTTP를 지원하는 프로그램 언어로 클라이언트, 서버를 구현할 수 있다.&lt;/li&gt;
&lt;li&gt;즉, REST API를 제작하면 델파이 클라이언트 뿐 아니라, 자바, C#, 웹 등을 이용해 클라이언트를 제작할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rest-api-설계-기본-규칙"&gt;
 &lt;strong&gt;REST API 설계 기본 규칙&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#rest-api-%ec%84%a4%ea%b3%84-%ea%b8%b0%eb%b3%b8-%ea%b7%9c%ec%b9%99" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="참고-리소스-원형"&gt;
 &lt;strong&gt;참고 리소스 원형&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%b0%b8%ea%b3%a0-%eb%a6%ac%ec%86%8c%ec%8a%a4-%ec%9b%90%ed%98%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;도큐먼트 : 객체 인스턴스나 데이터베이스 레코드와 유사한 개념&lt;/li&gt;
&lt;li&gt;컬렉션 : 서버에서 관리하는 디렉터리라는 리소스&lt;/li&gt;
&lt;li&gt;스토어 : 클라이언트에서 관리하는 리소스 저장소&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="uri는-정보의-자원을-표현해야-한다"&gt;
 &lt;strong&gt;URI는 정보의 자원을 표현해야 한다.&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#uri%eb%8a%94-%ec%a0%95%eb%b3%b4%ec%9d%98-%ec%9e%90%ec%9b%90%ec%9d%84-%ed%91%9c%ed%98%84%ed%95%b4%ec%95%bc-%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;resource는 동사보다는 명사를, 대문자보다는 소문자를 사용한다.&lt;/li&gt;
&lt;li&gt;resource의 도큐먼트 이름으로는 단수 명사를 사용해야 한다.&lt;/li&gt;
&lt;li&gt;resource의 컬렉션 이름으로는 복수 명사를 사용해야 한다.&lt;/li&gt;
&lt;li&gt;resource의 스토어 이름으로는 복수 명사를 사용해야 한다.
&lt;ul&gt;
&lt;li&gt;Ex) GET /Member/1 → GET /members/1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="자원에-대한-행위는-http-methodget-put-post-delete-등로-표현한다"&gt;
 &lt;strong&gt;자원에 대한 행위는 HTTP Method(GET, PUT, POST, DELETE 등)로 표현한다.&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%9e%90%ec%9b%90%ec%97%90-%eb%8c%80%ed%95%9c-%ed%96%89%ec%9c%84%eb%8a%94-http-methodget-put-post-delete-%eb%93%b1%eb%a1%9c-%ed%91%9c%ed%98%84%ed%95%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;URI에 HTTP Method가 들어가면 안된다.
&lt;ul&gt;
&lt;li&gt;Ex) GET /members/delete/1 → DELETE /members/1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;URI에 행위에 대한 동사 표현이 들어가면 안된다.(즉, CRUD 기능을 나타내는 것은 URI에 사용하지 않는다.)
&lt;ul&gt;
&lt;li&gt;Ex) GET /members/show/1 → GET /members/1&lt;/li&gt;
&lt;li&gt;Ex) GET /members/insert/2 → POST /members/2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;경로 부분 중 변하는 부분은 유일한 값으로 대체한다.(즉, :id는 하나의 특정 resource를 나타내는 고유값이다.)
&lt;ul&gt;
&lt;li&gt;Ex) student를 생성하는 route: POST /students&lt;/li&gt;
&lt;li&gt;Ex) id=12인 student를 삭제하는 route: DELETE /students/12&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rest-api-설계-규칙"&gt;
 &lt;strong&gt;REST API 설계 규칙&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#rest-api-%ec%84%a4%ea%b3%84-%ea%b7%9c%ec%b9%99" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;슬래시 구분자(/ )는 계층 관계를 나타내는데 사용한다.
&lt;ul&gt;
&lt;li&gt;Ex) &lt;a href="http://restapi.example.com/houses/apartments"&gt;http://restapi.example.com/houses/apartments&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;URI 마지막 문자로 슬래시(/ )를 포함하지 않는다.
&lt;ul&gt;
&lt;li&gt;URI에 포함되는 모든 글자는 리소스의 유일한 식별자로 사용되어야 하며 URI가 다르다는 것은 리소스가 다르다는 것이고, 역으로 리소스가 다르면 URI도 달라져야 한다.&lt;/li&gt;
&lt;li&gt;REST API는 분명한 URI를 만들어 통신을 해야 하기 때문에 혼동을 주지 않도록 URI 경로의 마지막에는 슬래시(/)를 사용하지 않는다.&lt;/li&gt;
&lt;li&gt;Ex) &lt;a href="http://restapi.example.com/houses/apartments/"&gt;http://restapi.example.com/houses/apartments/&lt;/a&gt; (X)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;하이픈(- )은 URI 가독성을 높이는데 사용
&lt;ul&gt;
&lt;li&gt;불가피하게 긴 URI경로를 사용하게 된다면 하이픈을 사용해 가독성을 높인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;밑줄(_ )은 URI에 사용하지 않는다.
&lt;ul&gt;
&lt;li&gt;밑줄은 보기 어렵거나 밑줄 때문에 문자가 가려지기도 하므로 가독성을 위해 밑줄은 사용하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;URI 경로에는 소문자가 적합하다.
&lt;ul&gt;
&lt;li&gt;URI 경로에 대문자 사용은 피하도록 한다.&lt;/li&gt;
&lt;li&gt;RFC 3986(URI 문법 형식)은 URI 스키마와 호스트를 제외하고는 대소문자를 구별하도록 규정하기 때문&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;파일확장자는 URI에 포함하지 않는다.
&lt;ul&gt;
&lt;li&gt;REST API에서는 메시지 바디 내용의 포맷을 나타내기 위한 파일 확장자를 URI 안에 포함시키지 않는다.&lt;/li&gt;
&lt;li&gt;Accept header를 사용한다.&lt;/li&gt;
&lt;li&gt;Ex) &lt;a href="http://restapi.example.com/members/soccer/345/photo.jpg"&gt;http://restapi.example.com/members/soccer/345/photo.jpg&lt;/a&gt; (X)&lt;/li&gt;
&lt;li&gt;Ex) GET / members/soccer/345/photo HTTP/1.1 Host: restapi.example.com Accept: image/jpg (O)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;리소스 간에는 연관 관계가 있는 경우
&lt;ul&gt;
&lt;li&gt;/리소스명/리소스 ID/관계가 있는 다른 리소스명&lt;/li&gt;
&lt;li&gt;Ex) GET : /users/{userid}/devices (일반적으로 소유 ‘has’의 관계를 표현할 때)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rest-api-설계-예시"&gt;
 &lt;strong&gt;REST API 설계 예시&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#rest-api-%ec%84%a4%ea%b3%84-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;CRUD&lt;/th&gt;
					&lt;th style="text-align: left"&gt;HTTP verbs&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Route&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;resource들의 목록을 표시&lt;/td&gt;
					&lt;td style="text-align: left"&gt;GET&lt;/td&gt;
					&lt;td style="text-align: left"&gt;/resource&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;resource 하나의 내용을 표시&lt;/td&gt;
					&lt;td style="text-align: left"&gt;GET&lt;/td&gt;
					&lt;td style="text-align: left"&gt;/resource/:id&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;resource를 생성&lt;/td&gt;
					&lt;td style="text-align: left"&gt;POST&lt;/td&gt;
					&lt;td style="text-align: left"&gt;/resource&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;resource를 수정&lt;/td&gt;
					&lt;td style="text-align: left"&gt;PUT&lt;/td&gt;
					&lt;td style="text-align: left"&gt;/resource/:id&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;resource를 삭제&lt;/td&gt;
					&lt;td style="text-align: left"&gt;DELETE&lt;/td&gt;
					&lt;td style="text-align: left"&gt;/resource/:id&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="참고-응답상태코드"&gt;
 &lt;strong&gt;참고 응답상태코드&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%b0%b8%ea%b3%a0-%ec%9d%91%eb%8b%b5%ec%83%81%ed%83%9c%ec%bd%94%eb%93%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;1xx&lt;/strong&gt; : 전송 프로토콜 수준의 정보 교환&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2xx&lt;/strong&gt; : 클라어인트 요청이 성공적으로 수행됨&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;3xx&lt;/strong&gt; : 클라이언트는 요청을 완료하기 위해 추가적인 행동을 취해야 함&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;4xx&lt;/strong&gt; : 클라이언트의 잘못된 요청&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;5xx&lt;/strong&gt; : 서버쪽 오류로 인한 상태코드&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Network] REST란?</title><link>https://kyungryeol-yoon.github.io/networking/rest/</link><pubDate>Tue, 10 Oct 2017 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/networking/rest/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/restful/"&gt;RESTful 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/rest-api/"&gt;REST API 참고&lt;/a&gt;
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="rest란"&gt;
 &lt;strong&gt;REST란?&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#rest%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="rest의-정의"&gt;
 &lt;strong&gt;REST의 정의&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#rest%ec%9d%98-%ec%a0%95%ec%9d%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Representational State Transfer&lt;/strong&gt;의 약자
&lt;ul&gt;
&lt;li&gt;자원을 이름(자원의 표현)으로 구분하여 해당 자원의 상태(정보)를 주고 받는 모든 것을 의미한다.&lt;/li&gt;
&lt;li&gt;즉, 자원(resource)의 표현(representation)에 의한 상태 전달
&lt;ul&gt;
&lt;li&gt;자원(resource)의 표현(representation)
&lt;ul&gt;
&lt;li&gt;자원: 해당 소프트웨어가 관리하는 모든 것
&lt;ul&gt;
&lt;li&gt;Ex) 문서, 그림, 데이터, 해당 소프트웨어 자체 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;자원의 표현: 그 자원을 표현하기 위한 이름
&lt;ul&gt;
&lt;li&gt;Ex) DB의 학생 정보가 자원일 때, ‘students’를 자원의 표현으로 정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;상태(정보) 전달
&lt;ul&gt;
&lt;li&gt;데이터가 요청되어지는 시점에서 자원의 상태(정보)를 전달한다.&lt;/li&gt;
&lt;li&gt;JSON 혹은 XML를 통해 데이터를 주고 받는 것이 일반적이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;월드 와이드 웹(www)과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 개발 아키텍처의 한 형식
&lt;ul&gt;
&lt;li&gt;REST는 기본적으로 웹의 기존 기술과 HTTP 프로토콜을 그대로 활용하기 때문에 웹의 장점을 최대한 활용할 수 있는 아키텍처 스타일이다.&lt;/li&gt;
&lt;li&gt;REST는 네트워크 상에서 Client와 Server 사이의 통신 방식 중 하나이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rest의-구체적인-개념"&gt;
 &lt;strong&gt;REST의 구체적인 개념&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#rest%ec%9d%98-%ea%b5%ac%ec%b2%b4%ec%a0%81%ec%9d%b8-%ea%b0%9c%eb%85%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;HTTP URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고, HTTP Method(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 의미한다.
&lt;ul&gt;
&lt;li&gt;즉, REST는 자원 기반의 구조(ROA, Resource Oriented Architecture) 설계의 중심에 Resource가 있고 HTTP Method를 통해 Resource를 처리하도록 설계된 아키텍쳐를 의미한다.&lt;/li&gt;
&lt;li&gt;웹 사이트의 이미지, 텍스트, DB 내용 등의 모든 자원에 고유한 ID인 HTTP URI를 부여한다.&lt;/li&gt;
&lt;li&gt;CRUD Operation
&lt;ul&gt;
&lt;li&gt;Create : 생성(POST)&lt;/li&gt;
&lt;li&gt;Read : 조회(GET)&lt;/li&gt;
&lt;li&gt;Update : 수정(PUT)&lt;/li&gt;
&lt;li&gt;Delete : 삭제(DELETE)&lt;/li&gt;
&lt;li&gt;HEAD: header 정보 조회(HEAD)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="rest의-장단점"&gt;
 &lt;strong&gt;REST의 장단점&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#rest%ec%9d%98-%ec%9e%a5%eb%8b%a8%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="장점"&gt;
 &lt;strong&gt;장점&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%9e%a5%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;HTTP 프로토콜의 인프라를 그대로 사용하므로 REST API 사용을 위한 별도의 인프라를 구출할 필요가 없다.&lt;/li&gt;
&lt;li&gt;HTTP 프로토콜의 표준을 최대한 활용하여 여러 추가적인 장점을 함께 가져갈 수 있게 해준다.&lt;/li&gt;
&lt;li&gt;HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용이 가능하다.&lt;/li&gt;
&lt;li&gt;Hypermedia API의 기본을 충실히 지키면서 범용성을 보장한다.&lt;/li&gt;
&lt;li&gt;REST API 메시지가 의도하는 바를 명확하게 나타내므로 의도하는 바를 쉽게 파악할 수 있다.&lt;/li&gt;
&lt;li&gt;여러가지 서비스 디자인에서 생길 수 있는 문제를 최소화한다.&lt;/li&gt;
&lt;li&gt;서버와 클라이언트의 역할을 명확하게 분리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="단점"&gt;
 &lt;strong&gt;단점&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%eb%8b%a8%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;표준이 존재하지 않는다.&lt;/li&gt;
&lt;li&gt;사용할 수 있는 메소드가 4가지 밖에 없다.
&lt;ul&gt;
&lt;li&gt;HTTP Method 형태가 제한적이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;브라우저를 통해 테스트할 일이 많은 서비스라면 쉽게 고칠 수 있는 URL보다 Header 값이 왠지 더 어렵게 느껴진다.&lt;/li&gt;
&lt;li&gt;구형 브라우저가 아직 제대로 지원해주지 못하는 부분이 존재한다.
&lt;ul&gt;
&lt;li&gt;PUT, DELETE를 사용하지 못하는 점&lt;/li&gt;
&lt;li&gt;pushState를 지원하지 않는 점&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="rest가-필요한-이유"&gt;
 &lt;strong&gt;REST가 필요한 이유&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#rest%ea%b0%80-%ed%95%84%ec%9a%94%ed%95%9c-%ec%9d%b4%ec%9c%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;애플리케이션 분리 및 통합&lt;/li&gt;
&lt;li&gt;다양한 클라이언트의 등장&lt;/li&gt;
&lt;li&gt;최근의 서버 프로그램은 다양한 브라우저와 안드로이폰, 아이폰과 같은 모바일 디바이스에서도 통신을 할 수 있어야 한다.&lt;/li&gt;
&lt;li&gt;이러한 멀티 플랫폼에 대한 지원을 위해 서비스 자원에 대한 아키텍처를 세우고 이용하는 방법을 모색한 결과, REST에 관심을 가지게 되었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="rest-구성-요소"&gt;
 &lt;strong&gt;REST 구성 요소&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#rest-%ea%b5%ac%ec%84%b1-%ec%9a%94%ec%86%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;자원(Resource): URI
&lt;ul&gt;
&lt;li&gt;모든 자원에 고유한 ID가 존재하고, 이 자원은 Server에 존재한다.&lt;/li&gt;
&lt;li&gt;자원을 구별하는 ID는 ‘/groups/:group_id’와 같은 HTTP URI 다.&lt;/li&gt;
&lt;li&gt;Client는 URI를 이용해서 자원을 지정하고 해당 자원의 상태(정보)에 대한 조작을 Server에 요청한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;행위(Verb): HTTP Method
&lt;ul&gt;
&lt;li&gt;HTTP 프로토콜의 Method를 사용한다.&lt;/li&gt;
&lt;li&gt;HTTP 프로토콜은 GET, POST, PUT, DELETE 와 같은 메서드를 제공한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;표현(Representation of Resource)
&lt;ul&gt;
&lt;li&gt;Client가 자원의 상태(정보)에 대한 조작을 요청하면 Server는 이에 적절한 응답(Representation)을 보낸다.&lt;/li&gt;
&lt;li&gt;REST에서 하나의 자원은 JSON, XML, TEXT, RSS 등 여러 형태의 Representation으로 나타내어 질 수 있다.&lt;/li&gt;
&lt;li&gt;JSON 혹은 XML를 통해 데이터를 주고 받는 것이 일반적이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="rest-특징"&gt;
 &lt;strong&gt;REST 특징&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#rest-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="server-client서버-클라이언트-구조"&gt;
 &lt;strong&gt;Server-Client(서버-클라이언트 구조)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#server-client%ec%84%9c%eb%b2%84-%ed%81%b4%eb%9d%bc%ec%9d%b4%ec%96%b8%ed%8a%b8-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;자원이 있는 쪽이 Server, 자원을 요청하는 쪽이 Client가 된다.
&lt;ul&gt;
&lt;li&gt;REST Server: API를 제공하고 비즈니스 로직 처리 및 저장을 책임진다.&lt;/li&gt;
&lt;li&gt;Client: 사용자 인증이나 context(세션, 로그인 정보) 등을 직접 관리하고 책임진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;서로 간 의존성이 줄어든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="stateless무상태"&gt;
 &lt;strong&gt;Stateless(무상태)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#stateless%eb%ac%b4%ec%83%81%ed%83%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;HTTP 프로토콜은 Stateless Protocol이므로 REST 역시 무상태성을 갖는다.&lt;/li&gt;
&lt;li&gt;Client의 context를 Server에 저장하지 않는다.
&lt;ul&gt;
&lt;li&gt;즉, 세션과 쿠키와 같은 context 정보를 신경쓰지 않아도 되므로 구현이 단순해진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Server는 각각의 요청을 완전히 별개의 것으로 인식하고 처리한다.
&lt;ul&gt;
&lt;li&gt;각 API 서버는 Client의 요청만을 단순 처리한다.&lt;/li&gt;
&lt;li&gt;즉, 이전 요청이 다음 요청의 처리에 연관되어서는 안된다.&lt;/li&gt;
&lt;li&gt;물론 이전 요청이 DB를 수정하여 DB에 의해 바뀌는 것은 허용한다.&lt;/li&gt;
&lt;li&gt;Server의 처리 방식에 일관성을 부여하고 부담이 줄어들며, 서비스의 자유도가 높아진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="cacheable캐시-처리-가능"&gt;
 &lt;strong&gt;Cacheable(캐시 처리 가능)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#cacheable%ec%ba%90%ec%8b%9c-%ec%b2%98%eb%a6%ac-%ea%b0%80%eb%8a%a5" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;웹 표준 HTTP 프로토콜을 그대로 사용하므로 웹에서 사용하는 기존의 인프라를 그대로 활용할 수 있다.
&lt;ul&gt;
&lt;li&gt;즉, HTTP가 가진 가장 강력한 특징 중 하나인 캐싱 기능을 적용할 수 있다.&lt;/li&gt;
&lt;li&gt;HTTP 프로토콜 표준에서 사용하는 Last-Modified 태그나 E-Tag를 이용하면 캐싱 구현이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;대량의 요청을 효율적으로 처리하기 위해 캐시가 요구된다.&lt;/li&gt;
&lt;li&gt;캐시 사용을 통해 응답시간이 빨라지고 REST Server 트랜잭션이 발생하지 않기 때문에 전체 응답시간, 성능, 서버의 자원 이용률을 향상시킬 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="layered-system계층화"&gt;
 &lt;strong&gt;Layered System(계층화)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#layered-system%ea%b3%84%ec%b8%b5%ed%99%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Client는 REST API Server만 호출한다.&lt;/li&gt;
&lt;li&gt;REST Server는 다중 계층으로 구성될 수 있다.
&lt;ul&gt;
&lt;li&gt;API Server는 순수 비즈니스 로직을 수행하고 그 앞단에 보안, 로드밸런싱, 암호화, 사용자 인증 등을 추가하여 구조상의 유연성을 줄 수 있다.&lt;/li&gt;
&lt;li&gt;또한 로드밸런싱, 공유 캐시 등을 통해 확장성과 보안성을 향상시킬 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;PROXY, 게이트웨이 같은 네트워크 기반의 중간 매체를 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="code-on-demandoptional"&gt;
 &lt;strong&gt;Code-On-Demand(optional)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#code-on-demandoptional" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Server로부터 스크립트를 받아서 Client에서 실행한다.&lt;/li&gt;
&lt;li&gt;반드시 충족할 필요는 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="uniform-interface인터페이스-일관성"&gt;
 &lt;strong&gt;Uniform Interface(인터페이스 일관성)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#uniform-interface%ec%9d%b8%ed%84%b0%ed%8e%98%ec%9d%b4%ec%8a%a4-%ec%9d%bc%ea%b4%80%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;URI로 지정한 Resource에 대한 조작을 통일되고 한정적인 인터페이스로 수행한다.&lt;/li&gt;
&lt;li&gt;HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용이 가능하다.
&lt;ul&gt;
&lt;li&gt;특정 언어나 기술에 종속되지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[DevOps] 개발과 운영</title><link>https://kyungryeol-yoon.github.io/devops/sre/devops/</link><pubDate>Wed, 02 Aug 2017 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/devops/sre/devops/</guid><description>&lt;h2 id="기존-개발-체계의-문제점"&gt;
 기존 개발 체계의 문제점
 &lt;a class="heading-anchor" href="#%ea%b8%b0%ec%a1%b4-%ea%b0%9c%eb%b0%9c-%ec%b2%b4%ea%b3%84%ec%9d%98-%eb%ac%b8%ec%a0%9c%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="전통적인-개발-운영-체계"&gt;
 전통적인 개발 운영 체계
 &lt;a class="heading-anchor" href="#%ec%a0%84%ed%86%b5%ec%a0%81%ec%9d%b8-%ea%b0%9c%eb%b0%9c-%ec%9a%b4%ec%98%81-%ec%b2%b4%ea%b3%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;개발팀에 의해서 개발이 끝나면, 시스템은 테스트를 거쳐서 운영팀에 이관되고, 운영팀은 해당 시스템을 배포 및 관리 운영한다.&lt;/li&gt;
&lt;li&gt;일단 이관된 시스템은, 개발팀이 일체 관여하지 않고, 운영팀에 의해서 현상 유지 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="문제점-1"&gt;
 문제점 1.
 &lt;a class="heading-anchor" href="#%eb%ac%b8%ec%a0%9c%ec%a0%90-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;시스템을 운영하다 보면, 반드시 장애가 생기기 마련인데, 문제는 여기부터 시작된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;개발은 “애플리케이션” 을 볼 수 있지만, 아랫단의 “인프라 시스템”을 볼 수 있는 능력이 없다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;반대로 운영팀은 “인프라 시스템” 을 잘 알지만, “애플리케이션” 자체에 대해서는 잘 모른다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그러다 보니, 서로 자기 분야의 문제가 아니라고 하면서 서로 책임 미루기를 하게 되고, 문제 해결은 지연된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이러한 책임 미루기에 대해서 “Fingerpointyness”라는 말로 표현한 것이 있는데, 정확하게, 누가 어떤 문제를 해결해야 하는지 정의 되지 않은 상황에서, 협업이 없어지고 문제 해결이 엉뚱한 방향으로 가는 현상이다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Freaking out &amp;amp; find fault 단계 (문제 발견)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;문제가 발생했다.&lt;/li&gt;
&lt;li&gt;문제의 내용을 먼저 파악한다.&lt;/li&gt;
&lt;li&gt;이때 협업은 없다.&lt;/li&gt;
&lt;li&gt;단지 자기 분야에서 문제가 어떤 것인지, 한정된 지식으로 현상 자체를 인지하는 수준이 된다.&lt;/li&gt;
&lt;li&gt;근본적인 문제에 대한 원인 파악보다는 대충 파악하는 단계 정도의 수준이 된다.&lt;/li&gt;
&lt;li&gt;이 단계에서 누가 문제를 파악할지에 대한 owner ship 자체가 정해지지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Blaming Covering ass 단계 (욕하기)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;그러다가, 어느 정도 문제의 현상 (정확한 원인이 아니라) 정도가 파악되면, 서로 미루기를 한다.&lt;/li&gt;
&lt;li&gt;“애플리케이션 문제네..”, “데이터 베이스 문제네..” 식으로, 정확한 원인 파악 없이 자기 문제가 아닌 것 처럼, 다른 쪽으로 미루기를 시작하면서, 상대편을 욕하는 단계가 된다.&lt;/li&gt;
&lt;li&gt;“데이터 베이스 구성을 그렇게 하니까는 그렇지.. 인덱스는 아냐?”. 내지는 “애플리케이션 구조에 맞춰서 배포는 한거야?” 이러면서 문제의 근본적인 원인은 해결되지 않고 시간은 계속 간다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Whining, Hiding. Hurt Ego 단계 (맘 상처 입기)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;계속 해서 문제를 서로에게 넘기다 보면, 문제를 숨기거나 상대방을 헐뜯거나 하면서 결국은 서로 상처를 입게 되고, 점점 커뮤니케이션은 없어지고 관계는 악화되어 간다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Figuring it out (문제 원인 분석)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;결국 문제를 해결해야 하는 시간이 가까워 오면, 문제를 풀긴 풀어야 하니, 어떻게든지 스스로 서로 모여서 문제를 같이 보게 되거나, 상위 메니져를 통해서 강제적으로 같이 모여서 문제에 대한 원인 분석을 해서 결국은 원인을 파악하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="5"&gt;
&lt;li&gt;Fixing things (문제 해결)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;그리고, 결과적으로 원인 파악 및 문제가 해결된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;아주 전형적인 개발과 운영간의 장애 처리 프로세스이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그나마 똑똑한 팀장을 가지고 있는 조직은 장애나 문제가 발생했을 때, “모두 다 모이세요.”해서 초기부터 문제를 같이 보고 해결하거나, 개발팀이나 운영팀 자체가 상대방의 분야를 볼 수 있는 능력을 갖춰서 문제를 해결하는 경우가 많다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;예를 들어, 운영팀이 애플리케이션에 대한 장애 대응 능력을 갖거나, 개발자가 OS나, 데이타베이스 또는 미들웨어등에 대한 인프라 운영 능력을 갖는 경우이다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="문제점-2-운영-이슈에-대한-전달-문제"&gt;
 문제점 2. 운영 이슈에 대한 전달 문제
 &lt;a class="heading-anchor" href="#%eb%ac%b8%ec%a0%9c%ec%a0%90-2-%ec%9a%b4%ec%98%81-%ec%9d%b4%ec%8a%88%ec%97%90-%eb%8c%80%ed%95%9c-%ec%a0%84%eb%8b%ac-%eb%ac%b8%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;개발은 운영으로 이관 후에, 서비스에 대해서 더 이상 관심을 갖지 않는다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;고객과의 접점도 거의 없다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그러나 운영은 (단순히 시스템을 운영하는 시스템 운영만이 아닌 실제 서비스 운영을 포함) 계속 해서 사용자와 interaction을 하고, 사용자로부터 끊임 없이 VOC (Voice Of Customer)를 받는다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;서비스를 운영하는 입장에서, 사용자의 의견을 들어서 서비스를 개선하고 싶은 것은 당연한 이치이고, 여러 VOC를 모아서 개발팀에 서비스 개선 요청을 하지만, 이미 개발과 운영은 멀어져있는 상태이고, 운영은 명시적으로 개발팀에 요구 사항을 정의할 수 있는 권한이 없기 때문에 (이러한 권한은 일반적으로 서비스 기획팀에서 갖는다).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이러한 개선 요청 요구 사항은 개발팀 입장에서는 추가적인 일이 되고, 개발팀은 이러한 신규 요구 사항에 대해서 저항하거나 또는 거절하게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="문제점-3-변경-요건"&gt;
 문제점 3. 변경 요건
 &lt;a class="heading-anchor" href="#%eb%ac%b8%ec%a0%9c%ec%a0%90-3-%eb%b3%80%ea%b2%bd-%ec%9a%94%ea%b1%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;서비스가 운영 배포된 후에도, 비즈니스 (기획팀)에 의해서, 계속 해서 서비스에 대한 신규 요구 사항은 나오게 되고, 새로운 변경 요건은 신규 개발과, 테스트 배포 그리고 지속적인 운영을 요구 하게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그런데, 근래의 서비스들의 경우에는 빠른 비즈니스 환경 변화에 따라가기 위해서 많은 변경 요구하게 되고, 이는 필연적으로 잦은 변경 배포를 요구 하게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;제대로 많은 변경으로 인하여 제대로 테스트 시간을 거치지 못한 애플리케이션의 경우에는 잦은 장애를 유발한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이런 배경으로 인해서 운영팀은 잦은 배포를 꺼려하게 되고, 조금 더 전통적이고 형식적인 관점에서 주기적인 릴리즈와 테스트를 요구하게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;애플리케이션단에 문제가 있다 하더라도 긴급 배포가 어려운 경우가 많고, 긴급 배포를 했다 하더라도, 개발팀의 실수를 뒷처리 하는 입장으로 인식하기 때문에, 계속 해서 개발팀과 운영팀의 관계는 악화 되어 간다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="해결책"&gt;
 해결책?
 &lt;a class="heading-anchor" href="#%ed%95%b4%ea%b2%b0%ec%b1%85" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;서비스 요구 사항의 신속한 반영의 문제&lt;/li&gt;
&lt;li&gt;고객의 요구 사항에 민감한 소프트웨어 개발&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;문제들은 어떻게 극복할 수 있을까?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solution 1.&lt;/strong&gt; 잘 협업 하자
&lt;ul&gt;
&lt;li&gt;기획과 개발을 합치자.&lt;/li&gt;
&lt;li&gt;답은 간단하다. 기획,개발,운영 모두 사이좋게 지내면 된다.&lt;/li&gt;
&lt;li&gt;어떻게 사이좋게? 서로 대화도 많이하고 팀웍을 잘 다지면 된다.&lt;/li&gt;
&lt;li&gt;이런 활동의 일환으로 시작된 것이 애자일 방법이다.&lt;/li&gt;
&lt;li&gt;기획팀과 개발팀을 하나의 팀으로 합친다.
&lt;ul&gt;
&lt;li&gt;요구 사항 변화에 빠르게 반응할 수 있는 구조로 바꾸고, Iterative 개발(반복적)과, Short Release를 이용한 잦은 릴리즈를 통해서 비즈니스의 요구 사항을 신속하게 반영하고, 변화에 잘 대응할 수 있는 구조를 갖추는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Solution 2.&lt;/strong&gt; 개발과 운영을 합쳐 버리자. (Devops)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="devops의-정의"&gt;
 Devops의 정의
 &lt;a class="heading-anchor" href="#devops%ec%9d%98-%ec%a0%95%ec%9d%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;이러한 개념들을 적극적으로 적용한 기업들이 Netflix, Flicker와 같은 인터넷 서비스 기업이다.&lt;/li&gt;
&lt;li&gt;기존 개발 프로세스에 비해서 훨씬 빠르게 고객의 요구 사항을 반영해 내가고 있다.&lt;/li&gt;
&lt;li&gt;Flicker의 경우에는 하루에 10번 정도 Deploy를 한다고 한다.&lt;/li&gt;
&lt;li&gt;일반적인 인터넷 서비스가 한달에 한번 업데이트 빨라야 일주에 한번인데, 하루에 10번이라면, 경쟁 구조 자체가 틀려진다.&lt;/li&gt;
&lt;li&gt;PuppetLab (Configuration management 자동화툴)에 따르면 Devops를 적용할 경우,경쟁사에 비해서 30배 정도 더 자주 Deployment를 할 수 있으며, Deployment 실패 비율도 50% 이상이나 줄일 수 있다는
것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="devops는-무엇인가"&gt;
 Devops는 무엇인가?
 &lt;a class="heading-anchor" href="#devops%eb%8a%94-%eb%ac%b4%ec%97%87%ec%9d%b8%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;일반적인 Devops의 정의는 “개발과 운영이 분리되면서 오는 문제점을 해결하기 위해서, 개발과 운영을 하나의 조직으로 합쳐서 팀을 운영하는 문화이자 방법론이다”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;개발 운영뿐만 아니라 테스트까지 하나의 팀에 합치는 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;상당 부분의 테스트는 이미 TDD (Test Driven Development), CI (Continuous Integration)를 통해서 개발 과정의 일부로 들어와 있는 경우가 많다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;즉 Devops란, “엔지니어가, 프로그래밍하고, 빌드하고, 직접 시스템에 배포 및 서비스를 RUN한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그리고, 사용자와 끊임 없이 Interaction하면서 서비스를 개선해 나가는 일련의 과정이자 문화이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;”Puppet lab의 Devops Engineer에 대한 정의를 보면 조금 더 이 개념을 확장하고 있는 것을 볼 수 있는데, “사용자와 끊임 없이 Interaction” 하는 부분은 원론적으로 보면 개발자의 역할 보다는 기존에는 마케팅이나
고객 접점에 있는 서비스 기획자의 역할이었다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;큰 의미에서 보면 단순히 개발, 운영이라는 기술적인 접근 뿐만 아니라 사용자와의 의사 소통을 통한 서비스의 개선이라는 “비즈니스”적인 역할까지 확장한 개념이 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그렇다면 Devops의 실체는 무엇일까? Scrum이나 XP와 같은 방법론? 아니면 조직 체계? Devops는 팀운용 방법론이기도 하지만 정확하게 이야기 하면 “문화”이다. 개발 문화.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;하나의 엔지니어가 멀티롤을 하면서 권한이 많아지게 되고, 예전 전통적인 소프트웨어 개발처럼 요구사항을 받아서, 개발하고 운영에 넘기는 개발 라인에 서 있는 하나의 리소스보다는 같이 생각하고 같이 서비스를 개발해야 하는 “협업” 중심의
문화 체계로 바뀌게 되는 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Devops는 하나의 방향을 제시 한다면, 이를 수행하기 위한 구체적인 방법은 팀에서 정의하고 만들어나가야 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="devops의-특징"&gt;
 Devops의 특징
 &lt;a class="heading-anchor" href="#devops%ec%9d%98-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Cross functional team – 하나의 팀에 각각 다른 역할을 할 수 있는 팀원들로 셋업해서 전체 End 2 End 서비스를 운용할 수 있도록 한다. 그렇다고 만능 개발자로 전체 팀을 채워서 일을 하라는 것이 아니다. 개발자의 커버러지가 넓어지고 협업은 해야 하겠지만, 그렇다고 모든 개발자가 그렇게 수퍼개발자일리는 없고, 엄연하게 다른 역할이 존재 한다. 예를 들어, 테스트 엔지니어, 빌드엔지니어 등.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;단, 여기서 Cross functional team이란, 한 팀내에서 서비스의 기획에서부터 운영 그리고 더 나아가서 영업등 해당 서비스에 관련된 모든 것 “ALL!!”을 할 수 있는 구조로 팀을 셋업 하라는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Widely Shared Metris – 개인적으로 가장 중요하다고 생각하는 항목중의 하나인데, 팀 전체가 기준으로 삼을 수 있는 서비스에 대한 공통적인 지표 (Metric)이 필요하다. 서비스를 개발하고 개선했을 때, 이를 평가하고 현재의 서비스의 진행 상태 (성공 여부, 시스템의 안정성, 사용자의 반응 등)를 인지할 수 있는 기준이 필요하다는 것이다. 예를 들어, 일 방문자수, 평균 체류 시간, 가입자수와 같은 비즈니스 지표에서부터, CPU 사용률, 메모리 사용률, 응답 시간등 기술 지표등이 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;기존 개발에서는 요건 받아서 개발하고, 운영으로 던져버렸기 때문에, 사용자들이 서비스에 만족하는지 운영에는 문제가 없는지에 대한 피드백이 전혀 없었다. 이 Metric을 팀 전체에 공유하고 꾸준하게 추적함으로써, 팀 전체가 서비스의 상태를 인지하고, 협업을 통해서 이에 대한 개선 작업을 진행할 수 있게 되는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;
&lt;p&gt;Automating repetitive tasks – 반복적인 작업을 툴을 이용해서 자동화 한다. 일반적으로 우리가 CI (Continuous Integration)이나 CD (Continuous Delivery)등을 이용해서 다루는 빌드, 배포, 테스트 자동화 들이 이에 속한다. 반복적인 작업의 자동화를 통해서 똑똑한 개발 자원들이 반복작업에 투여되는 시간을 줄여서 작업의 효율을 높이고 여기에 더해서 배포나 테스트에 관련된 시간을 줄여서 빠른 서비스 업데이트를 가능하게 하며, 마지막으로 이런 자동화 시스템 구축을 통해서 전체 시스템에 대한 이해도를 높일 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Post mortems – 직역하자면 해부? 사후 검증 정도의 의미가 되는데, 장애나 이슈가 있을때, 처리 후에, 그 내용을 전체 팀과 공유해야 한다. 서비스를 운영하는 팀의 문제점은 이슈등에 대한 심각도가 얼마나 높은지를 인지하지 못하는 경우가 많다. 시스템이 정지되었을 때, 비즈니스 적으로 손실이 어떤지,얼마나 심각한 문제를 인지하고 궁극적으로는 원인을 파악함으로써 다음 부터는 같은 이슈가 다시 발생하지 않도록 할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Regular release – 마지막으로 정기 릴리즈이다. 시스템 릴리즈는 많은 협업이 필요한 작업이다. 개발도 끝내야 하고, 테스트, 배포 과정을 거쳐야 하고, 릴리즈가 끝나면 다음 릴리즈를 위한 기능 정의 등의 과정을 거쳐야 한다. 그래서 정기적으로 릴리즈 주기를 설정하면, 전체 협업을 하는 입장에서 언제 어떤 협업을 해야 할지도 명확해지고, 개발이 리듬(?)을 타게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;짧은 주기의 정기 릴리즈를 통해서, 빠르게 서비스의 기능을 개선하고, 고객의 VoC를 반영해나갈 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="devops-기반의-팀의-개발-싸이클"&gt;
 Devops 기반의 팀의 개발 싸이클
 &lt;a class="heading-anchor" href="#devops-%ea%b8%b0%eb%b0%98%ec%9d%98-%ed%8c%80%ec%9d%98-%ea%b0%9c%eb%b0%9c-%ec%8b%b8%ec%9d%b4%ed%81%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;사용자의 needs 분석. VoC 수집&lt;/li&gt;
&lt;li&gt;사용자 스토리 작성 (요구 사항 작성)&lt;/li&gt;
&lt;li&gt;사용자 스토리에 대한 scope 정의 및 우선순위 지정&lt;/li&gt;
&lt;li&gt;Stakeholder에 대한 리포팅 및 관리 (내부 영업, 보고 등)&lt;/li&gt;
&lt;li&gt;다른 프로젝트와 연관성(dependency) 관리&lt;/li&gt;
&lt;li&gt;필요의 경우 솔루션 (오픈소스 또는 상용) 평가 및 도입&lt;/li&gt;
&lt;li&gt;개발!! (디자인, 빌드, 테스트, 데모.-iterative way)&lt;/li&gt;
&lt;li&gt;테스팅. 실 사용자 대상 테스팅 포함&lt;/li&gt;
&lt;li&gt;서버에 배포&lt;/li&gt;
&lt;li&gt;Security 관리, Compliance 관리 (개인 정보 보호, 국가별 법적 사항 확인등)&lt;/li&gt;
&lt;li&gt;서비스 운영, 모니터링.&lt;/li&gt;
&lt;li&gt;대 고객 지원 (Customer Support) – 추가 하였음&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;이런 프로세스를 한마디로 정리 해보면 결국 Devops 기반의 개발팀의 특징은, 한 팀내에서 모든 개발, 테스트, 배포 운영이 이루어진다는 것이고, 가장 중요한 것은, 운영을 통해서 사용자의 피드백을 접수하고, 이것이 새로운 요구 사항으로
연결되는데, 이 싸이클이 매우 빠르며 연속적이고 서로 연결 되어 있다 라는 것이다.&lt;/li&gt;
&lt;li&gt;기존 개발팀은 기획팀이 요구사항을 개발팀에 던지고, 개발팀은 개발 내용을 운영에 던지는, waterfall 모델 처럼, 각 팀이 개발 단계별로 자기 역할을 한 후에, 다음 단계로 던지고 잊어 버리는 (fire &amp;amp; forget) 형태라면, Devops 형태의 개발팀은, 던지는 것이 아니라 과정 내내 같이 수행한다.&lt;/li&gt;
&lt;li&gt;요구 사항을 개발팀에 넘겨도, 개발팀과 계속 협의를 하면서 요구 사항을 구체화 하고, 개선하며, 개발중에 운영인원과 같이 협의 하면서 최적의 구조를 논의 하면서 개발이 진행된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="devops-팀의-개발자의-필요-역량"&gt;
 Devops 팀의 개발자의 필요 역량
 &lt;a class="heading-anchor" href="#devops-%ed%8c%80%ec%9d%98-%ea%b0%9c%eb%b0%9c%ec%9e%90%ec%9d%98-%ed%95%84%ec%9a%94-%ec%97%ad%eb%9f%89" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;코딩능력은 필수&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Devops 엔지니어는 기본적으로 개발자를 기본으로 하고 있기 때문에, 개발을 위한 기본적인 코딩 능력.&lt;/li&gt;
&lt;li&gt;만약에 운영이나 시스템쪽에 치우친 엔지니어라면 자동화를 만들 수 있는 스크립트 작성 능력 등은 필수이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;다른 사람과 잘 협업하고 커뮤니케이션할 수 있는 능력&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Devops는 앞서 설명한바와 같이 큰 틀에서 협업 문화이다.&lt;/li&gt;
&lt;li&gt;시작 자체가 개발과 운영간의 소통 문제를 해결하고자 한것이기 때문에, 다른 팀원의 의견을 존중하고 문제를 함께 해결해나갈 수 있는 오픈 마인드 기반의 커뮤니케이션 능력이 매우 중요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;프로세스를 이해하고 때로는 그 프로세스를 재 정의할 수 있는 능력&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;마지막으로, Devops는 언뜻 보기에는 정형화된 프로세스가 없어 보일 수 있지만, 테스트 자동화, 배포, 그리고 요구 사항에 대한 수집 및 정의등은 모두 프로세스이며, 해당 팀의 모델이나 서비스의 성격에 따라서 만들어나가야 한다.&lt;/li&gt;
&lt;li&gt;그래서, 프로세스를 이해하고 준수하며, 같이 만들어나갈 수 있는 능력을 가져야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;오픈 소스 제품과 툴에 대한 이해&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;인프라 시스템에 대한 이해와 시스템 운영 경험&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;자동화된 툴 (컴파일,테스트,배포)에 대한 이해&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;비지니스에 대한 이해&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;오픈 마인드, 커뮤니케이션 및 협업 능력&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Devops 팀의 엔지니어는 부족한 부분을 메꾸기 위해서 공부는 필수이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그보다 더 중요한 것은 경험이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;운영은 직접 겪어 보기전에는 알 수 없다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그리고 오픈 마인드 기반으로 커뮤니케이션을 해가면서 문제를 풀고 협업하는 능력은 책이 아니라 직접 겪어야 얻을 수 있는 능력이다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Java] Synchronized</title><link>https://kyungryeol-yoon.github.io/backend/java/java-synchronized/</link><pubDate>Sat, 13 May 2017 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/java/java-synchronized/</guid><description>&lt;ul&gt;
&lt;li&gt;Java에서 프로그래밍을 한다면 Multi-Thread로 인하여 동기화를 제어해야하는 경우가 생긴다.&lt;/li&gt;
&lt;li&gt;그 때 Java에서 제공하는 키워드인 synchronized 키워드를 사용하게 되는데, Multi-Thread 상태에서 동일한 자원을 동시에 접근하게 되었을 때 동시 접근을 막게 된다.&lt;/li&gt;
&lt;li&gt;즉 공유 데이터에 lock을 걸어서 먼저 작업 중이던 쓰레드가 작업을 완전히 끝낼 때까지는 다른 쓰레드에게 제어권이 넘어가더라도 데이터가 변경되지 않도록 보호함으로써 쓰레드의 동기화를 가능하게 한다.&lt;/li&gt;
&lt;li&gt;synchronized 외에 volatile을 사용할 수 있고, Atomic 클래스를 사용할 수도 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;Method에 synchronized 하기&lt;/li&gt;
&lt;li&gt;블록에 synchronized 하기&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="먼저-multi-thread-환경에서-synchronized를-사용하지-않을-경우"&gt;
 &lt;strong&gt;먼저 Multi-Thread 환경에서 synchronized를 사용하지 않을 경우&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%eb%a8%bc%ec%a0%80-multi-thread-%ed%99%98%ea%b2%bd%ec%97%90%ec%84%9c-synchronized%eb%a5%bc-%ec%82%ac%ec%9a%a9%ed%95%98%ec%a7%80-%ec%95%8a%ec%9d%84-%ea%b2%bd%ec%9a%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;계좌에는 1000원이 있다.&lt;/li&gt;
&lt;li&gt;100 ~ 300 으로 랜덤하게 계좌에서 출금을 할 수 있다.&lt;/li&gt;
&lt;li&gt;계좌에서 출금을 하는데 잔액이 출금하는 돈보다 크다면 출금이 가능하다.&lt;/li&gt;
&lt;li&gt;Multi-Thread 방식으로 2명이 출금을 한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;withDraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34; money : &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34; balance : &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InterruptedException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Task&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;implements&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Runnable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;balance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)((&lt;/span&gt;&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withDraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ThreadSynchronizedTest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thread1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thread1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;No.1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thread2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thread2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;No.2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thread1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thread2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;No.2 money : 200
No.1 money : 100
No.1 balance : 700
No.1 money : 300
No.2 balance : 700
No.2 money : 200
No.1 balance : 200
No.1 money : 100
No.2 balance : 200
No.2 money : 200
No.1 balance : 100
No.2 balance : -100&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;잔액이 -100이 되 버렸다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;한 쓰레드가 if문의 조건식을 통과하고 출금하기 바로 직전에 다른 쓰레드가 끼어들어서 출금을 먼저 했기 때문이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;위의 예제에서는 상황 설명을 위해 if문을 실행하고 다른 스레드에게 제어권을 넘겨주기 위해 Thread.sleep(1000)을 주었다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;하지만 Thread.sleep을 사용하지 않더라도 위와 같은 상황은 충분히 발생할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이렇게 동기화를 하지 않으면 의도치 않은 일이 발생할 지도 모른다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;사용자가 의도한 대로 정상적인 결과를 얻으려면 객체, 함수, 또는 변수에 synchronized를 사용해야 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="method에-synchronized"&gt;
 &lt;strong&gt;Method에 synchronized&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#method%ec%97%90-synchronized" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Instance Method의 동기화는 이 Method를 가진 Instance를 기준으로 이루어진다.&lt;/li&gt;
&lt;li&gt;그러므로 한 클래스에 synchronized를 사용한 Method를 가진다면, 여기서 동기화는 Instance를 기준으로 이루어진다.&lt;/li&gt;
&lt;li&gt;그리고 오직 하나의 Thread 만이 동기화된 Instance Method를 실행할 수 있다.&lt;/li&gt;
&lt;li&gt;결론은 synchronized를 사용한 Method가 존재한다면 Instance당 한 개의 Thread만이 접근할 수 있다.&lt;/li&gt;
&lt;li&gt;쉽게 생각하면 Method에 synchronized를 사용하면 그 함수가 포함된 객체(this)가 lock이 걸린 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;synchronized&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;synchronizedTest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;위의 예제에서 Method에 synchronized를 사용하려면 아래와 같이 사용하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;synchronized&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;withDraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34; money : &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34; balance : &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InterruptedException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="블록에-synchronized"&gt;
 &lt;strong&gt;블록에 synchronized&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%eb%b8%94%eb%a1%9d%ec%97%90-synchronized" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;아래 synchronized 키워드 괄호 사이에 락(Lock)이라 부르는 객체를 볼 수 있다.&lt;/li&gt;
&lt;li&gt;위에서 설명했듯이 동기화과 공유 자원에 대한 접근을 허락한다고 정의한 바 있다.&lt;/li&gt;
&lt;li&gt;즉 synchronized 키워드는 공유 자원에 대한 범위를 지정하는 기능을 하며 synchronized() 괄호 안에 있는락 객체는 다른 스레드의 접근을 차단하거나 접근을 허용하는 일종의 자물쇠 역할을 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;synchronized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;락&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Lock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;객체&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;withDraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;synchronized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34; money : &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34; balance : &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InterruptedException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;락 객체는 문지기 역할을 해서 오직 하나의 스레드만이 동기화 블록에 접근할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;동기화는 락을 필요로 하며 락은 모든 객체마다 존재한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Method 제어자 뒤에 synchronized 키워드가 위치한 동기화 Method는 락 객체를 지정하는 부분이 없다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;동기화 Method는 내부적으로 자신의 객체를 락으로 사용한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;즉, 객체 스스로 Method 전체를 감시하는 역할을 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이에 반해서 동기화 블록은 Method 안의 특정 부분을 동기화할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이런 경우에 락 객체는 자기 자신 객체를 의미하는 this 키워드를 사용할 수도 있지만 다른 객체를 락으로 사용할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;단, 락 객체가 여러 개라면 우리가 원하는 동기화 작업을 제대로 실행할 수 없다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그래서 보통은 락 객체를 하나만 사용하는 경우가 많다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;동기화 블록을 사용하는 경우, 해당 Method는 여러 스레드가 동시에 점유할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;하지만 동기화된 블록에 이르면 락 객체에 의해서 모든 스레드들은 실행을 중단하고 자신의 차례가 될 때까지 대기한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Network] 도메인 서버(DNS) 구축과 관리</title><link>https://kyungryeol-yoon.github.io/networking/dns-server-setup/</link><pubDate>Sun, 09 Apr 2017 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/networking/dns-server-setup/</guid><description>&lt;h2 id="-도메인-서버dns-구축"&gt;
 🖥️ 도메인 서버(DNS) 구축
 &lt;a class="heading-anchor" href="#-%eb%8f%84%eb%a9%94%ec%9d%b8-%ec%84%9c%eb%b2%84dns-%ea%b5%ac%ec%b6%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;DNS는 도메인 이름을 IP로 변환하여 서비스 접근을 가능하게 합니다.&lt;br&gt;
개발자 관점에서 직접 DNS를 이해하고 구축할 수 있으면 &lt;strong&gt;서비스 장애 대응과 인프라 관리&lt;/strong&gt;에 강점이 됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-dns-기본-개념"&gt;
 1️⃣ DNS 기본 개념
 &lt;a class="heading-anchor" href="#1-dns-%ea%b8%b0%eb%b3%b8-%ea%b0%9c%eb%85%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;역할&lt;/strong&gt;: 도메인 ↔ IP 변환&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;레코드 종류&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;A&lt;/code&gt; : IPv4&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AAAA&lt;/code&gt; : IPv6&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CNAME&lt;/code&gt; : 다른 도메인&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MX&lt;/code&gt; : 메일 서버&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="2-dns-서버-종류"&gt;
 2️⃣ DNS 서버 종류
 &lt;a class="heading-anchor" href="#2-dns-%ec%84%9c%eb%b2%84-%ec%a2%85%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;권한 DNS(Authoritative)&lt;/strong&gt;: 자신의 도메인 관리&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;재귀 DNS(Recursive)&lt;/strong&gt;: 다른 DNS 결과를 사용자에게 전달&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="3-bind9-예시-ubuntu"&gt;
 3️⃣ BIND9 예시 (Ubuntu)
 &lt;a class="heading-anchor" href="#3-bind9-%ec%98%88%ec%8b%9c-ubuntu" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;sudo apt install bind9
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# named.conf.local 설정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;zone &lt;span class="s2"&gt;&amp;#34;mydomain.com&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;type&lt;/span&gt; master&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; file &lt;span class="s2"&gt;&amp;#34;/etc/bind/db.mydomain.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# db.mydomain.com 예시&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$TTL&lt;/span&gt; &lt;span class="m"&gt;604800&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;@ IN SOA ns1.mydomain.com. admin.mydomain.com. &lt;span class="o"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;2026030201&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; Serial
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;604800&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; Refresh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;86400&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; Retry
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;2419200&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; Expire
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;604800&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; Negative Cache TTL
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;@ IN NS ns1.mydomain.com.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;ns1 IN A 192.168.1.10
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;www IN A 192.168.1.20
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl restart bind9&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="4-개발자-팁"&gt;
 4️⃣ 개발자 팁
 &lt;a class="heading-anchor" href="#4-%ea%b0%9c%eb%b0%9c%ec%9e%90-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;TTL 값 관리 → 캐시 정책 최적화&lt;/li&gt;
&lt;li&gt;권한 DNS / 재귀 DNS 분리 → 보안 강화&lt;/li&gt;
&lt;li&gt;테스트: &lt;code&gt;dig&lt;/code&gt;, &lt;code&gt;nslookup&lt;/code&gt; 활용&lt;/li&gt;
&lt;li&gt;컨테이너/클라우드 환경에서 DNS 문제 대응 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;💡 한 줄 기억:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;DNS 이해 = 도메인 접근 문제 해결 + 서비스 안정성 확보&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Network] IP 주소와 주소 공간 이해</title><link>https://kyungryeol-yoon.github.io/networking/ip-address-space/</link><pubDate>Thu, 06 Apr 2017 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/networking/ip-address-space/</guid><description>&lt;h2 id="-ip-주소와-주소-공간"&gt;
 📡 IP 주소와 주소 공간
 &lt;a class="heading-anchor" href="#-ip-%ec%a3%bc%ec%86%8c%ec%99%80-%ec%a3%bc%ec%86%8c-%ea%b3%b5%ea%b0%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;IP 주소는 네트워크 상 장치를 식별하고 통신하게 하는 필수 요소입니다.&lt;br&gt;
개발자 관점에서 IP 주소 공간을 이해하면 &lt;strong&gt;컨테이너 네트워크, VPC 설계, 서비스 접속 문제&lt;/strong&gt; 해결이 수월합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-ip-주소-종류"&gt;
 1️⃣ IP 주소 종류
 &lt;a class="heading-anchor" href="#1-ip-%ec%a3%bc%ec%86%8c-%ec%a2%85%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IPv4&lt;/strong&gt;: 32비트, 예: &lt;code&gt;192.168.1.10&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IPv6&lt;/strong&gt;: 128비트, 예: &lt;code&gt;2001:db8::1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="2-서브넷subnet"&gt;
 2️⃣ 서브넷(Subnet)
 &lt;a class="heading-anchor" href="#2-%ec%84%9c%eb%b8%8c%eb%84%b7subnet" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;네트워크를 나누어 관리하는 단위&lt;/li&gt;
&lt;li&gt;CIDR 표기: &lt;code&gt;192.168.1.0/24&lt;/code&gt; → 256개 주소 가능&lt;/li&gt;
&lt;li&gt;게이트웨이(Gateway) 지정: 네트워크 밖 통신 경로&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="3-ip-주소-범위-예시"&gt;
 3️⃣ IP 주소 범위 예시
 &lt;a class="heading-anchor" href="#3-ip-%ec%a3%bc%ec%86%8c-%eb%b2%94%ec%9c%84-%ec%98%88%ec%8b%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;범위&lt;/th&gt;
					&lt;th&gt;용도&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;10.0.0.0/8&lt;/td&gt;
					&lt;td&gt;대규모 사설 네트워크&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;172.16.0.0/12&lt;/td&gt;
					&lt;td&gt;중간 규모 사설 네트워크&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;192.168.0.0/16&lt;/td&gt;
					&lt;td&gt;소규모 사설 네트워크, 가정/사무실&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="4-dhcp"&gt;
 4️⃣ DHCP
 &lt;a class="heading-anchor" href="#4-dhcp" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;동적 IP 할당 프로토콜&lt;/li&gt;
&lt;li&gt;서버가 장치에 IP, 서브넷, 게이트웨이 자동 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="5-개발자-실무-팁"&gt;
 5️⃣ 개발자 실무 팁
 &lt;a class="heading-anchor" href="#5-%ea%b0%9c%eb%b0%9c%ec%9e%90-%ec%8b%a4%eb%ac%b4-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너 / VM / 클라우드 IP 충돌 방지&lt;/li&gt;
&lt;li&gt;서브넷, 게이트웨이, NAT 이해 필수&lt;/li&gt;
&lt;li&gt;디버깅: &lt;code&gt;ip addr&lt;/code&gt;, &lt;code&gt;ip route&lt;/code&gt; 활용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;💡 한 줄 기억:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;IP 주소 공간 이해 = 안정적인 네트워크 설계 + 문제 해결 능력&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Network] 네트워크 기초 개념</title><link>https://kyungryeol-yoon.github.io/networking/network-basics/</link><pubDate>Sat, 01 Apr 2017 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/networking/network-basics/</guid><description>&lt;h2 id="-네트워크-기초-개념"&gt;
 🌐 네트워크 기초 개념
 &lt;a class="heading-anchor" href="#-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac-%ea%b8%b0%ec%b4%88-%ea%b0%9c%eb%85%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;개발자라면 네트워크 기본 구조를 이해해야 애플리케이션 통신, 컨테이너 연결, 클라우드 인프라 문제를 해결하기 쉽습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-네트워크란"&gt;
 1️⃣ 네트워크란?
 &lt;a class="heading-anchor" href="#1-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;장치 간 데이터를 주고받는 구조&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;패킷(Packet)&lt;/strong&gt;: 네트워크 전송 최소 단위&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;프로토콜(Protocol)&lt;/strong&gt;: 통신 규약, 예: TCP, UDP, HTTP, HTTPS&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="2-주요-장치"&gt;
 2️⃣ 주요 장치
 &lt;a class="heading-anchor" href="#2-%ec%a3%bc%ec%9a%94-%ec%9e%a5%ec%b9%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;라우터(Router)&lt;/strong&gt;: 다른 네트워크 연결&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;스위치(Switch)&lt;/strong&gt;: 같은 네트워크 내 연결&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;방화벽(Firewall)&lt;/strong&gt;: 트래픽 허용/차단&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;게이트웨이(Gateway)&lt;/strong&gt;: 내부 → 외부 네트워크 연결 통로&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="3-개발자-관점"&gt;
 3️⃣ 개발자 관점
 &lt;a class="heading-anchor" href="#3-%ea%b0%9c%eb%b0%9c%ec%9e%90-%ea%b4%80%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;API 호출 실패, 컨테이너 통신 문제 시 &lt;strong&gt;패킷 흐름 추적&lt;/strong&gt; 가능&lt;/li&gt;
&lt;li&gt;TCP/UDP 차이 이해 → 네트워크 지연/데이터 손실 디버깅&lt;/li&gt;
&lt;li&gt;포트, 서브넷, 라우팅 경로 기본 이해 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="4-실무-팁"&gt;
 4️⃣ 실무 팁
 &lt;a class="heading-anchor" href="#4-%ec%8b%a4%eb%ac%b4-%ed%8c%81" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ping&lt;/code&gt;, &lt;code&gt;traceroute&lt;/code&gt;, &lt;code&gt;netstat&lt;/code&gt;, &lt;code&gt;ss&lt;/code&gt; 활용&lt;/li&gt;
&lt;li&gt;클라우드: VPC, Security Group, Network ACL 이해&lt;/li&gt;
&lt;li&gt;컨테이너: Pod-to-Pod 통신 구조 파악&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;💡 한 줄 기억:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;네트워크 이해 = 애플리케이션 연결 문제 해결 능력 향상&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>[Android] Facebook 로그인 구현하기</title><link>https://kyungryeol-yoon.github.io/frontend/android/android-facebook-login/</link><pubDate>Wed, 25 Jan 2017 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/frontend/android/android-facebook-login/</guid><description>&lt;h2 id="androidmanifestxml"&gt;
 AndroidManifest.xml
 &lt;a class="heading-anchor" href="#androidmanifestxml" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;meta-data&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;com.facebook.sdk.ApplicationId&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;android:value=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;페이스북APP_ID&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;activity&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;com.facebook.FacebookActivity&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;android:configChanges=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;keyboard|keyboardHidden|screenLayout|screenSize|orientation&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;android:theme=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;@android:style/Theme.Translucent.NoTitleBar&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;android:theme=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;@android:style/Theme.Translucent.NoTitleBar&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;android:label=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;@string/app_name&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;provider&lt;/span&gt; &lt;span class="na"&gt;android:authorities=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;com.facebook.app.FacebookContentProvider페이스북APP_ID&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;com.facebook.FacebookContentProvider&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;android:exported=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="login-요청-버튼-구현"&gt;
 Login 요청 버튼 구현
 &lt;a class="heading-anchor" href="#login-%ec%9a%94%ec%b2%ad-%eb%b2%84%ed%8a%bc-%ea%b5%ac%ed%98%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Arrays.asList를 이용하여 권한을 추가로 요청하실 수 있습니다. 일부 권한은 페이스북 앱 리뷰를 통과해야 합니다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;isLoginFacebook&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FacebookSdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sdkInitialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getApplicationContext&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;callbackManager&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CallbackManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LoginManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;logInWithReadPermissions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Arrays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;public_profile&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;email&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LoginManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;registerCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;callbackManager&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FacebookCallback&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LoginResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LoginResult&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;loginResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;TAG&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;페이스북 토큰 -&amp;gt; &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;loginResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAccessToken&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getToken&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;TAG&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;페이스북 UserID -&amp;gt; &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;loginResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAccessToken&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getUserId&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onCancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;TAG&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;취소됨&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FacebookException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="사용자-정보-획득"&gt;
 사용자 정보 획득
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%ec%9e%90-%ec%a0%95%eb%b3%b4-%ed%9a%8d%eb%93%9d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;GraphRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GraphRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newMeRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;엑세스토큰&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GraphRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GraphJSONObjectCallback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onCompleted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JSONObject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GraphResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;TAG&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;페이스북 로그인 결과&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;email&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 이메일&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 이름&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gender&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;gender&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 성별&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;TAG&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;페이스북 이메일 -&amp;gt; &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;TAG&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;페이스북 이름 -&amp;gt; &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;TAG&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;페이스북 성별 -&amp;gt; &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Bundle&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bundle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fields&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;id,name,email,gender&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setParameters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="callbackmanager-호출"&gt;
 callbackManager 호출
 &lt;a class="heading-anchor" href="#callbackmanager-%ed%98%b8%ec%b6%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;protected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onActivityResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;requestCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;resultCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Intent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onActivityResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;resultCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 페이스북 로그인 결과를 콜백매니저에 담는다&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;callbackManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onActivityResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;resultCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[MySQL] MySQL user 생성시 ERROR 1364 (HY000)</title><link>https://kyungryeol-yoon.github.io/database/mysql/mysql-create-user-error-ssl-cipher/</link><pubDate>Fri, 13 Jan 2017 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/mysql/mysql-create-user-error-ssl-cipher/</guid><description>&lt;h2 id="error-1364-hy000-field-ssl_cipher-doesnt-have-a-default-value"&gt;
 ERROR 1364 (HY000): Field &amp;lsquo;ssl_cipher&amp;rsquo; doesn&amp;rsquo;t have a default value
 &lt;a class="heading-anchor" href="#error-1364-hy000-field-ssl_cipher-doesnt-have-a-default-value" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Mysql 버전이 높아지면서 보안 관련 오류&lt;/li&gt;
&lt;li&gt;User 생성시 Host, User ,Password, ssl_cipher, x509_issuer, x509_subject를 입력해야함&lt;/li&gt;
&lt;li&gt;ssl_cipher, x509_issuer, x509_subject 값은 &amp;rsquo;&amp;rsquo; 빈값을 입력&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;insert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;into&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ssl_cipher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x509_issuer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x509_subject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;사용자명&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;비밀번호&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="error-1364-hy000-field-authentication_string-doesnt-have-a-default-value"&gt;
 ERROR 1364 (HY000): Field &amp;lsquo;authentication_string&amp;rsquo; doesn&amp;rsquo;t have a default value
 &lt;a class="heading-anchor" href="#error-1364-hy000-field-authentication_string-doesnt-have-a-default-value" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;mysql 5.5 에서 user 생성시 authentication_string 필드 추가. &amp;rsquo;&amp;rsquo; 값으로 입력&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;insert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;into&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ssl_cipher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x509_issuer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x509_subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authentication_string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;사용자명&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;비밀번호&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[MySQL] MySQL 접속 및 데이터베이스 추가</title><link>https://kyungryeol-yoon.github.io/database/mysql/mysql-create-database/</link><pubDate>Mon, 07 Nov 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/mysql/mysql-create-database/</guid><description>&lt;h2 id="db-접속"&gt;
 DB 접속
 &lt;a class="heading-anchor" href="#db-%ec%a0%91%ec%86%8d" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;mysql -u root -p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="db-목록-확인"&gt;
 DB 목록 확인
 &lt;a class="heading-anchor" href="#db-%eb%aa%a9%eb%a1%9d-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;show&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;databases&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="mysql-database-선택-및-테이블-살펴보기"&gt;
 mysql database 선택 및 테이블 살펴보기
 &lt;a class="heading-anchor" href="#mysql-database-%ec%84%a0%ed%83%9d-%eb%b0%8f-%ed%85%8c%ec%9d%b4%eb%b8%94-%ec%82%b4%ed%8e%b4%eb%b3%b4%ea%b8%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="데이터베이스-생성"&gt;
 데이터베이스 생성
 &lt;a class="heading-anchor" href="#%eb%8d%b0%ec%9d%b4%ed%84%b0%eb%b2%a0%ec%9d%b4%ec%8a%a4-%ec%83%9d%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;db_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="둘중에-하나를-입력하면-db-생성됨"&gt;
 둘중에 하나를 입력하면 DB 생성됨
 &lt;a class="heading-anchor" href="#%eb%91%98%ec%a4%91%ec%97%90-%ed%95%98%eb%82%98%eb%a5%bc-%ec%9e%85%eb%a0%a5%ed%95%98%eb%a9%b4-db-%ec%83%9d%ec%84%b1%eb%90%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="alert alert-info"&gt;
 &lt;span class="alert-label"&gt;참고&lt;/span&gt;
 MySQL에서는 schema와 database가 같은 뜻이라고 한다.
&lt;/div&gt;

&lt;div class="alert alert-danger"&gt;
 &lt;span class="alert-label"&gt;위험&lt;/span&gt;
 default character set을 지정하지 않으면 한글이 깨져서 나오므로 주의해야 한다.
&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;msyql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;schema&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;db_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;character&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;utf8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;db_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;character&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;utf8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;db_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;character&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;utf8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;COLLATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;utf8_general_ci&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="default-character-set-변경"&gt;
 default character set 변경
 &lt;a class="heading-anchor" href="#default-character-set-%eb%b3%80%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;msyql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DATABASE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DEFAULT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;CHARACTER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;utf8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;COLLATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;utf8_general_ci&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="데이터베이스-삭제"&gt;
 데이터베이스 삭제
 &lt;a class="heading-anchor" href="#%eb%8d%b0%ec%9d%b4%ed%84%b0%eb%b2%a0%ec%9d%b4%ec%8a%a4-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;msyql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;drop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;db_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[MySQL] MySQL 사용자에게 데이터베이스 사용권한 부여</title><link>https://kyungryeol-yoon.github.io/database/mysql/mysql-privileges-user/</link><pubDate>Sat, 05 Nov 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/mysql/mysql-privileges-user/</guid><description>&lt;p&gt;MySQL은 사용자 이름, 비밀번호, 접속 호스트로 인증한다.\
MySQL은 로그인을 시도하는 위치가 어디인가 하는 것도 인증의 일부로 간주한다.\
MySQL에서 사용자 계정을 추가하고 권한을 추가하거나 제거하는데 GRANT와 REVOKE 명령을 사용하기를 권장한다.\
사용자에게 허가된 것을 확인하려면 SHOW GRANTS 를 사용한다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;IDENTIFIED BY 'PASSWORD';&lt;/code&gt; 는 권한부여를 하면서 비밀번호까지 변경하고자 하는 경우이므로 비밀번호는 변경하지 않으려면 이 부분을 빼면 된다.
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="사용권한-부여"&gt;
 사용권한 부여
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%ea%b6%8c%ed%95%9c-%eb%b6%80%ec%97%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;GRANT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ALL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;PRIVILEGES&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;TABLE_NAME&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;USER_ID&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="k"&gt;host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IDENTIFIED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;PASSWORD&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="계정이-이미-존재-하는데-identified-by-비밀번호-부분을-추가하면-비밀번호가-변경된다"&gt;
 계정이 이미 존재 하는데 &amp;lsquo;identified by &amp;lsquo;비밀번호&amp;rsquo; 부분을 추가하면 비밀번호가 변경된다
 &lt;a class="heading-anchor" href="#%ea%b3%84%ec%a0%95%ec%9d%b4-%ec%9d%b4%eb%af%b8-%ec%a1%b4%ec%9e%ac-%ed%95%98%eb%8a%94%eb%8d%b0-identified-by-%eb%b9%84%eb%b0%80%eb%b2%88%ed%98%b8-%eb%b6%80%eb%b6%84%ec%9d%84-%ec%b6%94%ea%b0%80%ed%95%98%eb%a9%b4-%eb%b9%84%eb%b0%80%eb%b2%88%ed%98%b8%ea%b0%80-%eb%b3%80%ea%b2%bd%eb%90%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;GRANT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ALL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;privileges&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;USER_ID&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;locahost&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IDENTIFIED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;PASSWORD&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="모든-원격지에서-접속-권한-추가"&gt;
 모든 원격지에서 접속 권한 추가
 &lt;a class="heading-anchor" href="#%eb%aa%a8%eb%93%a0-%ec%9b%90%ea%b2%a9%ec%a7%80%ec%97%90%ec%84%9c-%ec%a0%91%ec%86%8d-%ea%b6%8c%ed%95%9c-%ec%b6%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;GRANT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ALL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;privileges&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;USER_ID&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IDENTIFIED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;PASSWORD&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;host에 &amp;lsquo;200.100.%&amp;rsquo; 로 하면 IP주소가 200.100.X.X 로 시작되는 모든 IP에서 원격 접속을 허용한다는 의미
{: .prompt-tip }
host에 &amp;lsquo;200.100.100.50&amp;rsquo; 으로 하면 IP주소가 200.100.100.50 인 곳에서만 원격 접속을 허용한다는 의미
{: .prompt-tip }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="user에게-test-데이터베이스-모든-테이블에-대한-권한-부여"&gt;
 user에게 test 데이터베이스 모든 테이블에 대한 권한 부여
 &lt;a class="heading-anchor" href="#user%ec%97%90%ea%b2%8c-test-%eb%8d%b0%ec%9d%b4%ed%84%b0%eb%b2%a0%ec%9d%b4%ec%8a%a4-%eb%aa%a8%eb%93%a0-%ed%85%8c%ec%9d%b4%eb%b8%94%ec%97%90-%eb%8c%80%ed%95%9c-%ea%b6%8c%ed%95%9c-%eb%b6%80%ec%97%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;grant&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;privileges&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userid&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;identified&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;password&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="user에게-test-데이터베이스-모든-테이블에-select-insert-update-권한-부여"&gt;
 user에게 test 데이터베이스 모든 테이블에 select, insert, update 권한 부여
 &lt;a class="heading-anchor" href="#user%ec%97%90%ea%b2%8c-test-%eb%8d%b0%ec%9d%b4%ed%84%b0%eb%b2%a0%ec%9d%b4%ec%8a%a4-%eb%aa%a8%eb%93%a0-%ed%85%8c%ec%9d%b4%eb%b8%94%ec%97%90-select-insert-update-%ea%b6%8c%ed%95%9c-%eb%b6%80%ec%97%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;grant&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;update&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;identified&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;password&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="user에게-test-데이터베이스-모든-테이블에-select-insert-update-권한-부여-1"&gt;
 user에게 test 데이터베이스 모든 테이블에 select, insert, update 권한 부여
 &lt;a class="heading-anchor" href="#user%ec%97%90%ea%b2%8c-test-%eb%8d%b0%ec%9d%b4%ed%84%b0%eb%b2%a0%ec%9d%b4%ec%8a%a4-%eb%aa%a8%eb%93%a0-%ed%85%8c%ec%9d%b4%eb%b8%94%ec%97%90-select-insert-update-%ea%b6%8c%ed%95%9c-%eb%b6%80%ec%97%ac-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;grant&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;update&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;-- 패스워드는 변경없이 권한만 부여하는 경우&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="user에게-모든-데이터베이스-모든-테이블에-권한-부여"&gt;
 user에게 모든 데이터베이스 모든 테이블에 권한 부여
 &lt;a class="heading-anchor" href="#user%ec%97%90%ea%b2%8c-%eb%aa%a8%eb%93%a0-%eb%8d%b0%ec%9d%b4%ed%84%b0%eb%b2%a0%ec%9d%b4%ec%8a%a4-%eb%aa%a8%eb%93%a0-%ed%85%8c%ec%9d%b4%eb%b8%94%ec%97%90-%ea%b6%8c%ed%95%9c-%eb%b6%80%ec%97%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;전역 권한은 모두 광범위한 보안문제가 수반되므로 권한을 허용하는 경우 신중해야 함
{: .prompt-warning }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;grant&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;privileges&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;identified&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;password&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;grant&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;option&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="변경된-내용을-반영권한-적용"&gt;
 변경된 내용을 반영(권한 적용)
 &lt;a class="heading-anchor" href="#%eb%b3%80%ea%b2%bd%eb%90%9c-%eb%82%b4%ec%9a%a9%ec%9d%84-%eb%b0%98%ec%98%81%ea%b6%8c%ed%95%9c-%ec%a0%81%ec%9a%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;flush&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;privileges&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="사용자에게-부여된-권한-확인"&gt;
 사용자에게 부여된 권한 확인
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%ec%9e%90%ec%97%90%ea%b2%8c-%eb%b6%80%ec%97%ac%eb%90%9c-%ea%b6%8c%ed%95%9c-%ed%99%95%ec%9d%b8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SHOW&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GRANTS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FOR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;-- userid 와 host명까지 붙여서 검색해야 함
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SHOW&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GRANTS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FOR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SHOW&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GRANTS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FOR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;200.100.100.50&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="사용자에게-데이터베이스-사용권한-제거"&gt;
 사용자에게 데이터베이스 사용권한 제거
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%ec%9e%90%ec%97%90%ea%b2%8c-%eb%8d%b0%ec%9d%b4%ed%84%b0%eb%b2%a0%ec%9d%b4%ec%8a%a4-%ec%82%ac%ec%9a%a9%ea%b6%8c%ed%95%9c-%ec%a0%9c%ea%b1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;모든 권한을 삭제&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;revoke&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;TABLE_NAME&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;USER_ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="사용자-계정-삭제"&gt;
 사용자 계정 삭제
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%ec%9e%90-%ea%b3%84%ec%a0%95-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;drop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userid&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;drop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userid&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[MySQL] MySQL 사용자 추가(권한추가)</title><link>https://kyungryeol-yoon.github.io/database/mysql/mysql-add-user-copy/</link><pubDate>Wed, 02 Nov 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/database/mysql/mysql-add-user-copy/</guid><description>&lt;h2 id="사용자-추가"&gt;
 사용자 추가
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%ec%9e%90-%ec%b6%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;identified&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;PASSWORD&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="사용자user를-추가하면서-패스워드까지-설정"&gt;
 사용자(user)를 추가하면서 패스워드까지 설정
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%ec%9e%90user%eb%a5%bc-%ec%b6%94%ea%b0%80%ed%95%98%eb%a9%b4%ec%84%9c-%ed%8c%a8%ec%8a%a4%ec%9b%8c%eb%93%9c%ea%b9%8c%ec%a7%80-%ec%84%a4%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;기존에 사용하던 계정에 외부 접근 권한을 부여하려면, Host를 &amp;lsquo;%&amp;rsquo; 로 하여 똑같은 계정을 추가한다
{: .prompt-info }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;%&lt;/code&gt; 의 의미는 외부에서의 접근을 허용&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;user_id&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;identified&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;PASSWORD&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="다른-방법으로는"&gt;
 다른 방법으로는
 &lt;a class="heading-anchor" href="#%eb%8b%a4%eb%a5%b8-%eb%b0%a9%eb%b2%95%ec%9c%bc%eb%a1%9c%eb%8a%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;mysql database 선택&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;USE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;INTO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;userid&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;PASSWORD&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;INTO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;userid&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;PASSWORD&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FLUSH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;privileges&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;사용자 삭제&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;drop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;User_ID&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="등록된-모든-사용자-id-조회"&gt;
 등록된 모든 사용자 ID 조회
 &lt;a class="heading-anchor" href="#%eb%93%b1%eb%a1%9d%eb%90%9c-%eb%aa%a8%eb%93%a0-%ec%82%ac%ec%9a%a9%ec%9e%90-id-%ec%a1%b0%ed%9a%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="사용자-삭제"&gt;
 사용자 삭제
 &lt;a class="heading-anchor" href="#%ec%82%ac%ec%9a%a9%ec%9e%90-%ec%82%ad%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;User_ID&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>RestController와 Controller (ResponseBody, ResponseEntity)</title><link>https://kyungryeol-yoon.github.io/backend/java/representational-state-transfer/</link><pubDate>Thu, 20 Oct 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/java/representational-state-transfer/</guid><description>&lt;h2 id="rest의-탄생-배경"&gt;
 REST의 탄생 배경
 &lt;a class="heading-anchor" href="#rest%ec%9d%98-%ed%83%84%ec%83%9d-%eb%b0%b0%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;기존 웹서비스 전달 프로토콜인 SOAP(simple Object Access Protocol)은 HTTP응용 프로토콜로서 SOAP 헤더와 바디로 구성되어 있고, 메시지 송수신 시 헤더와 바디의 인코딩/디코딩 과정이 필수입니다. 따라서 기본 HTTP로 메시지를 전달하던 인터넷 서비스 분야에서는 원하는 기능에 비해 SOAP 프로토콜 처리의 오버헤드가 발생하는 문제가 있습니다.\
(여기서 오버헤드란, 시스템에서 목적으로 하는 효과를 얻기 위해 본질적인 것은 아니지만 요구되는 작동, 또는 그 때문에 필요한 자원을 말합니다.)\
이런 SOAP의 단점을 보완하고자 등장한 구현 기술이 바로 RESTful 웹서비스입니다. RESTful 웹서비스는 REST 기반의 웹서비스를 의미하고, HTTP의 기본 기능만으로 원격 정보에 접근하는 웹 응용 기술입니다.\
RESTsms 웹의 창시자 중 한 사람인 Roy Fielding이 그의 박사 학위 논문에서, 현재의 웹 아키텍처가 웹의 본래 설계의 우수성을 활용하지 못하므로 웹의 장점을 최대한 활용할 수 있는 네트워크 기반의 아키텍처를 제안했는데 이것이 REST입니다.\
REST는 REpresentational State Transfer의 약어로서 부수적인 레이어나 세션 관리를 추가하지 않고도 HTTP프로토콜로 데이터를 전달하는 프레임워크입니다. 또한 클라이언트/서버 간의 구성요소를 엄격히 분리하여 구현은 단순화시키고 확장성과 성능은 높일 수 있는 아키텍처입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;REST는 SOAP와 같은 프로토콜이 아닙니다. REST는 architecture입니다. Resource를 기반으로 하는 architecture이기 때문에 시스템 설계도 Rest에 맞는 설계가 필요한 것입니다.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="controller-vs-restcontroller-controller와-restcontroller의-차이점"&gt;
 &lt;code&gt;@Controller VS&lt;/code&gt;, &lt;code&gt;@RestController&lt;/code&gt; (Controller와 RestController의 차이점)
 &lt;a class="heading-anchor" href="#controller-vs-restcontroller-controller%ec%99%80-restcontroller%ec%9d%98-%ec%b0%a8%ec%9d%b4%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;전통적인 Spring MVC Controller와 Restful 웹서비스 Controller의 주요 차이점은 HTTP Response Body가 생성되는 방식이다. 기존의 MVC Controlloer는 view 기술을 사용하지만 Restful 웹서비스 Controller는 객체를 반환하기만 하면 객체 데이터는 Json/XML 형식의 HTTP 응답을 직접 작성하게 된다.\
정리하자면, &lt;code&gt;@Controller&lt;/code&gt;의 주 용도는 view(화면)을 return하는 것이고, &lt;code&gt;@RestController&lt;/code&gt;는 데이터를 return하는 것이 주 용도라고 할 수 있다. 물론, &lt;code&gt;@Controller&lt;/code&gt;의 경우 Method에 &lt;code&gt;@ResponseBody&lt;/code&gt;를 사용하여 객체를 return 할 수도 있다.&lt;/p&gt;
&lt;h3 id="spring-mvc의-전통적인-work-flow"&gt;
 Spring MVC의 전통적인 Work Flow
 &lt;a class="heading-anchor" href="#spring-mvc%ec%9d%98-%ec%a0%84%ed%86%b5%ec%a0%81%ec%9d%b8-work-flow" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/spring/traditional-mvc-work-flow.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Client는 URI 형식으로 웹서비스에 요청을 보낸다.&lt;/li&gt;
&lt;li&gt;요청은 Handler Mapping과 그 타입을 찾는 DispatcherServlet에 의해 인터셉트&lt;/li&gt;
&lt;li&gt;요청은 Controller에 의해 처리되고 응답은 DispatcherServlet으로 return된 후 DispatcherServlet은 View로 디스패치&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;위의 그림을 보면 전통적인 Spring MVC Work Flow는 ModelAndView 객체가 Controller에서 Client로 전달되는 것을 알 수 있다. &lt;code&gt;@ResponseBody&lt;/code&gt; annotation을 사용하면 View를 return하지 않고 Controller에서 직접 데이터를 return 할 수 있다. Spring 4.0부터는 &lt;code&gt;@RestController&lt;/code&gt; annotation을 통해 더 단순화 되었다.&lt;/p&gt;
&lt;p&gt;Client -&amp;gt; Request -&amp;gt; DispatcherServlet -&amp;gt; HandlerMapping -&amp;gt; Controller -&amp;gt; View -&amp;gt; DispatcherServlet -&amp;gt; Response -&amp;gt; Client&lt;/p&gt;
&lt;h4 id="controllerbasiccontroller"&gt;
 Controller(BasicController)
 &lt;a class="heading-anchor" href="#controllerbasiccontroller" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;com.chris.springmvcproj.controller.test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;org.springframework.stereotype.Controller&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;org.springframework.web.bind.annotation.RequestMapping&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Controller&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/basic/*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BasicController&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/hello&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;helloWorld&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="viewhellojsp"&gt;
 View(hello.jsp)
 &lt;a class="heading-anchor" href="#viewhellojsp" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;%@ page language=&amp;#34;java&amp;#34; contentType=&amp;#34;text/html; charset=UTF-8&amp;#34; pageEncoding=&amp;#34;UTF-8&amp;#34;%&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;text/html; charset=UTF-8&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; Hello World
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="responsebody"&gt;
 &lt;code&gt;@ResponseBody&lt;/code&gt;
 &lt;a class="heading-anchor" href="#responsebody" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h3 id="spring-3x-mvc-restful-web-service-work-flow"&gt;
 Spring 3.x MVC Restful Web Service Work Flow
 &lt;a class="heading-anchor" href="#spring-3x-mvc-restful-web-service-work-flow" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/spring/3x-mvc-restful-web-services-work-flow.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Client -&amp;gt; Request -&amp;gt; DispatcherServlet -&amp;gt; HandlerMapping -&amp;gt; Controller(ResponseBody) -&amp;gt; Response -&amp;gt; Client&lt;/p&gt;
&lt;h4 id="controllerbasiccontroller2"&gt;
 Controller(BasicController2)
 &lt;a class="heading-anchor" href="#controllerbasiccontroller2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/basic/*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BasicController2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/sendVO&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//@ResponseBody &amp;lt;- Method 상단 또는 return 타입 앞에 annotation 추가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@ResponseBody&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;helloworld&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setBno&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Chris&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;게시글 내용입니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setRecnt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;게시글 1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUserName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Chris&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;@ResponseBody&lt;/code&gt;을 사용하면, Spring은 HTTP 응답에 return 값을 자동으로 변환해준다. Controller Class의 각 Method에 &lt;code&gt;@ResponseBody&lt;/code&gt; annotation을 작성해줘야 한다.&lt;/p&gt;
&lt;h3 id="restcontroller"&gt;
 &lt;code&gt;@RestController&lt;/code&gt;
 &lt;a class="heading-anchor" href="#restcontroller" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h3 id="spring-4x-mvc-restful-web-service-work-flow"&gt;
 Spring 4.x MVC Restful Web Service Work Flow
 &lt;a class="heading-anchor" href="#spring-4x-mvc-restful-web-service-work-flow" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/spring/4x-mvc-restful-web-services-work-flow.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Client -&amp;gt; HTTP Request -&amp;gt; DispatcherServlet -&amp;gt; HandlerMapping -&amp;gt; RestController(자동 ResponseBody 추가) -&amp;gt; HTTP Response -&amp;gt; Client&lt;/p&gt;
&lt;h4 id="restcontrollerrestcontroller"&gt;
 RestController(RestController)
 &lt;a class="heading-anchor" href="#restcontrollerrestcontroller" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;com.chris.springmvcproj.controller.test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;java.util.ArrayList&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;java.util.HashMap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;org.springframework.web.bind.annotation.RequestMapping&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;org.springframework.web.bind.annotation.RestController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;com.chris.springmvcproj.model.board.dto.BoardVO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RestController&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/basic/*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ControllerRest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// json객체 리턴&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/sendVO2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;sendVO2&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setBno&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Chris&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;게시글 내용입니다&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setRecnt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;게시글 1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUserName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Chris&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// json 객체 배열 리턴&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/sendList&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;sendList&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// ArrayList 객체 생성&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="n"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//vo 객체 생성&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setBno&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Chris&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;게시글 내용입니다&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setRecnt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;게시글&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUserName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Chris&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 리스트에 vo추가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 리스트를 리턴함&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// json객체를 map에 저장하여&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/sendMap&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;sendMap&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Map&amp;lt;Key자료형, Value자료형&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="n"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//vo 객체 생성&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setBno&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Chris&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;게시글 내용입니다&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setRecnt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;게시글&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUserName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Chris&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 맵에 vo추가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;61&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;62&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;63&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;64&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Spring 4.0에서는 &lt;code&gt;@RestController&lt;/code&gt; annotation이 추가 되었는데 Controller Class의 각 Method마다 &lt;code&gt;@ResponseBody&lt;/code&gt;을 추가할 필요가 없어졌고, 모든 Method는 &lt;code&gt;@ResponseBody&lt;/code&gt; annotation이 기본으로 작동이 된다.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="responseentity"&gt;
 ResponseEntity
 &lt;a class="heading-anchor" href="#responseentity" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;RestController는 별도의 View를 제공하지 않는 형태로 서비스를 실행하기 때문에, 때로는 결과데이터가 예외적인 상황에서 문제가 발생할 수 있다.&lt;/li&gt;
&lt;li&gt;ResponseEntity는 개발자가 직접 결과 데이터와 HTTP 상태 코드를 직접 제어할 수 있는 클래스로 개발자는 404나 500 같은 HTTP 상태 코드를 전송하고 싶은 데이터와 함께 전송할 수 있기 때문에 좀 더 세밀한 제어가 필요한 경우 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ResponseEntity : 데이터 + http status code&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/sendMap2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;sendMap2&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Map&amp;lt;Key 자료형, Value 자료형&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Map&amp;lt;Integer, BoardVO&amp;gt; map = new HashMap&amp;lt;Integer, BoardVO&amp;gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BoardVO&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//vo 객체 생성&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setBno&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Cris&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;게시글 내용입니다.&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setRecnt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;게시글&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUserName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Chris&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// map에 vo 추가&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// return시 map과 상태 메시지를 함께 전송&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HttpStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;INTERNAL_SERVER_ERROR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/sendErrorAuth&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;sendListAuth&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;BAD_REQUEST&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="restcontroller--view가-필요-없는-api만-지원하는-서비스에서-사용-responsebody를-포함하고-있음-view가-필요한-곳에서-restcontroller를-사용해서-class를-매핑해버리면-view로-접근을-못하는-문제가-있음"&gt;
 &lt;code&gt;@RestController&lt;/code&gt; : View가 필요 없는 API만 지원하는 서비스에서 사용, &lt;code&gt;@ResponseBody&lt;/code&gt;를 포함하고 있음. (View가 필요한 곳에서 &lt;code&gt;@RestController&lt;/code&gt;를 사용해서 Class를 매핑해버리면, View로 접근을 못하는 문제가 있음)
 &lt;a class="heading-anchor" href="#restcontroller--view%ea%b0%80-%ed%95%84%ec%9a%94-%ec%97%86%eb%8a%94-api%eb%a7%8c-%ec%a7%80%ec%9b%90%ed%95%98%eb%8a%94-%ec%84%9c%eb%b9%84%ec%8a%a4%ec%97%90%ec%84%9c-%ec%82%ac%ec%9a%a9-responsebody%eb%a5%bc-%ed%8f%ac%ed%95%a8%ed%95%98%ea%b3%a0-%ec%9e%88%ec%9d%8c-view%ea%b0%80-%ed%95%84%ec%9a%94%ed%95%9c-%ea%b3%b3%ec%97%90%ec%84%9c-restcontroller%eb%a5%bc-%ec%82%ac%ec%9a%a9%ed%95%b4%ec%84%9c-class%eb%a5%bc-%eb%a7%a4%ed%95%91%ed%95%b4%eb%b2%84%eb%a6%ac%eb%a9%b4-view%eb%a1%9c-%ec%a0%91%ea%b7%bc%ec%9d%84-%eb%aa%bb%ed%95%98%eb%8a%94-%eb%ac%b8%ec%a0%9c%ea%b0%80-%ec%9e%88%ec%9d%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h3 id="controller--api와-view를-동시에-사용-대신-api-서비스는-responsebody를-붙여줘야-함"&gt;
 &lt;code&gt;@Controller&lt;/code&gt; : API와 View를 동시에 사용, 대신 API 서비스는 &lt;code&gt;@ResponseBody&lt;/code&gt;를 붙여줘야 함.
 &lt;a class="heading-anchor" href="#controller--api%ec%99%80-view%eb%a5%bc-%eb%8f%99%ec%8b%9c%ec%97%90-%ec%82%ac%ec%9a%a9-%eb%8c%80%ec%8b%a0-api-%ec%84%9c%eb%b9%84%ec%8a%a4%eb%8a%94-responsebody%eb%a5%bc-%eb%b6%99%ec%97%ac%ec%a4%98%ec%95%bc-%ed%95%a8" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;</description></item><item><title>Spring framework home.jsp 구동 과정과 web.xml, servlet-context.xml은 무엇인가?</title><link>https://kyungryeol-yoon.github.io/backend/spring/spring-framework-process/</link><pubDate>Sun, 16 Oct 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/spring/spring-framework-process/</guid><description>&lt;p&gt;Spring project를 생성하고 바로 실행하면 browser에 home.jsp가 실행된다.\
여기서 home.jsp가 구동되는 과정은 아래와 같다.
&lt;img src="https://kyungryeol-yoon.github.io/images/spring/spring-process.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;클라이어트 요청(/, root 페이지 요청)&lt;/li&gt;
&lt;li&gt;web.xml에서 dispatcherServlet가 클라이언트 요청을 핸들링&lt;/li&gt;
&lt;li&gt;servlet-context.xml에서 해당 클래스의 웹요청을 처리하는 컨트롤러를 사용(HandlerMapping으로 Controller를 검색)&lt;/li&gt;
&lt;li&gt;해당 Controller가 요청을 처리 후, home을 리턴&lt;/li&gt;
&lt;li&gt;View에 출력&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="dispatcherservlet"&gt;
 DispatcherServlet
 &lt;a class="heading-anchor" href="#dispatcherservlet" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="model-controller-view를-조합하여-browser로-출력해주는-역할을-수행하는-class"&gt;
 Model, Controller, View를 조합하여 browser로 출력해주는 역할을 수행하는 class
 &lt;a class="heading-anchor" href="#model-controller-view%eb%a5%bc-%ec%a1%b0%ed%95%a9%ed%95%98%ec%97%ac-browser%eb%a1%9c-%ec%b6%9c%eb%a0%a5%ed%95%b4%ec%a3%bc%eb%8a%94-%ec%97%ad%ed%95%a0%ec%9d%84-%ec%88%98%ed%96%89%ed%95%98%eb%8a%94-class" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/spring/dispatcher-servlet.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="01-web-infwebxml"&gt;
 01. /WEB-INF/web.xml
 &lt;a class="heading-anchor" href="#01-web-infwebxml" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="웹프로젝트의-배치-기술서deploy-descriptor-웹프로젝트의-환경-설정-파일"&gt;
 웹프로젝트의 배치 기술서(deploy descriptor, 웹프로젝트의 환경 설정 파일)
 &lt;a class="heading-anchor" href="#%ec%9b%b9%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8%ec%9d%98-%eb%b0%b0%ec%b9%98-%ea%b8%b0%ec%88%a0%ec%84%9cdeploy-descriptor-%ec%9b%b9%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8%ec%9d%98-%ed%99%98%ea%b2%bd-%ec%84%a4%ec%a0%95-%ed%8c%8c%ec%9d%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Spring project가 실행되면 가장 먼저 web.xml을 읽어 들이게 되고 위에서부터 차례대로 태그들을 해석하기 시작한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;web-app&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;2.5&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;http://java.sun.com/xml/ns/javaee&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;http://www.w3.org/2001/XMLSchema-instance&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;http://java.sun.com/xml/ns/javaee
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- The definition of the Root Spring Container shared by all Servlets and Filters --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;context-param&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;param-name&amp;gt;&lt;/span&gt;contextConfigLocation&lt;span class="nt"&gt;&amp;lt;/param-name&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- 스프링의 환경설정 파일인 root-context.xml을 가장 먼저 참조한다--&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;param-value&amp;gt;&lt;/span&gt;/WEB-INF/spring/root-context.xml&lt;span class="nt"&gt;&amp;lt;/param-value&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/context-param&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- Creates the Spring Container shared by all Servlets and Filters --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;listener&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;listener-class&amp;gt;&lt;/span&gt;org.springframework.web.context.ContextLoaderListener&lt;span class="nt"&gt;&amp;lt;/listener-class&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/listener&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- Processes application requests --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;servlet&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;servlet-name&amp;gt;&lt;/span&gt;appServlet&lt;span class="nt"&gt;&amp;lt;/servlet-name&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- 스프링에 내장된 서블릿 클래스--&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;servlet-class&amp;gt;&lt;/span&gt;org.springframework.web.servlet.DispatcherServlet&lt;span class="nt"&gt;&amp;lt;/servlet-class&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;init-param&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;param-name&amp;gt;&lt;/span&gt;contextConfigLocation&lt;span class="nt"&gt;&amp;lt;/param-name&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- /WEB-INF/spring/appServlet/servlet-context.xml을 참조 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- xml 파일 안에 정의된 객체들을 로딩한다. --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;param-value&amp;gt;&lt;/span&gt;/WEB-INF/spring/appServlet/servlet-context.xml&lt;span class="nt"&gt;&amp;lt;/param-value&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/init-param&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- 가장 첫번째 우선순위를 뜻한다. --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;load-on-startup&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/load-on-startup&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/servlet&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;servlet-mapping&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;servlet-name&amp;gt;&lt;/span&gt;appServlet&lt;span class="nt"&gt;&amp;lt;/servlet-name&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;url-pattern&amp;gt;&lt;/span&gt;/&lt;span class="nt"&gt;&amp;lt;/url-pattern&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- DispatcherServlet이 모든 요청을 가로챌 수 있도록 등록 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- 특정 url으로 변경하여 사용가능 ex) *.do --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/servlet-mapping&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/web-app&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="02-web-infspringroot-contextxml"&gt;
 02. /WEB-INF/spring/root-context.xml
 &lt;a class="heading-anchor" href="#02-web-infspringroot-contextxml" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="spring의-환경-설정-파일"&gt;
 Spring의 환경 설정 파일
 &lt;a class="heading-anchor" href="#spring%ec%9d%98-%ed%99%98%ea%b2%bd-%ec%84%a4%ec%a0%95-%ed%8c%8c%ec%9d%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;현재는 별다른 내용을 작성하지 않았기 때문에 web.xml에서는 root-context.xml을 건너 뛰게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;beans&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;http://www.springframework.org/schema/beans&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;http://www.w3.org/2001/XMLSchema-instance&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;http://www.springframework.org/schema/beans
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; http://www.springframework.org/schema/beans/spring-beans.xsd&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- Root Context: defines shared resources visible to all other web components --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="03-servlet-contextxml"&gt;
 03. servlet-context.xml
 &lt;a class="heading-anchor" href="#03-servlet-contextxml" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;web.xml에서 DispatcherServlet(Spring에 내장된 컨트롤러)로 이동하게 되고, /WEB-INF/spring/appServlet/servlet-context.xml을 참조하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;beans:beans&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;http://www.springframework.org/schema/mvc&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;http://www.w3.org/2001/XMLSchema-instance&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;xmlns:beans=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;http://www.springframework.org/schema/beans&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;xmlns:context=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;http://www.springframework.org/schema/context&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;http://www.springframework.org/schema/mvc
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; http://www.springframework.org/schema/mvc/spring-mvc.xsd
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; http://www.springframework.org/schema/beans
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; http://www.springframework.org/schema/beans/spring-beans.xsd
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; http://www.springframework.org/schema/context
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; http://www.springframework.org/schema/context/spring-context.xsd&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- DispatcherServlet Context: defines this servlet&amp;#39;s
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt; request-processing infrastructure --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- Enables the Spring MVC @Controller programming model --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- 애노테이션을 사용가능하도록 설정 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;annotation-driven&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- Handles HTTP GET requests for /resources/** by efficiently serving up
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt; static resources in the ${webappRoot}/resources directory --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;resources&lt;/span&gt; &lt;span class="na"&gt;mapping=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/resources/**&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;location=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/resources/&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- Resolves views selected for rendering by @Controllers to .jsp
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt; resources in the /WEB-INF/views directory --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- view resolver(뷰리졸버, 뷰 해석기) --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;beans:bean&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;org.springframework.web.servlet.view.InternalResourceViewResolver&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- 뷰(jsp)의 접두어, 접미어 설정 : 파일명만 작성할 수 있게 세팅 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- 접두어(Directory) --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;beans:property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;prefix&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/WEB-INF/views/&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- 접미어(확장자) --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;beans:property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;suffix&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;.jsp&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/beans:bean&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/beans:beans&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="04-homecontroller"&gt;
 04. HomeController
 &lt;a class="heading-anchor" href="#04-homecontroller" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;com.chris.springmvcproj&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;java.text.DateFormat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;java.util.Date&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;java.util.Locale&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;org.slf4j.Logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;org.slf4j.LoggerFactory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;org.springframework.stereotype.Controller&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;org.springframework.ui.Model&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;org.springframework.web.bind.annotation.RequestMapping&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;org.springframework.web.bind.annotation.RequestMethod&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Controller 애노테이션&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Controller&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HomeController&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Logger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LoggerFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HomeController&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// url mapping&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 기본, 루트 페이지 =&amp;gt; home메서드 호출&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;RequestMethod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;home&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Locale&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Welcome home! The client locale is {}.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DateFormat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dateFormat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DateFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDateTimeInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LONG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DateFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LONG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;formattedDate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dateFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 모델(서블릿의 request 객체를 대체한 것)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;serverTime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;formattedDate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// home.jsp로 포워딩&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// servlet-context.xml&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// &amp;lt;beans:property name=&amp;#34;prefix&amp;#34; value=&amp;#34;/WEB-INF/views/&amp;#34; /&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// &amp;lt;beans:property name=&amp;#34;suffix&amp;#34; value=&amp;#34;.jsp&amp;#34; /&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Directory(접두어)와 jsp(접미어)확장자를 제외하고 이름만 작성하도록 세팅&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;home&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Spring framework 특징 및 구성, 구조</title><link>https://kyungryeol-yoon.github.io/backend/spring/spring-framework-directory/</link><pubDate>Sat, 15 Oct 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/backend/spring/spring-framework-directory/</guid><description>&lt;h2 id="spring-framework란"&gt;
 Spring framework란?
 &lt;a class="heading-anchor" href="#spring-framework%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;자바 엔터프라이즈 개발을 편하게 해주는 오픈소스 경량급 애플리케이션 프레임워크&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="pojoplain-old-java-object-기반의-구성"&gt;
 POJO(Plain Old Java Object) 기반의 구성
 &lt;a class="heading-anchor" href="#pojoplain-old-java-object-%ea%b8%b0%eb%b0%98%ec%9d%98-%ea%b5%ac%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="pojo란"&gt;
 POJO란?
 &lt;a class="heading-anchor" href="#pojo%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;오래된 방식의 간단한 자바 오브젝트라는 말로서 객체지향적인 원리에 충실하면서, 환경과 기술에 종속되지 않고 필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트를 의마한다.\
즉, 별도의 API가 필요하지 않은 일반적인 자바 코드를 이용하여 개발이 가능하다.&lt;/p&gt;
&lt;h4 id="pojo의-조건"&gt;
 POJO의 조건
 &lt;a class="heading-anchor" href="#pojo%ec%9d%98-%ec%a1%b0%ea%b1%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;특정 규챡에 종속되지 않는다.&lt;/li&gt;
&lt;li&gt;특정 환경에 종속되지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="di의존성-주입을-통한-객체간의-관계구성"&gt;
 DI(의존성 주입)을 통한 객체간의 관계구성
 &lt;a class="heading-anchor" href="#di%ec%9d%98%ec%a1%b4%ec%84%b1-%ec%a3%bc%ec%9e%85%ec%9d%84-%ed%86%b5%ed%95%9c-%ea%b0%9d%ec%b2%b4%ea%b0%84%ec%9d%98-%ea%b4%80%ea%b3%84%ea%b5%ac%ec%84%b1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;객체 간의 의존성을 개발자가 설정하는 것이 아닌 Spring 컨테이너가 주입시켜주는 기능&lt;/li&gt;
&lt;li&gt;객체를 쉽게 확장하고 재사용할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="aopaspect-oriented-programming-관점-지향-프로그래밍-지원"&gt;
 AOP(Aspect Oriented Programming, 관점 지향 프로그래밍) 지원
 &lt;a class="heading-anchor" href="#aopaspect-oriented-programming-%ea%b4%80%ec%a0%90-%ec%a7%80%ed%96%a5-%ed%94%84%eb%a1%9c%ea%b7%b8%eb%9e%98%eb%b0%8d-%ec%a7%80%ec%9b%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;반복적인 코드를 줄이고, 개발자가 비지니스 로직에만 집중할 수 있도록 지원한다.&lt;/li&gt;
&lt;li&gt;핵심로직이 중요하지, 부수적인 코드가 중요한 것이 아니다.&lt;/li&gt;
&lt;li&gt;Spring은 반드시 처리가 필요한 부분을 &amp;lsquo;횡단 관심사&amp;rsquo;라고 하며, 이러한 횡단 관심사를 분리해 제작하는 것이 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="편리한-mvc-구조"&gt;
 편리한 MVC 구조
 &lt;a class="heading-anchor" href="#%ed%8e%b8%eb%a6%ac%ed%95%9c-mvc-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h2 id="was에-종속적이지-않은-개발-환경"&gt;
 WAS에 종속적이지 않은 개발 환경
 &lt;a class="heading-anchor" href="#was%ec%97%90-%ec%a2%85%ec%86%8d%ec%a0%81%ec%9d%b4%ec%a7%80-%ec%95%8a%ec%9d%80-%ea%b0%9c%eb%b0%9c-%ed%99%98%ea%b2%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h2 id="iocinversion-of-control-제어의-역전--객체에-대한-제어권"&gt;
 IoC(Inversion of Control, 제어의 역전) = 객체에 대한 제어권
 &lt;a class="heading-anchor" href="#iocinversion-of-control-%ec%a0%9c%ec%96%b4%ec%9d%98-%ec%97%ad%ec%a0%84--%ea%b0%9d%ec%b2%b4%ec%97%90-%eb%8c%80%ed%95%9c-%ec%a0%9c%ec%96%b4%ea%b6%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;기존에는 개발자에게 제어권이 있었다. (new 연산자로 객체생성)&lt;/li&gt;
&lt;li&gt;객체의 제어권을 스프링에게 넘김(개발자에게 편리함을 제공, 코드의 최소화)&lt;/li&gt;
&lt;li&gt;인스턴스의 라이프 사이클(생성-&amp;gt;소멸)을 개발자가 아닌 Spring 컨테이너가 담당&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="트랜잭션transaction의-지원"&gt;
 트랜잭션(Transaction)의 지원
 &lt;a class="heading-anchor" href="#%ed%8a%b8%eb%9e%9c%ec%9e%ad%ec%85%98transaction%ec%9d%98-%ec%a7%80%ec%9b%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;복잡한 트랜잭션관리를 애노테이션이나 XML로 설정할 수 있기 때문에 개발자가 매번 상황에 맞는 코드를 작성할 수 없게 설계&lt;/p&gt;
&lt;h1 id="spring-project-directory-구조"&gt;
 Spring Project Directory 구조
 &lt;a class="heading-anchor" href="#spring-project-directory-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/spring/directory/src-main-java.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/dt&gt;
&lt;dd&gt;&lt;strong&gt;src/main/java :&lt;/strong&gt; 자바 코드 (컨트롤러, 모델)&lt;/dd&gt;
&lt;dt&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/spring/directory/src-main-resources.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/dt&gt;
&lt;dd&gt;&lt;strong&gt;src/main/resources :&lt;/strong&gt; 자바 코드에서 사용할 리소스 (mapper, sql)&lt;/dd&gt;
&lt;dt&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/spring/directory/src-test-java.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/dt&gt;
&lt;dd&gt;&lt;strong&gt;src/test/java :&lt;/strong&gt; 테스트 코드&lt;/dd&gt;
&lt;dt&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/spring/directory/src-test-resources.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/dt&gt;
&lt;dd&gt;&lt;strong&gt;src/test/resources :&lt;/strong&gt; 테스트 코드에서 사용할 리소스&lt;/dd&gt;
&lt;dt&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/spring/directory/maven-dependencies.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/dt&gt;
&lt;dd&gt;&lt;strong&gt;Maven Dependencies :&lt;/strong&gt; 라이브러리 관리도구 (Maven에서 다운받은 jar 파일)&lt;/dd&gt;
&lt;dt&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/spring/directory/src-main-webapp.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/dt&gt;
&lt;dd&gt;&lt;strong&gt;src :&lt;/strong&gt; web Directory&lt;/dd&gt;
&lt;dd&gt;&lt;strong&gt;src/main/webapp/resources :&lt;/strong&gt; js, css, image 등을 관리&lt;/dd&gt;
&lt;dd&gt;&lt;strong&gt;src/main/webapp/WEB-INF/classes :&lt;/strong&gt; 컴파일된 클래스&lt;/dd&gt;
&lt;dd&gt;&lt;strong&gt;src/main/webapp/WEB-INF/spirng :&lt;/strong&gt; Spring 환경 설정 파일 (root-context.xml, servlet-context.xml)&lt;/dd&gt;
&lt;dd&gt;&lt;strong&gt;src/main/webapp/WEB-INF/views :&lt;/strong&gt; html, jsp 파일&lt;br/&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;strong&gt;src/main/webapp/ :&lt;/strong&gt; 외부 접근 가능&lt;/dd&gt;
&lt;dd&gt;&lt;strong&gt;src/main/webapp/WEB-INF :&lt;/strong&gt; 외부 접근 불가, 컨트롤러를 경유해서 접근 가능&lt;/dd&gt;
&lt;/dl&gt;
&lt;h3 id="web-inf-폴더"&gt;
 WEB-INF 폴더
 &lt;a class="heading-anchor" href="#web-inf-%ed%8f%b4%eb%8d%94" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;외부에서 직접 접속이 차단되어있다.\
그 이유는 컴파일된 클래스와 Spring 환경설정파일(DB연결정보)이 존재하기 때문이다.\
JSP 또한 외부로 접속하여 수정되는 것을 방지하기 위한 보안 때문에 외부접근이 금지되어 있기 때문이다.&lt;/p&gt;
&lt;h3 id="pomxml--maven에서-참조하는-환경설정파일"&gt;
 pom.xml : maven에서 참조하는 환경설정파일
 &lt;a class="heading-anchor" href="#pomxml--maven%ec%97%90%ec%84%9c-%ec%b0%b8%ec%a1%b0%ed%95%98%eb%8a%94-%ed%99%98%ea%b2%bd%ec%84%a4%ec%a0%95%ed%8c%8c%ec%9d%bc" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;maven은 빌드와 관련된 정보를 프로젝트 객체모델(Project Object Model)이라는 이름으로 정의하고 사용하는데 pom이라는 이름으로 된 pom.xml 파일을 사용한다.&lt;/p&gt;
&lt;h3 id="maven의-로컬-저장소"&gt;
 maven의 로컬 저장소
 &lt;a class="heading-anchor" href="#maven%ec%9d%98-%eb%a1%9c%ec%bb%ac-%ec%a0%80%ec%9e%a5%ec%86%8c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;C:Users\사용자계정.m2\repository&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;pom.xml에서 dependency 태그를 추가하고 설정하고 싶은 라이브러리를 추가하면 된다.\
라이브러리는 maven repository에서 원하는 라이브러리를 검색하여 내용을 복사하여 추가해주면 maven이 알아서 jar파일을 로컬저장소에 다운받아준다.\
&lt;a href="https://mvnrepository.com/"&gt;https://mvnrepository.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;여기서 Spring의 장점 중에 하나를 알 수 있다.\
기존의 웹프로젝트의 경우에는 프로젝트에 필요한 모든 라이브러리 파일을 직접 다운로드 받아 해당 라이브러리 폴더에 적용시켜줘야했고, 각각의 프로젝트마다 다시 또 적용해야하는 불편함이 있었는데 Spring의 경우에는 denpendency 태그를 적용시켜주면 알아서 다운로드 받고 해당 프로젝트에 적용할 수 있다.\
또한 다른 프로젝트 생성 시에는 같은 denpendency 태그만 적용시켜주면 별도의 다운로드가 필요없이 로컬저장소에 저장된 라이브러리를 자동으로 적용시켜준다.&lt;/p&gt;
&lt;h3 id="mvn-repository에서-msyql-검색-후-dependency-태그-복수-후-pomxml에-붙여넣기-하면-된다"&gt;
 MVN repository에서 msyql 검색 후 dependency 태그 복수 후 pom.xml에 붙여넣기 하면 된다.
 &lt;a class="heading-anchor" href="#mvn-repository%ec%97%90%ec%84%9c-msyql-%ea%b2%80%ec%83%89-%ed%9b%84-dependency-%ed%83%9c%ea%b7%b8-%eb%b3%b5%ec%88%98-%ed%9b%84-pomxml%ec%97%90-%eb%b6%99%ec%97%ac%eb%84%a3%ea%b8%b0-%ed%95%98%eb%a9%b4-%eb%90%9c%eb%8b%a4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/spring/maven/mvn-repository.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>Compilation Process</title><link>https://kyungryeol-yoon.github.io/cs/sw-theory/compilation-process/</link><pubDate>Thu, 12 May 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/cs/sw-theory/compilation-process/</guid><description>&lt;ul&gt;
&lt;li&gt;컴파일 과정은 프로그램을 만드는 데 있어서 반드시 알아야 하는 내용은 아니지만 이 과정을 머리속에 담고 있는 개발자는 앞으로 무수히 부딪히게 될 많은 문제나 오류들을 이해하는데 &lt;strong&gt;훨씬 큰 이점&lt;/strong&gt;을 얻게 될 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="compile-과정이란"&gt;
 &lt;strong&gt;Compile 과정이란?&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#compile-%ea%b3%bc%ec%a0%95%ec%9d%b4%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;컴퓨터 프로그램의 개발은 코드 작성(프로그래밍)부터 시작된다.&lt;/li&gt;
&lt;li&gt;이렇게 작성된 코드는 사용자(개발자)가 컴퓨터가 수행해 주기를 원하는 내용을 기술한 것이지만, 컴퓨터가 이해할 수 있는 문법(언어)이 아닌 사용자가 이해할 수 있는 문법이다.&lt;/li&gt;
&lt;li&gt;따라서 작성된 코드는 &lt;strong&gt;컴파일(Compile)&lt;/strong&gt; 과정을 거쳐 컴퓨터가 이해할 수 있는 언어로 변환되며, 컴파일된 파일을 **오브젝트 파일(Object File)**이라고 부른다.&lt;/li&gt;
&lt;li&gt;일반적으로 하나의 프로그램은 여러 개의 오브젝트 파일과 공용 라이브러리로 조합이 되며, 하나의 컴퓨터가 실행할 수 있는 프로그램을 완성화기 위한 작업을 **링킹(Linking)**이라고 부른다.&lt;/li&gt;
&lt;li&gt;결국 코드를 컴파일 과정과 링킹 과정을 거치면 사용자가 실행할 수 있는 **실행 파일(ex. EXE 파일)**이 생성된다.&lt;/li&gt;
&lt;li&gt;완성된 실행파일을 사용자가 실행(Execute)하게 되면 컴퓨터는 해당 프로그램의 내용을 메모리에 적재(Load)시키고 내용에 따라 프로그램을 수행하게 된다.&lt;/li&gt;
&lt;li&gt;이러한 일을 수행하는 프로그램을 **로더(Loader)**라고 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/compilation-process/compilation-process.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;개발자가 작성한 코드는 위의 과정을 거쳐 실행 가능한 **바이너리 파일(Binary File)**로 만들어진다.&lt;/li&gt;
&lt;li&gt;이렇게 만들어진 실행파일을 실행하면 바이너리 파일의 내용들이 **주기억장치(Ram)**로 **적재(Load)**되어 시스템에서 동작하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="전처리기preprocessor란"&gt;
 &lt;strong&gt;전처리기(Preprocessor)란?&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%a0%84%ec%b2%98%eb%a6%ac%ea%b8%b0preprocessor%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;컴파일 하기 직전에 처리하는 컴파일러의 한 부분이다.&lt;/li&gt;
&lt;li&gt;전처리기가 하는 일은 #define처럼 치환의 역할을 하기도 하고, 디버깅에도 도움을 주며 헤더파일의 중복 포함도 방지해준다.&lt;/li&gt;
&lt;li&gt;전처리기에서는 몇가지 지시자들을 처리하게 된다.&lt;/li&gt;
&lt;li&gt;이 지시자들은 **#**라는 기호로 시작한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="include-headerh"&gt;
 &lt;strong&gt;#include &amp;lt;header.h&amp;gt;&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#include-headerh" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;가장 흔히 볼 수 있는 전처리기이다.&lt;/li&gt;
&lt;li&gt;해당 파일을 찾아서 컴파일러가 그 파일이 마치 현재 컴파일하는 소스 코드에 포함되어 있는 것 같이 해준다.&lt;/li&gt;
&lt;li&gt;&amp;lt;&amp;gt;는 표준 헤더 파일일 경우에 설정되어 있는 폴더에서 헤더 파일을 찾으며, &amp;ldquo;&amp;ldquo;는 그 외 폴더에서 찾을 수 있는데 최우선으로 현재 프로젝트 폴더에서 찾게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="define"&gt;
 &lt;strong&gt;#define&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#define" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;define문은 여러 경우에 사용될 수 있는데 일반적으로 문자열 대치에 사용된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-------------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define MAX 512
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-------------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define MAX
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#ifdef MAX
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Max is defined!&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#else
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Max is not defined!&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#endif
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-------------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#ifdef MAX
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#elif defined(MIN)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#else
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#endif
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-------------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#if defined(MAX)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#elif defined(MIN)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#else
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#endif
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-------------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// [관련된 주요 전처리기 명령어]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#ifdef
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#ifndef
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#undef
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#if defined
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#if !defined
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#elif
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#else
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#endif&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="포함감시inclusion-guard"&gt;
 &lt;strong&gt;포함감시(Inclusion Guard)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ed%8f%ac%ed%95%a8%ea%b0%90%ec%8b%9cinclusion-guard" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;여러 개의 헤더 파일(.h 또는 .hpp)과 구현 파일(.c 또는 .cpp)들이 있을 경우 헤더 파일이 중복 포함되는 경우가 많다. 포함 감시 기능은 만드는 모든 헤더 파일에 적용하도록 하자.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#ifndef FILENAME_H
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define FILENAME_H
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 여기에 헤더 파일의 모든 내용을 넣는다.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#endif
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-------------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;filename.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;filename.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 두 번째 헤더 파일이 포함될 때 #ifndef가 거짓이 되어 헤더 파일이 포함되지 않는다.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;포함 감시 기능을 이용하여 두 번째 헤더 파일이 포함될 때 #ifndef가 거짓이 되어 헤더 파일이 포함되지 않는다.&lt;/li&gt;
&lt;li&gt;FILENAME_H 부분은 관례상 파일명을 이용해서 이렇게 명명한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_FILENAME_H&lt;/code&gt; 또는 &lt;code&gt;__FILENAME_H__&lt;/code&gt; 등 잘 사용되지 않는 문자열을 파일 이름을 사용해서 만드는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="매크로-함수macro-function"&gt;
 &lt;strong&gt;매크로 함수(Macro Function)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%eb%a7%a4%ed%81%ac%eb%a1%9c-%ed%95%a8%ec%88%98macro-function" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;매크로 함수도 전처리기로 흔히 사용된다. 다만 디버깅이 힘들다는 단점 때문에 점점 사용되지 않고 있다고 들었다.
&lt;ul&gt;
&lt;li&gt;특히, C++의 경우 엄격한 형 검사를 하게 되는데 매크로 함수를 사용하게 되면 그 기능을 사용할 수 없으니 피해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;C++ 사용자는 매크로 함수보다는 &lt;strong&gt;Template&lt;/strong&gt; 또는 &lt;strong&gt;inline&lt;/strong&gt; 함수를 사용해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define CUBE(x) ((x)*(x)*(x))
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CUBE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-------------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="문자열-조작"&gt;
 &lt;strong&gt;문자열 조작&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%eb%ac%b8%ec%9e%90%ec%97%b4-%ec%a1%b0%ec%9e%91" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define SAY(x) printf(#x)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SAY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 위와 같이 식별자 앞에 #을 붙이게 되면 자동으로 &amp;#34;x&amp;#34;와 같이 &amp;#34;&amp;#34;로 둘러싸준다.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-------------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Hello, world!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="문자열-결합"&gt;
 &lt;strong&gt;문자열 결합&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%eb%ac%b8%ec%9e%90%ec%97%b4-%ea%b2%b0%ed%95%a9" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define Print(x) Print ## x
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ##은 두 개의 문자열을 결합해 준다.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Pirnt(One)을 사용하면 PrintOne이라는 문자열로 대치되고 Print(Two)는 PrintTwo라는 문자열로 대치된다.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="assert"&gt;
 &lt;strong&gt;ASSERT()&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#assert" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;대부분의 컴파일러는 ASSERT() 매크로를 가지고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#ifndef DEBUG
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define ASSERT(x)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#else
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define ASSERT(x) \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;	if(!(x))\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;	{ \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;		printf(#x); \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;		printf(&amp;#34;is Null on line %d in file %s&amp;#34;, __LINE__, __FILE__); \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#endif&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;위 코드의 위에 #define DEBUG를 포함하면 #define ASSERT(x)는 아무 일도 하지 않고, DEBUG가 정의되지 않으면 그 아래 함수가 정의된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;즉, 디버그일 때만 코드가 생성되고 릴리즈시에는 코드가 생서되지 않게 할 수 있는 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;여러 줄이 필요할 때는 ****가 사용되었다는 것에 유의하자.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="내장-매크로"&gt;
 &lt;strong&gt;내장 매크로&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%eb%82%b4%ec%9e%a5-%eb%a7%a4%ed%81%ac%eb%a1%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;컴파일 시에 컴파일러가 미리 정의하고 있는 매크로들이 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;__DATE__&lt;/code&gt; : 컴파일하는 날짜&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;__TIME__&lt;/code&gt; : 컴파일하는 시간&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;__LINE__&lt;/code&gt; : 현재 컴파일하고 있는 줄 번호&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;__FILE__&lt;/code&gt; : 현재 컴파일하고 있는 파일의 이름을&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="error"&gt;
 &lt;strong&gt;error&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#error" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;컴파일러는 이 명령을 만나게 되면 해당 메시지를 출력하고 컴파일을 중지한다.&lt;/li&gt;
&lt;li&gt;C++ 컴파일러에서만 동작하게 하는 다음 코드를 참조하자.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#if !defined(__cplusplus)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#error C++ compiler required.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#endif
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// __cplusplus는 C++ 컴파일러일 경우에 정의되는 내장 매크로이다.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="pragma"&gt;
 &lt;strong&gt;pragma&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#pragma" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;#pragma는 컴파일러마다 고유하게 사용할 수 있는 명령어이다. 따라서 그 문법은 컴파일러마다 다르고 그 종류도 많다.&lt;/li&gt;
&lt;li&gt;#pragma once 같은 경우 위의 포함 감시 기능을 컴파일러가 알아서 해준다. 즉, 한 번 include 된 헤더 파일은 중복해서 포함되지 않도록 컴파일러가 처리해 준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="컴파일-과정---전단부-front-end"&gt;
 &lt;strong&gt;컴파일 과정 - 전단부 (Front-End)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%bb%b4%ed%8c%8c%ec%9d%bc-%ea%b3%bc%ec%a0%95---%ec%a0%84%eb%8b%a8%eb%b6%80-front-end" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/compilation-process/Front-End.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;전단부에서는 언어 종속적인 부분을 처리한다.&lt;/li&gt;
&lt;li&gt;이 단계에서는 C, C++, Java 등의 다른 언어로 작성된 코드들이 각각 다른 모듈에 의해 처리되며, 소스코드가 올바르게 작성되었는지 분석하고, 중단부에 넘겨주기 위한 GIMPLE 트리 (소스코드를 트리 형태로 표현한 자료구조)를 생성하는 일을 수행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;어휘 분석 : C 소스코드를 의미가 있는 최소단위(토큰 : Token)으로 나눈다.&lt;/li&gt;
&lt;li&gt;구문 분석 : 토큰으로 파스 트리(Parse Tree)를 만들면서 문법적 오류를 검출한다.&lt;/li&gt;
&lt;li&gt;의미 분석 : 파스 트리를 이용해 문법적 오류는 없지만 의미상 오류가 있는지 검사한다.(함수의 매개변수를 잘못 사용했다거나 변수의 자료형(Data Type)이 불일치 하는 것 등을 검사)&lt;/li&gt;
&lt;li&gt;중간 표현 생성 : 언어 독립적인 특성을 제공하기 위해 트리 형태의 중간표현(GIMPLE Tree)을 생성한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="컴파일-과정---중단부-middle-end"&gt;
 &lt;strong&gt;컴파일 과정 - 중단부 (Middle-End)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%bb%b4%ed%8c%8c%ec%9d%bc-%ea%b3%bc%ec%a0%95---%ec%a4%91%eb%8b%a8%eb%b6%80-middle-end" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/compilation-process/Middle-End.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;중단부에서는 전단부에서 넘겨 받은 GIMPLE Tree를 **SSA(Static Single Assignment)**형태로 변환한 후에 아키텍쳐 비종속적인 최적화를 수행한 후 최종적으로 후단부에서 사용하는 **RTL(Register Transfer Language : 고급 언어와 어셈블리 언어의 중간 형태)**을 생성한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;아키텍쳐 비종속적인 최적화&lt;/strong&gt;란 서로 다른 CPU 아키텍쳐에 구애받지 않고 공통적으로 수행할 수 있는 최적화를 말한다. 중단부에서는 SSA 기반으로 최적화를 수행한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;**최적화가 왜 중요한가?**에 대해서 설명하자면, 개발자들이 작성한 프로그램이 한번 컴파일 되고 나면 다시 컴파일하기 전까지 변경이 불가능하다. &lt;strong&gt;(물론 리버싱이라는 기법이 있다고 합니다만 여기에서는 논외로 하겠습니다&amp;hellip; 잘 몰라서리&amp;hellip;)&lt;/strong&gt; 그렇기 때문에 최적화를 수행함으로써 컴파일 시간이 오래 걸릴지라도 &lt;strong&gt;프로그램의 수행 속도를 향상&lt;/strong&gt;시켜 &lt;strong&gt;전체 시스템 성능의 효율을 지속적으로 높여주기 때문&lt;/strong&gt;이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SSA 기반 최적화&lt;/strong&gt;는 크게 &lt;strong&gt;지역 최적화, 전역 최적화, 루프 최적화&lt;/strong&gt;로 나눌 수 있는데, 최적화에 관한 내용은 굉장히 방대하여 여기에서는 간략하게 &amp;lsquo;이런 과정들이 있다&amp;rsquo; 정도로만 알고 있으면 되겠다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;최적화가 완료되면 후단부에서 최적화에 사용하기 위해 &lt;strong&gt;RTL(Register Transfer Language)구조&lt;/strong&gt;로 변환한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="컴파일-과정---후단부-back-end"&gt;
 &lt;strong&gt;컴파일 과정 - 후단부 (Back-End)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%bb%b4%ed%8c%8c%ec%9d%bc-%ea%b3%bc%ec%a0%95---%ed%9b%84%eb%8b%a8%eb%b6%80-back-end" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/compilation-process/Back-End.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;후단부에서는 RTL Optimizer에 의해 &lt;strong&gt;아키텍쳐 비종속적인 최적화&lt;/strong&gt;와 함께 &lt;strong&gt;아키텍쳐 종속적인 최적화&lt;/strong&gt;가 수행된다.&lt;/li&gt;
&lt;li&gt;아키텍쳐 종속적인 최적화는 각 프로그램 내의 명령어 중 아키텍쳐별로 좀 더 효율적인 명령어로 대체해 성능을 높이는 작업과 같이 아키텍쳐 특성에 따라 최적화를 수행하는 것을 말한다.&lt;/li&gt;
&lt;li&gt;이렇게 최적화를 마치게 되면 Code Generator &lt;strong&gt;어셈블리어&lt;/strong&gt;로 구성된 .s 파일이 만들어지게 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="컴파일-과정---어셈블-과정"&gt;
 &lt;strong&gt;컴파일 과정 - 어셈블 과정&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%bb%b4%ed%8c%8c%ec%9d%bc-%ea%b3%bc%ec%a0%95---%ec%96%b4%ec%85%88%eb%b8%94-%ea%b3%bc%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;컴파일이 끝난 어셈블리 코드는 어셈블러에 의해 기계어로 어셈블됩니다.&lt;/li&gt;
&lt;li&gt;어셈블러에 의해 생성되는 목적코드(helloworld.o) 파일은 어셈블된 프로그램의 **명령어(Instruction)**과 **데이터(Data)**가 들어있는 &lt;strong&gt;ELF 바이너리 포맷(Binary Format) 구조&lt;/strong&gt;를 갖는다.&lt;/li&gt;
&lt;li&gt;다음 단계인 링킹에서 링커가 여러 개의 바이너리 파일을 하나의 실행 파일로 묶기 위해서 각 바이너리의 정보를 효과적으로 파악하기 위해서(명령어와 데이터의 범위 등) 일정한 규칙을 갖게 형식화 해놓은 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="컴파일-과정---링킹-과정"&gt;
 &lt;strong&gt;컴파일 과정 - 링킹 과정&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%bb%b4%ed%8c%8c%ec%9d%bc-%ea%b3%bc%ec%a0%95---%eb%a7%81%ed%82%b9-%ea%b3%bc%ec%a0%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;어셈블리에 의해 &lt;strong&gt;ELF 포맷&lt;/strong&gt;의 목적코드 파일들이 만들어지면 이제 링커의 차례이다.&lt;/li&gt;
&lt;li&gt;링커는 &lt;strong&gt;오브젝트 파일들&lt;/strong&gt;과 여러분의 프로그램에서 사용된 **표준 C 라이브러리, 사용자 라이브러리들을 링크(Link)**를 합니다.&lt;/li&gt;
&lt;li&gt;printf() 함수나 scanf() 등의 표준 C 라이브러리 함수들은 여러분이 직접 구현하지 않아도 미리 컴파일이 되어 있기 때문에 링크하는 과정만 거치면 사용할 수 있다. &lt;strong&gt;(표준 C 라이브러리는 별도로 명시하지 않아도 자동으로 링크됩니다.)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;이렇게 링킹 과정이 끝나면 실행 가능한 &lt;strong&gt;실행 파일&lt;/strong&gt;이 만들어진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="byte-code-languages-java-c"&gt;
 &lt;strong&gt;Byte code languages (JAVA, C#&amp;hellip;.)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#byte-code-languages-java-c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;바이트코드는 가상기계어 개념으로 생각하시면됩니다. JAVA도 알다시피 컴파일을 합니다. 하지만 컴파일의 결과물이 실행파일이 아닌 class라는 바이트 코드 파일이죠. 이를 JRE(Java Runtime Environment), CLI(common language infrastructure)라는 인터프리터가 한줄씩 실행하여 동작합니다. CLI는 윈도우의 닷넷 계열 실행환경입니다. 이를 통해 컴파일러 즉 바이트 코드 생성기는 C++ 컴파일러와 같지만 실행하는 JVM, CLI등의 인터프리터를 OS나 플랫폼 별로 만들어 Java라는 언어가 플랫폼 독립적으로 실행되는 것입니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;lsquo;보통 자바는 C++보다 엄청 느리다.&amp;rsquo; 라고하는데 이는 단정짓기 어려운 사실입니다. JRE 즉 바이트코드를 실행하는 JVM 은 바이트코드를 인터프리터 형식으로 실행하는데 이떄 C++ 처럼 기계어로 번역되어 실행합니다 또한 JVM(Java Virtual Machine)은 GC(Garbage Collector)를 튜닝할수 있기 때문에 어떤때는 C++보다 빠를수가 있습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;하지만 분명한 사실은 자바 같은 바이트 코드언어는 직접적인 하드웨어 제어가 불가능합니다. 소스 코드가 직접적으로 하드웨어에 반영되는게 아니기 때문이죠. 그래서 포인터나 Win32 API 같은 수준의 System call을 사용할수 없는 것입니다. 그러한 이유로 보안 관련 프로그램이나 극도의 optimization이 요구되는 프로그램에 C/C++등이 사용되는 것입니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;결론은 &amp;lsquo;자바가 확실한건 C++보다 개발생산성이 뛰어나고 직접전인 하드웨어 제어는 불가능하다,&amp;rsquo; 라는 점입니다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;컴파일&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Compiler에 의해서 java 소스 파일이 class파일로 바꾸어집니다.&lt;/li&gt;
&lt;li&gt;이 과정은 C++ 컴파일 과정과 유사합니다 결과물이 어셈블리나 기계어가 아닌 바이트 코드라는 점이 다른것입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;JRE안에서의 과정&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;먼저 바이트 코드가 유효한지 검사합니다.&lt;/li&gt;
&lt;li&gt;CLASS 파일을 JRE가 메모리에 적재시킵니다.&lt;/li&gt;
&lt;li&gt;Just In-Time Compiler(JIT)&lt;/li&gt;
&lt;li&gt;이 기술은 바이트 코드 형태의 언어 실행 속도를 높이기 위한 기술로써 JRE에 포함된 JVM이 바이트 코드를 실행할 때 플랫폼별로 컴파일을 하는데 이 과정에서 실제 실행 코드가 기계어로 번역되어집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;실행&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;어떤 OS든 JAVA 코드가 같은 결과물을 내놓습니다.&lt;/li&gt;
&lt;li&gt;즉, 자바의 플랫폼 독립은 같은 소스코드와 실행 결과를 말하는 것이며,&lt;/li&gt;
&lt;li&gt;코드를 플랫폼 독립적으로 실행 시키기위해 OS별로 다른 방식의 JVM이나 JRE가 만들어집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="interpreter-languages-javascript-python-ruby"&gt;
 &lt;strong&gt;Interpreter languages (Javascript, Python, Ruby&amp;hellip;)&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#interpreter-languages-javascript-python-ruby" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;인터프리터 언어는 컴파일 언어와 다르게 한줄씩 바로 언어를 번역해서 실행됩니다. C++은 소스 파일이 전체 컴파일되는 반면 인터프리터는 한줄씩 컴파일되어 실행됩니다. 그렇기 때문에 번역하는 과정에서 메모리가 훨씬 적게 소모되기 때문에 효율적입니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;구글 크롬은 크로미늄이라는 오픈소스 프로젝트의 결과물입니다. 이 크로미늄은 오픈소스 이기 때문에 누구나 다운받아 빌드할수있습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;과연 시간이 얼마나 걸릴까요? 검색해본결과 적어도 1시간이상 걸린다고 합니다. 이는 크로미늄은 C/C++로 작성되어 있기 때문인데요. 컴파일 과정에 필요한 메모리와 시간이 인터프리터에 비해 엄청나게 높고 오래걸립니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;만약 파이썬으로 작성되어있다면 2시간은 커녕 길어야 5분일것입니다. 이것이 컴파일과 인터프리터의 차이입니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;인터프리터는 즉시 실행될수있다는 장점때문에 실시간 분석이나 대화형으로 프로그래밍이 가능합니다. 여러분이 아시는 파이썬은 데이터마이닝, 빅데이터, 등의 연구 분야의 주로 사용되는 언어입니다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[C++] Lvalue와 Rvalue</title><link>https://kyungryeol-yoon.github.io/cs/sw-theory/cpp-lvalue-rvalue/</link><pubDate>Sun, 20 Mar 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/cs/sw-theory/cpp-lvalue-rvalue/</guid><description>&lt;h2 id="lvalue-left-value"&gt;
 Lvalue (Left-value)
 &lt;a class="heading-anchor" href="#lvalue-left-value" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Lvalue는 &amp;ldquo;Left-value&amp;quot;의 줄임말로, 메모리 상에 특정 주소를 가지며, 이 값은 변경이 가능하거나 수정 가능한 값이다.&lt;/li&gt;
&lt;li&gt;다시 말해, Lvalue는 대입 연산자(=)의 왼쪽에 위치할 수 있는 표현식이다. Lvalue는 항상 메모리에서 특정 주소를 참조하기 때문에, 해당 값은 변수를 통해 접근할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="특징"&gt;
 특징
 &lt;a class="heading-anchor" href="#%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;메모리 주소를 가지며, 해당 값을 수정할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;변수나 객체와 같은 값들이 대표적인 Lvalue입니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;대입 연산자의 왼쪽에 올 수 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#39;a&amp;#39;는 Lvalue, 대입 연산자의 왼쪽에 있다.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#39;a&amp;#39;는 Lvalue, 값을 변경할 수 있다.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#39;a&amp;#39;는 Lvalue, 대입 연산자의 왼쪽에 위치하고 값이 변경된다.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="lvalue의-종류"&gt;
 Lvalue의 종류
 &lt;a class="heading-anchor" href="#lvalue%ec%9d%98-%ec%a2%85%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;일반 변수&lt;/strong&gt;: int a = 5;에서 a는 Lvalue입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;배열 요소&lt;/strong&gt;: arr[3] 같은 배열 요소도 Lvalue입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;참조&lt;/strong&gt;: int&amp;amp; x = a;에서 x는 Lvalue입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="rvalue-right-value"&gt;
 Rvalue (Right-value)
 &lt;a class="heading-anchor" href="#rvalue-right-value" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Rvalue는 &amp;ldquo;Right-value&amp;quot;의 줄임말로, 값 자체를 나타내며, 메모리 상의 특정 주소를 가지지 않는 값이다.&lt;/li&gt;
&lt;li&gt;대입 연산자의 오른쪽에 위치하는 표현식이 Rvalue에 해당합니다. Rvalue는 일시적인 값으로, 일반적으로 리터럴 값이나 연산 결과로 생성된다.&lt;/li&gt;
&lt;li&gt;Rvalue는 변경할 수 없거나 수정할 수 없는 값이기도 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="특징-1"&gt;
 특징
 &lt;a class="heading-anchor" href="#%ed%8a%b9%ec%a7%95-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;메모리 주소를 가지지 않으며, 보통 값만 존재한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;대입 연산자의 오른쪽에 올 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;값이 임시적이거나 일시적이어서, 해당 값을 수정할 수 없다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#39;a&amp;#39;는 Lvalue
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#39;20&amp;#39;은 Rvalue, 대입 연산자의 오른쪽에 있다.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#39;20&amp;#39;은 Rvalue, 대입 연산자의 오른쪽에 위치하며 변경할 수 없다.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rvalue의-종류"&gt;
 Rvalue의 종류
 &lt;a class="heading-anchor" href="#rvalue%ec%9d%98-%ec%a2%85%eb%a5%98" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;리터럴&lt;/strong&gt;: 10 같은 상수 값은 Rvalue이다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;연산 결과&lt;/strong&gt;: a + b와 같은 표현식은 Rvalue이다. 이 표현식은 값을 계산하지만, 해당 값은 메모리의 특정 위치에 존재하지 않는다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;임시 객체&lt;/strong&gt;: std::vector&lt;int&gt;(5)와 같이 임시로 생성된 객체도 Rvalue이다&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="lvalue와-rvalue-구분"&gt;
 Lvalue와 Rvalue 구분
 &lt;a class="heading-anchor" href="#lvalue%ec%99%80-rvalue-%ea%b5%ac%eb%b6%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#39;a&amp;#39;는 Lvalue
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#39;a + 3&amp;#39;은 Rvalue, 계산된 결과는 임시 객체로 존재
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#39;a + 5&amp;#39;는 Rvalue, &amp;#39;b&amp;#39;는 Lvalue (대입 연산자의 왼쪽)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="lvalue와-rvalue의-관계"&gt;
 Lvalue와 Rvalue의 관계
 &lt;a class="heading-anchor" href="#lvalue%ec%99%80-rvalue%ec%9d%98-%ea%b4%80%ea%b3%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Lvalue를 Rvalue로 사용할 수 있는 경우&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lvalue는 Rvalue로 변환될 수 있다. 예를 들어, a는 Lvalue이지만 a + 1은 Rvalue이다.&lt;/li&gt;
&lt;li&gt;Lvalue는 Rvalue로 &amp;ldquo;읽히기&amp;rdquo; 위해 사용될 수 있다. 예를 들어, int x = a + 1;에서 a + 1은 Rvalue이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Rvalue를 Lvalue로 사용할 수 있는 경우&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rvalue는 직접적으로 Lvalue로 변환될 수 없지만, Rvalue를 참조할 수 있는 임시 객체 참조(rvalue reference)를 이용하여 간접적으로 Lvalue처럼 다룰 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="c11에서-추가된-rvalue-참조와-move-semantics"&gt;
 C++11에서 추가된 Rvalue 참조와 Move Semantics
 &lt;a class="heading-anchor" href="#c11%ec%97%90%ec%84%9c-%ec%b6%94%ea%b0%80%eb%90%9c-rvalue-%ec%b0%b8%ec%a1%b0%ec%99%80-move-semantics" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;C++11부터 도입된 **Rvalue 참조(T&amp;amp;&amp;amp;)**와 Move Semantics은 Rvalue 개념을 보다 발전시킨 것이다.&lt;/li&gt;
&lt;li&gt;Rvalue 참조는 임시 객체나 이동 가능한 객체를 이동할 수 있게 해 주며, 이를 통해 성능을 크게 개선할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// x는 Rvalue 참조로, x를 이동할 수 있다.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;T&amp;amp;&amp;amp;는 일반적으로 Rvalue 참조를 의미하며, 주로 임시 객체를 다룰 때 사용된다.&lt;/li&gt;
&lt;li&gt;Move Semantics은 자원을 복사하는 대신 자원의 소유권을 이동하는 방법을 제공한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="결론"&gt;
 결론
 &lt;a class="heading-anchor" href="#%ea%b2%b0%eb%a1%a0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Lvalue&lt;/strong&gt;: 메모리 주소를 가지며, 수정 가능한 값(변수 등).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rvalue&lt;/strong&gt;: 메모리 주소를 가지지 않으며, 주로 임시적인 값(리터럴, 연산 결과 등)&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>SSD VS HDD</title><link>https://kyungryeol-yoon.github.io/hardware/ssd-hdd-post/</link><pubDate>Wed, 10 Feb 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/hardware/ssd-hdd-post/</guid><description>&lt;h2 id="컴퓨터의-보조-기억-장치란"&gt;
 &lt;strong&gt;컴퓨터의 보조 기억 장치란?&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#%ec%bb%b4%ed%93%a8%ed%84%b0%ec%9d%98-%eb%b3%b4%ec%a1%b0-%ea%b8%b0%ec%96%b5-%ec%9e%a5%ec%b9%98%eb%9e%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;보조 기억 장치는 컴퓨터의 데이터를 전원이 들어오지 않는 상황에서도 저장하기 위해 사용되는 장치이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;주기억장치를 대표하는 D-RAM의 속도는 HDD와는 비교가 되지 않을 정도로 빠르며, 보조 기억 장치 중 최고의 속도를 자랑하는 SSD보다도 빠르다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;하지만, D-RAM은 휘발성 반도체로 주기적으로 리플래시라는 동작을 통해 전류를 공급해 줘야만 데이터를 보존할 수 있다는 단점이 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;물론, 비휘발성 주 기억 장치도 있지만, 경제적인 면에서 매우 불리하다. 때문에 컴퓨터를 종료하게 되어 더 이상 전류가 공급되지 않으면 저장된 데이터가 모두 손실되게 된다. 이러한 이유로, 전원이 없는 상태에서도 데이터를 보존할 수 있는 보조 기억 장치들이 사용되는 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;현재, 보조 기억 장치의 대부분은 HDD가 차지하고 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;하지만, 플래터를 회전시켜 플래터 위에 자기적으로 데이터를 기록하는 기계적인 원리의 HDD는 많은 전력 소모, 발열, 소음 등의 문제가 있고, 무엇보다도 전자적 원리로 작동하는 컴퓨터의 다른 부품들에 비해 데이터 처리 속도가 매우 느려 시스템의 전체적인 성능을 저하시키게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="hdd"&gt;
 &lt;strong&gt;HDD&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#hdd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;HDD의 구동 원리와 그 속도에 대해 이해하기 위해서는 먼저, HDD의 주요 부품에 대해 알아야 한다.&lt;/li&gt;
&lt;li&gt;HDD는 플래터와 헤드, 스핀들, 헤드 구동 장치, 카트리지 등 많은 부품들로 이루어져 있지만, HDD의 데이터 기록 원리와 직접적으로 관련이 있는 장치는 플래터와 헤드이므로, 지금은 플래터와 헤드에 대해서만 다루기로 한다.&lt;/li&gt;
&lt;li&gt;플래터는 데이터가 실제로 기록되는 얇은 판으로, 자성체로 되어 있으며, 다른 원인에 의한 사정의 변화를 막기 위해 산화물 층으로 절연돼 있다.&lt;/li&gt;
&lt;li&gt;HDD의 플래터가 회전하며, 헤드가 플래터에 자기 데이터를 읽고 쓰는 원리로 구동되는데, 플래터가 한 바퀴 돌 때마다 헤드가 일정량의 데이터 처리를 한다.&lt;/li&gt;
&lt;li&gt;그러므로 플래터의 회전 속도에 따라 HDD의 성능이 결정된다고 할 수 있는데, 발열과 소음 문제 때문에 일반적인 HDD의 회전 속도는 7200rpm을 넘지 못한다.&lt;/li&gt;
&lt;li&gt;플래터에서 데이터의 기록 단위를 섹터라고 하고, 한 동심원 위에 있는 섹터들의 집합을 트랙이라고 한다.&lt;/li&gt;
&lt;li&gt;헤드는 플래터에 데이터를 기록하는 장치로, 플래터와 보이지 않을 데이터의 간격을 두고 떨어져 있으며, 플래터의 읽기/쓰기를 원하는 위치로 이동할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ssd"&gt;
 &lt;strong&gt;SSD&lt;/strong&gt;
 &lt;a class="heading-anchor" href="#ssd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SSD의 읽기/쓰기 원리는 HDD의 비하면 훨씬 간단하다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;기계적인 방법은 전혀 없이 전기적으로만 구동된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SSD는 크게 Nand Flash Memory와 컨트롤러로 구성되어 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;여러 개의 Nand Flash Memory가 하나의 SSD를 이루고 있고, 컨트롤러가 이 Nand Flash Memory들을 관리하는 방식으로 작동한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Flash Memory는, Floating Gate에 Control Gate를 이용해 전자를 주입시켜, 전자가 없을 경우에는 0, 전자가 있을 경우에는 1이 되는 원리로 작동한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;즉, Floating Gate 당 1Bit의 데이터를 저장하는 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이 때, Floating Gate는 HDD의 플래터와 마찬가지로 산화물 층으로 절연돼 있기 때문에, 데이터는 반영구적으로 보존된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이처럼, Flash Memory는 단순하게 전자에 의한 전하를 이용해 데이터를 저장하기 때문에, Access Time이 매우 짧다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Flash Memory는 또다시 Nor Flash Memory와 Nand Flash Memory로 나누어진다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Nor은 Not Or의 약자로, 앞에서 살펴보았던 Floating Gate가 병렬로 연결되어 있고, Nand는 Not And의 약자로 Floating Gate가 직렬로 연결되어 있는 구조다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;일반적으로 생각하면, Nor Flash Memory는 어떤 Floating Gate에나 직접 접근할 수 있지만, Nand Flash Memory는 일부 Floating Gate에 접근하기 위해서는 다른 Floating Gate들을 거쳐야 하기 때문에 Nor Flash Memory가 Nand Flash Memory보다 빠르다고 할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이와 같은 이유로 각각의 Floating Gate에서의 읽기 작업은 Nor Flash Memory가 빠르다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;하지만, 쓰기 작업의 특성상, 한 번의 작업에서 한 단위만큼, 즉 Nand Flash Memory에서는 한 직렬 회로에 있는 Floating Gate 만큼의 데이터를 처리하기 때문에, 쓰기 작업에서는 Nand Flash Memory가 빠르다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그리고 쓰기 작업과 같은 이유로, 규모가 큰 데이터를 처리할 때는 읽기/쓰기 속도 모두 Nand Flash Memory가 빠르다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;또한, Nand Flash Memory의 경우, 직렬 회로로 구조가 비교적 단순해 집적도를 높이기 쉽기 때문에, 대용량화와 보급화가 쉽다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;즉, 일상적인 Byte 단위 이상의 작업에서 유리하고, 대용량화와 보급화에 유리한 Nand Flash Memory가 Nor Flash Memory보다 많이 사용되고 있으며, SSD에도 주로 Nand Flash Memory가 사용되고 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Nand Flash Memory는 또 MLC 방식과 SLC 방식으로 나누어진다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MLC는 앞에서 말했던 하나에 Floating Gate에 전자의 양, 즉 전하량의 차이를 두어 0과 1 사이의 단계를 두어, 1Bit 이상의 데이터를 저장할 수 있는 방식이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SLC는 처음 설명했듯이, 하나의 Floating Gate에 1Bit 만에 데이터를 저장하는 방식이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SLC의 경우가 하나의 Floating Gate에서의 데이터 구별이 명확하기 때문에, 속도와 신뢰성이 MLC보다 우수하지만, 대용량화가 힘들기 때문에 가격이 비싸다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;결론적으로 읽기 쓰기의 작동 원리적인 측면으로 봤을 때, HDD는 전기적 신호를 자기로 바꾸어 읽기/쓰기 작업을 하는 중간 과정이 필요하고, 읽기/쓰기 작업을 할 섹터로 헤드가 이동하기까지 걸리는 Access Time이 있으며, 플래터가 한 바퀴 돌 때마다 일정량의 데이터밖에 처리할 수 없으므로, 읽기/쓰기 속도가 비교적 느리다. 하지만, SSD는 Nand Flash Memory에 단순한 전기적 원리로 데이터를 저장하기 때문에 Access Time이 거의 없고, 컨트롤러가 데이터를 다중 채널 분산 기술로 처리해 읽기/쓰기 속도를 극대화시켜주기 때문에 성능이 매우 우수하다.&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Algorithms | C++] Quick sort : 퀵 정렬</title><link>https://kyungryeol-yoon.github.io/cs/algorithms-ds/algorithms-sort-quick/</link><pubDate>Thu, 04 Feb 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/cs/algorithms-ds/algorithms-sort-quick/</guid><description>&lt;h2 id="퀵-정렬quick-sort-알고리즘의-개념-요약"&gt;
 퀵 정렬(Quick sort) 알고리즘의 개념 요약
 &lt;a class="heading-anchor" href="#%ed%80%b5-%ec%a0%95%eb%a0%acquick-sort-%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98%ec%9d%98-%ea%b0%9c%eb%85%90-%ec%9a%94%ec%95%bd" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&amp;lsquo;찰스 앤터니 리처드 호어(Charles Antony Richard Hoare)&amp;lsquo;가 개발한 정렬 알고리즘&lt;/li&gt;
&lt;li&gt;퀵 정렬은 &lt;strong&gt;불안정 정렬&lt;/strong&gt; 에 속하며, 다른 원소와의 비교만으로 정렬을 수행하는 &lt;strong&gt;비교 정렬&lt;/strong&gt; 에 속한다.&lt;/li&gt;
&lt;li&gt;분할 정복 알고리즘의 하나로, 평균적으로 &lt;span style="color:#4d0000"&gt;&lt;strong&gt;매우 빠른 수행 속도를&lt;/strong&gt;&lt;/span&gt; 자랑하는 정렬 방법
&lt;ul&gt;
&lt;li&gt;합병 정렬(merge sort)과 달리 퀵 정렬은 리스트를 &lt;strong&gt;비균등하게&lt;/strong&gt; 분할한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;분할 정복(divide and conquer) 방법
&lt;ul&gt;
&lt;li&gt;문제를 작은 2개의 문제로 분리하고 각각을 해결한 다음, 결과를 모아서 원래의 문제를 해결하는 전략이다.&lt;/li&gt;
&lt;li&gt;분할 정복 방법은 대개 순환 호출을 이용하여 구현한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;과정 설명
&lt;ol&gt;
&lt;li&gt;리스트 안에 있는 한 요소를 선택한다. 이렇게 고른 원소를 &lt;span style="color:#4d0000"&gt;&lt;strong&gt;피벗(pivot)&lt;/strong&gt;&lt;/span&gt; 이라고 한다.&lt;/li&gt;
&lt;li&gt;피벗을 기준으로 피벗보다 작은 요소들은 모두 피벗의 왼쪽으로 옮겨지고 피벗보다 큰 요소들은 모두 피벗의 오른쪽으로 옮겨진다. (피벗을 중심으로 왼쪽: 피벗보다 작은 요소들, 오른쪽: 피벗보다 큰 요소들)&lt;/li&gt;
&lt;li&gt;피벗을 제외한 왼쪽 리스트와 오른쪽 리스트를 다시 정렬한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;분할된 부분 리스트에 대하여 &lt;strong&gt;순환 호출&lt;/strong&gt; 을 이용하여 정렬을 반복한다.&lt;/li&gt;
&lt;li&gt;부분 리스트에서도 다시 피벗을 정하고 피벗을 기준으로 2개의 부분 리스트로 나누는 과정을 반복한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="4"&gt;
&lt;li&gt;부분 리스트들이 더 이상 분할이 불가능할 때까지 반복한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;리스트의 크기가 0이나 1이 될 때까지 반복한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/algorithms/quick-sort/quick-sort-concepts.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="퀵-정렬quick-sort-알고리즘의-구체적인-개념"&gt;
 퀵 정렬(Quick sort) 알고리즘의 구체적인 개념
 &lt;a class="heading-anchor" href="#%ed%80%b5-%ec%a0%95%eb%a0%acquick-sort-%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98%ec%9d%98-%ea%b5%ac%ec%b2%b4%ec%a0%81%ec%9d%b8-%ea%b0%9c%eb%85%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;하나의 리스트를 피벗(pivot)을 기준으로 두 개의 비균등한 크기로 분할하고 분할된 부분 리스트를 정렬한 다음, 두 개의 정렬된 부분 리스트를 합하여 전체가 정렬된 리스트가 되게 하는 방법이다.&lt;/li&gt;
&lt;li&gt;퀵 정렬은 다음의 단계들로 이루어진다.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;분할(Divide):&lt;/strong&gt; 입력 배열을 피벗을 기준으로 비균등하게 2개의 부분 배열(피벗을 중심으로 왼쪽: 피벗보다 작은 요소들, 오른쪽: 피벗보다 큰 요소들)로 분할한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;정복(Conquer):&lt;/strong&gt; 부분 배열을 정렬한다. 부분 배열의 크기가 충분히 작지 않으면 &lt;strong&gt;순환 호출&lt;/strong&gt; 을 이용하여 다시 분할 정복 방법을 적용한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;결합(Combine):&lt;/strong&gt; 정렬된 부분 배열들을 하나의 배열에 합병한다.&lt;/li&gt;
&lt;li&gt;순환 호출이 한번 진행될 때마다 최소한 하나의 원소(피벗)는 최종적으로 위치가 정해지므로, 이 알고리즘은 반드시 끝난다는 것을 보장할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/algorithms/quick-sort/quick-sort.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="퀵-정렬quick-sort-알고리즘의-예제"&gt;
 퀵 정렬(Quick sort) 알고리즘의 예제
 &lt;a class="heading-anchor" href="#%ed%80%b5-%ec%a0%95%eb%a0%acquick-sort-%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98%ec%9d%98-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;배열에 5, 3, 8, 4, 9, 1, 6, 2, 7이 저장되어 있다고 가정하고 자료를 오름차순으로 정렬해 보자.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;퀵 정렬에서 피벗을 기준으로 두 개의 리스트로 나누는 과정(c언어 코드의 partition 함수의 내용)&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/algorithms/quick-sort/quick-sort2.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;피벗 값을 입력 리스트의 첫 번째 데이터로 하자. (다른 임의의 값이어도 상관없다.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2개의 인덱스 변수(low, high)를 이용해서 리스트를 두 개의 부분 리스트로 나눈다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1회전: 피벗이 5인 경우,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;low는 왼쪽에서 오른쪽으로 탐색해가다가 피벗보다 큰 데이터(8)을 찾으면 멈춘다.&lt;/li&gt;
&lt;li&gt;high는 오른쪽에서 왼쪽으로 탐색해가다가 피벗보다 작은 데이터(2)를 찾으면 멈춘다.&lt;/li&gt;
&lt;li&gt;low와 high가 가리키는 두 데이터를 서로 교환한다.&lt;/li&gt;
&lt;li&gt;이 탐색-교환 과정은 low와 high가 엇갈릴 때까지 반복한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2회전: 피벗(1회전의 왼쪽 부분리스트의 첫 번째 데이터)이 1인 경우,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;위와 동일한 방법으로 반복한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3회전: 피벗(1회전의 오른쪽 부분리스트의 첫 번째 데이터)이 9인 경우,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;위와 동일한 방법으로 반복한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="c로-구현한-퀵-정렬-quick-sort"&gt;
 C++로 구현한 퀵 정렬 (Quick sort)
 &lt;a class="heading-anchor" href="#c%eb%a1%9c-%ea%b5%ac%ed%98%84%ed%95%9c-%ed%80%b5-%ec%a0%95%eb%a0%ac-quick-sort" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/data-structures-linked-list-array/"&gt;이전에 작성한 양방향 링크드 리스트의 코드를 재활용&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;DoubleList&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;QuickSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Partition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;QuickSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;QuickSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;DoubleList&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Partition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pivot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ArrangeNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ArrangeNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;pivot&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;Left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ArrangeNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pivot&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;Left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;Swap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ArrangeNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;ArrangeNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Swap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ArrangeNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;ArrangeNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="퀵-정렬quick-sort-알고리즘의-특징"&gt;
 퀵 정렬(quick sort) 알고리즘의 특징
 &lt;a class="heading-anchor" href="#%ed%80%b5-%ec%a0%95%eb%a0%acquick-sort-%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98%ec%9d%98-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;장점
&lt;ol&gt;
&lt;li&gt;속도가 빠르다.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;시간 복잡도가 O(nlog₂n)를 가지는 다른 정렬 알고리즘과 비교했을 때도 가장 빠르다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;추가 메모리 공간을 필요로 하지 않는다.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;퀵 정렬은 O(log n)만큼의 메모리를 필요로 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ol&gt;
&lt;li&gt;정렬된 리스트에 대해서는 퀵 정렬의 불균형 분할에 의해 오히려 수행시간이 더 많이 걸린다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;퀵 정렬의 불균형 분할을 방지하기 위하여 피벗을 선택할 때 더욱 리스트를 균등하게 분할할 수 있는 데이터를 선택한다.
&lt;ul&gt;
&lt;li&gt;EX) 리스트 내의 몇 개의 데이터 중에서 크기순으로 중간 값(medium)을 피벗으로 선택한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="퀵-정렬quick-sort의-시간복잡도"&gt;
 퀵 정렬(quick sort)의 시간복잡도
 &lt;a class="heading-anchor" href="#%ed%80%b5-%ec%a0%95%eb%a0%acquick-sort%ec%9d%98-%ec%8b%9c%ea%b0%84%eb%b3%b5%ec%9e%a1%eb%8f%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;최선의 경우
&lt;ul&gt;
&lt;li&gt;비교 횟수
&lt;ul&gt;
&lt;li&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/algorithms/quick-sort/sort-time-complexity-etc1.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;순환 호출의 깊이&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;레코드의 개수 n이 2의 거듭제곱이라고 가정(n=2^k)했을 때, n=2^3의 경우, 2^3 -&amp;gt; 2^2 -&amp;gt; 2^1 -&amp;gt; 2^0 순으로 줄어들어 순환 호출의 깊이가 3임을 알 수 있다. 이것을 &lt;strong&gt;일반화하면&lt;/strong&gt; n=2^k의 경우, k(k=log₂n)임을 알 수 있다.&lt;/li&gt;
&lt;li&gt;k=log₂n&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;각 순환 호출 단계의 비교 연산&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;각 순환 호출에서는 전체 리스트의 대부분의 레코드를 비교해야 하므로 평균 n번 정도의 비교가 이루어진다.&lt;/li&gt;
&lt;li&gt;평균 n번&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;순환 호출의 깊이 * 각 순환 호출 단계의 비교 연산 = &lt;strong&gt;nlog₂n&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이동 횟수
&lt;ul&gt;
&lt;li&gt;비교 횟수보다 적으므로 무시할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;최선의 경우 T(n) = &lt;strong&gt;O(nlog₂n)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;최악의 경우
&lt;ul&gt;
&lt;li&gt;리스트가 계속 불균형하게 나누어지는 경우 (특히, 이미 정렬된 리스트에 대하여 퀵 정렬을 실행하는 경우)&lt;/li&gt;
&lt;li&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/algorithms/quick-sort/sort-time-complexity-etc2.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/li&gt;
&lt;li&gt;비교 횟수
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;순환 호출의 깊이&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;레코드의 개수 n이 2의 거듭제곱이라고 가정(n=2^k)했을 때, 순환 호출의 깊이는 n임을 알 수 있다.&lt;/li&gt;
&lt;li&gt;n&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;각 순환 호출 단계의 비교 연산&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;각 순환 호출에서는 전체 리스트의 대부분의 레코드를 비교해야 하므로 평균 n번 정도의 비교가 이루어진다.&lt;/li&gt;
&lt;li&gt;평균 n번&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;순환 호출의 깊이 * 각 순환 호출 단계의 비교 연산 = &lt;strong&gt;n^2&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이동 횟수
&lt;ul&gt;
&lt;li&gt;비교 횟수보다 적으므로 무시할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;최악의 경우 T(n) = &lt;strong&gt;O(n^2)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;평균
&lt;ul&gt;
&lt;li&gt;평균 T(n) = &lt;strong&gt;O(nlog₂n)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;시간 복잡도가 O(nlog₂n)를 가지는 다른 정렬 알고리즘과 비교했을 때도 가장 빠르다.&lt;/li&gt;
&lt;li&gt;퀵 정렬이 불필요한 데이터의 이동을 줄이고 먼 거리의 데이터를 교환할 뿐만 아니라, 한 번 결정된 피벗	들이 추후 연산에서 제외되는 특성 때문이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="정렬-알고리즘-시간복잡도-비교"&gt;
 정렬 알고리즘 시간복잡도 비교
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a0%ac-%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98-%ec%8b%9c%ea%b0%84%eb%b3%b5%ec%9e%a1%eb%8f%84-%eb%b9%84%ea%b5%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/algorithms/quick-sort/sort-time-complexity.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;단순(구현 간단)하지만 비효율적인 방법
&lt;ul&gt;
&lt;li&gt;삽입 정렬, 선택 정렬, 버블 정렬&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;복잡하지만 효율적인 방법
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;퀵 정렬&lt;/strong&gt;, 힙 정렬, 합병 정렬, 기수 정렬&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;퀵 정렬 - 위키백과 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ko.wikipedia.org/wiki/%ED%80%B5_%EC%A0%95%EB%A0%AC"&gt;https://ko.wikipedia.org/wiki/%ED%80%B5_%EC%A0%95%EB%A0%AC&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Algorithms | C++] Insertion sort : 삽입 정렬</title><link>https://kyungryeol-yoon.github.io/cs/algorithms-ds/algorithms-sort-insertion/</link><pubDate>Wed, 03 Feb 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/cs/algorithms-ds/algorithms-sort-insertion/</guid><description>&lt;h2 id="삽입-정렬insertion-sort-알고리즘-개념"&gt;
 삽입 정렬(Insertion sort) 알고리즘 개념
 &lt;a class="heading-anchor" href="#%ec%82%bd%ec%9e%85-%ec%a0%95%eb%a0%acinsertion-sort-%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98-%ea%b0%9c%eb%85%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;손안의 카드를 정렬하는 방법과 유사하다.
&lt;ul&gt;
&lt;li&gt;새로운 카드를 기존의 정렬된 카드 사이의 올바른 자리를 찾아 삽입한다.&lt;/li&gt;
&lt;li&gt;새로 삽입될 카드의 수만큼 반복하게 되면 전체 카드가 정렬된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;자료 배열의 모든 요소를 &lt;strong&gt;앞에서부터 차례대로 이미 정렬된 배열 부분과 비교&lt;/strong&gt; 하여, 자신의 위치를 찾아 삽입함으로써 정렬을 완성하는 알고리즘&lt;/li&gt;
&lt;li&gt;매 순서마다 해당 원소를 삽입할 수 있는 위치를 찾아 해당 위치에 넣는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="삽입-정렬insertion-sort-알고리즘의-예제"&gt;
 삽입 정렬(Insertion sort) 알고리즘의 예제
 &lt;a class="heading-anchor" href="#%ec%82%bd%ec%9e%85-%ec%a0%95%eb%a0%acinsertion-sort-%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98%ec%9d%98-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;배열에 8, 5, 6, 2, 4가 저장되어 있다고 가정하고 자료를 오름차순으로 정렬해 보자.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/algorithms/insertion-sort/insertion-sort.png" alt="" loading="lazy" decoding="async"&gt;
{: width=&amp;ldquo;900&amp;rdquo; height=&amp;ldquo;950&amp;rdquo;}&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1회전: 두 번째 자료인 5를 Key로 해서 그 이전의 자료들과 비교한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Key 값 5와 첫 번째 자료인 8을 비교한다. 8이 5보다 크므로 8을 5자리에 넣고 Key 값 5를 8의 자리인 첫 번째에 기억시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2회전: 세 번째 자료인 6을 Key 값으로 해서 그 이전의 자료들과 비교한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Key 값 6과 두 번째 자료인 8을 비교한다. 8이 Key 값보다 크므로 8을 6이 있던 세 번째 자리에 기억시킨다.&lt;/li&gt;
&lt;li&gt;Key 값 6과 첫 번째 자료인 5를 비교한다. 5가 Key 값보다 작으므로 Key 값 6을 두 번째 자리에 기억시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3회전: 네 번째 자료인 2를 Key 값으로 해서 그 이전의 자료들과 비교한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Key 값 2와 세 번째 자료인 8을 비교한다. 8이 Key 값보다 크므로 8을 2가 있던 네 번째 자리에 기억시킨다.&lt;/li&gt;
&lt;li&gt;Key 값 2와 두 번째 자료인 6을 비교한다. 6이 Key 값보다 크므로 6을 세 번째 자리에 기억시킨다.&lt;/li&gt;
&lt;li&gt;Key 값 2와 첫 번째 자료인 5를 비교한다. 5가 Key 값보다 크므로 5를 두 번째 자리에 넣고 그 자리에 Key 값 2를 기억시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;4회전: 다섯 번째 자료인 4를 Key 값으로 해서 그 이전의 자료들과 비교한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Key 값 4와 네 번째 자료인 8을 비교한다. 8이 Key 값보다 크므로 8을 다섯 번째 자리에 기억시킨다.&lt;/li&gt;
&lt;li&gt;Key 값 4와 세 번째 자료인 6을 비교한다. 6이 Key 값보다 크므로 6을 네 번째 자리에 기억시킨다.&lt;/li&gt;
&lt;li&gt;Key 값 4와 두 번째 자료인 5를 비교한다. 5가 Key 값보다 크므로 5를 세 번째 자리에 기억시킨다.&lt;/li&gt;
&lt;li&gt;Key 값 4와 첫 번째 자료인 2를 비교한다. 2가 Key 값보다 작으므로 4를 두 번째 자리에 기억시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="c로-구현한-삽입-정렬-insertion-sort"&gt;
 C++로 구현한 삽입 정렬 (Insertion sort)
 &lt;a class="heading-anchor" href="#c%eb%a1%9c-%ea%b5%ac%ed%98%84%ed%95%9c-%ec%82%bd%ec%9e%85-%ec%a0%95%eb%a0%ac-insertion-sort" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/data-structures-linked-list-array/"&gt;이전에 작성한 양방향 링크드 리스트의 코드를 재활용&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;DoubleList&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;InsertSort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;CountNode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;Current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ArrangeNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getLlink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getLlink&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="n"&gt;Head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Tail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;						&lt;span class="n"&gt;Tail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;Tail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;						&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Tail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="n"&gt;Tail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getLlink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getLlink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getLlink&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;Current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;Current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getLlink&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="삽입-정렬insertion-sort-알고리즘의-특징"&gt;
 삽입 정렬(Insertion sort) 알고리즘의 특징
 &lt;a class="heading-anchor" href="#%ec%82%bd%ec%9e%85-%ec%a0%95%eb%a0%acinsertion-sort-%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98%ec%9d%98-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;안정한 정렬 방법&lt;/li&gt;
&lt;li&gt;레코드의 수가 적을 경우 알고리즘 자체가 매우 간단하므로 다른 복잡한 정렬 방법보다 유리할 수 있다.&lt;/li&gt;
&lt;li&gt;대부분위 레코드가 이미 정렬되어 있는 경우에 매우 효율적일 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;비교적 많은 레코드들의 이동을 포함한다.&lt;/li&gt;
&lt;li&gt;레코드 수가 많고 레코드 크기가 클 경우에 적합하지 않다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="삽입-정렬insertion-sort의-시간복잡도"&gt;
 삽입 정렬(Insertion sort)의 시간복잡도
 &lt;a class="heading-anchor" href="#%ec%82%bd%ec%9e%85-%ec%a0%95%eb%a0%acinsertion-sort%ec%9d%98-%ec%8b%9c%ea%b0%84%eb%b3%b5%ec%9e%a1%eb%8f%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;시간복잡도를 계산한다면&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;최선의 경우&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;비교 횟수
&lt;ul&gt;
&lt;li&gt;이동 없이 1번의 비교만 이루어진다.&lt;/li&gt;
&lt;li&gt;외부 루프: (n-1)번&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Best T(n) = &lt;strong&gt;O(n)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;최악의 경우(입력 자료가 역순일 경우)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;비교 횟수
&lt;ul&gt;
&lt;li&gt;외부 루프 안의 각 반복마다 i번의 비교 수행&lt;/li&gt;
&lt;li&gt;외부 루프: (n-1) + (n-2) + … + 2 + 1 = n(n-1)/2 = O(n^2)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;교환 횟수
&lt;ul&gt;
&lt;li&gt;외부 루프의 각 단계마다 (i+2)번의 이동 발생&lt;/li&gt;
&lt;li&gt;n(n-1)/2 + 2(n-1) = (n^2+3n-4)/2 = &lt;strong&gt;O(n^2)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Worst T(n) = &lt;strong&gt;O(n^2)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="정렬-알고리즘-시간복잡도-비교"&gt;
 정렬 알고리즘 시간복잡도 비교
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a0%ac-%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98-%ec%8b%9c%ea%b0%84%eb%b3%b5%ec%9e%a1%eb%8f%84-%eb%b9%84%ea%b5%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/algorithms/insertion-sort/sort-time-complexity.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;단순(구현 간단)하지만 비효율적인 방법
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;삽입 정렬&lt;/strong&gt;, 선택 정렬, 버블 정렬&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;복잡하지만 효율적인 방법
&lt;ul&gt;
&lt;li&gt;퀵 정렬, 힙 정렬, 합병 정렬, 기수 정렬&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;삽입 정렬 - 위키백과 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ko.wikipedia.org/wiki/%EC%82%BD%EC%9E%85_%EC%A0%95%EB%A0%AC"&gt;https://ko.wikipedia.org/wiki/%EC%82%BD%EC%9E%85_%EC%A0%95%EB%A0%AC&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Algorithms | C++] Bubble sort : 버블 정렬</title><link>https://kyungryeol-yoon.github.io/cs/algorithms-ds/algorithms-sort-bubble/</link><pubDate>Tue, 02 Feb 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/cs/algorithms-ds/algorithms-sort-bubble/</guid><description>&lt;h2 id="버블-정렬bubble-sort-알고리즘의-개념"&gt;
 버블 정렬(Bubble sort) 알고리즘의 개념
 &lt;a class="heading-anchor" href="#%eb%b2%84%eb%b8%94-%ec%a0%95%eb%a0%acbubble-sort-%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98%ec%9d%98-%ea%b0%9c%eb%85%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;서로 &lt;strong&gt;인접한&lt;/strong&gt; 두 원소를 검사하여 정렬하는 알고리즘
&lt;ul&gt;
&lt;li&gt;인접한 2개의 레코드를 비교하여 크기가 순서대로 되어 있지 않으면 서로 교환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;선택 정렬과 기본 개념이 유사하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="버블-정렬bubble-sort-알고리즘의-예제"&gt;
 버블 정렬(Bubble sort) 알고리즘의 예제
 &lt;a class="heading-anchor" href="#%eb%b2%84%eb%b8%94-%ec%a0%95%eb%a0%acbubble-sort-%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98%ec%9d%98-%ec%98%88%ec%a0%9c" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;배열에 7, 4, 5, 1, 3이 저장되어 있다고 가정하고 자료를 오름차순으로 정렬해 보자.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/algorithms/bubble-sort/bubble-sort.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1회전&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;첫 번째 자료 7을 두 번째 자료 4와 비교하여 교환하고, 두 번째의 7과 세 번째의 5를 비교하여 교환하고, 세 번째의 7과 네 번째의 1을 비교하여 교환하고, 네 번째의 7과 다섯 번째의 3을 비교하여 교환한다. 이 과정에서 자료를 네 번 비교한다. 그리고 가장 큰 자료가 맨 끝으로 이동하므로 다음 회전에서는 맨 끝에 있는 자료는 비교할 필요가 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2회전&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;첫 번째의 4을 두 번째 5와 비교하여 교환하지 않고, 두 번째의 5와 세 번째의 1을 비교하여 교환하고, 세 번째의 5와 네 번째의 3을 비교하여 교환한다. 이 과정에서 자료를 세 번 비교한다. 비교한 자료 중 가장 큰 자료가 끝에서 두 번째에 놓인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3회전&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;첫 번째의 4를 두 번째 1과 비교하여 교환하고, 두 번째의 4와 세 번째의 3을 비교하여 교환한다. 이 과정에서 자료를 두 번 비교한다. 비교한 자료 중 가장 큰 자료가 끝에서 세 번째에 놓인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;4회전&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;첫 번째의 1과 두 번째의 3을 비교하여 교환하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="c로-구현한-버블-정렬-bubble-sort"&gt;
 C++로 구현한 버블 정렬 (Bubble sort)
 &lt;a class="heading-anchor" href="#c%eb%a1%9c-%ea%b5%ac%ed%98%84%ed%95%9c-%eb%b2%84%eb%b8%94-%ec%a0%95%eb%a0%ac-bubble-sort" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/data-structures-linked-list-array/"&gt;이전에 작성한 양방향 링크드 리스트의 코드를 재활용&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;DoubleList&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BubbleSort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;CountNode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;Current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;CountNode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="n"&gt;Head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Tail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;						&lt;span class="n"&gt;Tail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;Tail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;						&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Tail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="n"&gt;Tail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getLlink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;					&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getLlink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getLlink&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;Current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;Current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="버블-정렬bubble-sort-알고리즘의-특징"&gt;
 버블 정렬(Bubble sort) 알고리즘의 특징
 &lt;a class="heading-anchor" href="#%eb%b2%84%eb%b8%94-%ec%a0%95%eb%a0%acbubble-sort-%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98%ec%9d%98-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;구현이 매우 간단하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;순서에 맞지 않은 요소를 인접한 요소와 교환한다.&lt;/li&gt;
&lt;li&gt;하나의 요소가 가장 왼쪽에서 가장 오른쪽으로 이동하기 위해서는 배열에서 모든 다른 요소들과 교환되어야 한다.&lt;/li&gt;
&lt;li&gt;특히 특정 요소가 최종 정렬 위치에 이미 있는 경우라도 교환되는 일이 일어난다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;일반적으로 자료의 교환 작업(SWAP)이 자료의 이동 작업(MOVE)보다 더 복잡하기 때문에 버블 정렬은 단순성에도 불구하고 &lt;strong&gt;거의 쓰이지 않는다.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="버블-정렬bubble-sort의-시간복잡도"&gt;
 버블 정렬(Bubble sort)의 시간복잡도
 &lt;a class="heading-anchor" href="#%eb%b2%84%eb%b8%94-%ec%a0%95%eb%a0%acbubble-sort%ec%9d%98-%ec%8b%9c%ea%b0%84%eb%b3%b5%ec%9e%a1%eb%8f%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;시간복잡도를 계산한다면&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;비교 횟수&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;최상, 평균, 최악 모두 일정&lt;/li&gt;
&lt;li&gt;n-1, n-2, … , 2, 1 번 = n(n-1)/2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;교환 횟수&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;입력 자료가 역순으로 정렬되어 있는 최악의 경우, 한 번 교환하기 위하여 3번의 이동(SWAP 함수의 작업)이 필요하므로 (비교 횟수 - 3) 번 = 3n(n-1)/2&lt;/li&gt;
&lt;li&gt;입력 자료가 이미 정렬되어 있는 최상의 경우, 자료의 이동이 발생하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;T(n) = &lt;strong&gt;O(n^2)&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="정렬-알고리즘-시간복잡도-비교"&gt;
 정렬 알고리즘 시간복잡도 비교
 &lt;a class="heading-anchor" href="#%ec%a0%95%eb%a0%ac-%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98-%ec%8b%9c%ea%b0%84%eb%b3%b5%ec%9e%a1%eb%8f%84-%eb%b9%84%ea%b5%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/algorithms/bubble-sort/sort-time-complexity.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;단순(구현 간단)하지만 비효율적인 방법
&lt;ul&gt;
&lt;li&gt;삽입 정렬, 선택 정렬, &lt;strong&gt;버블 정렬&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;복잡하지만 효율적인 방법
&lt;ul&gt;
&lt;li&gt;퀵 정렬, 힙 정렬, 합병 정렬, 기 수 정렬&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;버블 정렬 - 위키백과 참고&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ko.wikipedia.org/wiki/%EA%B1%B0%ED%92%88_%EC%A0%95%EB%A0%AC"&gt;https://ko.wikipedia.org/wiki/%EA%B1%B0%ED%92%88_%EC%A0%95%EB%A0%AC&lt;/a&gt;
{: .prompt-info }&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Data Structures | C++] Stack : 스택</title><link>https://kyungryeol-yoon.github.io/cs/algorithms-ds/data-structures-stack/</link><pubDate>Fri, 29 Jan 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/cs/algorithms-ds/data-structures-stack/</guid><description>&lt;h2 id="스택stack"&gt;
 스택(Stack)
 &lt;a class="heading-anchor" href="#%ec%8a%a4%ed%83%9dstack" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;스택은 마지막에 저장한 데이터를 가장 먼저 꺼내는 후입선출(LIFO:Last In First Out) 구조로 되어 있다.&lt;/li&gt;
&lt;li&gt;입출력이 모두 한 방향에서 이루어지는 데이터 구조이다.&lt;/li&gt;
&lt;li&gt;입출력이 가능한 쪽을 TOP, 바닥을 BOTTOM이라고 한다.&lt;/li&gt;
&lt;li&gt;TOP은 출력 우선순위가 가장 높은 요소를 가리키고 있다.&lt;/li&gt;
&lt;li&gt;입출력을 할 위치를 표시하기 위해서 TOP(포인터 사용)이 필요하다.&lt;/li&gt;
&lt;li&gt;TOP을 통해서 데이터를 넣는 것을 PUSH라고 하고, 꺼내는 것을 POP이라고 한다.&lt;/li&gt;
&lt;li&gt;스택을 구현하는 방법은 배열과 연결 리스트가 있다.&lt;/li&gt;
&lt;li&gt;배열의 큰 단점은 처음 생성한 크기를 바꿀 수 없다는 점이다. 그래서 순차적으로 데이터를 추가하고 삭제하는 스택은 배열리스트(Array List)와 같은 배열기반의 컬렉션 클래스가 적합하다.&lt;/li&gt;
&lt;li&gt;overflow : 스택의 모든 기억장소가 꽉 채워져 있어서 더 이상 데이터를 삽입(PUSH할 때)할 수 없다.&lt;/li&gt;
&lt;li&gt;underflow : 자료가 없다면(TOP포인터가 주소 0을 가지고 있다면) 스택에는 삭제(POP할 때)할 자료가 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="스택stack의-연산"&gt;
 스택(Stack)의 연산
 &lt;a class="heading-anchor" href="#%ec%8a%a4%ed%83%9dstack%ec%9d%98-%ec%97%b0%ec%82%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;스택(Stack)는 &lt;strong&gt;LIFO(Last In First Out)&lt;/strong&gt; 를 따른다. 즉, 가장 최근에 스택에 추가한 항목이 가장 먼저 제거될 항목이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pop() : 스택에서 가장 위에 있는 항목을 제거한다.&lt;/li&gt;
&lt;li&gt;push(item) : item 하나를 스택의 가장 윗 부분에 추가한다.&lt;/li&gt;
&lt;li&gt;peek() : 스택의 가장 위에 있는 항목을 반환한다.&lt;/li&gt;
&lt;li&gt;isEmpty() : 스택이 비어 있을 때에 true를 반환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="스택의-단점"&gt;
 스택의 단점
 &lt;a class="heading-anchor" href="#%ec%8a%a4%ed%83%9d%ec%9d%98-%eb%8b%a8%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;먼저 들어온 것이 나중에 출력되는 후입선출의 구조로 우선순위에 관련된 문제가 생길 수 있다.&lt;/li&gt;
&lt;li&gt;새로운 입력이 들어오면 바닥에 있는 데이터가 오랫동안 잔류하게 되는 경우가 생긴다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="스택의-용도"&gt;
 스택의 용도
 &lt;a class="heading-anchor" href="#%ec%8a%a4%ed%83%9d%ec%9d%98-%ec%9a%a9%eb%8f%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;재귀 알고리즘을 사용하는 경우 스택이 유용하다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;재귀 알고리즘
&lt;ul&gt;
&lt;li&gt;재귀적으로 함수를 호출해야 하는 경우에 임시 데이터를 스택에 넣어준다.&lt;/li&gt;
&lt;li&gt;재귀함수를 빠져 나와 퇴각 검색(backtrack)을 할 때는 스택에 넣어 두었던 임시 데이터를 빼 줘야 한다.&lt;/li&gt;
&lt;li&gt;스택은 이런 일련의 행위를 직관적으로 가능하게 해 준다.&lt;/li&gt;
&lt;li&gt;또한 스택은 재귀 알고리즘을 반복적 형태(iterative)를 통해서 구현할 수 있게 해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;웹 브라우저 방문기록 (뒤로가기)&lt;/li&gt;
&lt;li&gt;실행 취소 (undo)&lt;/li&gt;
&lt;li&gt;역순 문자열 만들기&lt;/li&gt;
&lt;li&gt;수식의 괄호 검사 (연산자 우선순위 표현을 위한 괄호 검사)
&lt;ul&gt;
&lt;li&gt;Ex) 올바른 괄호 문자열(VPS, Valid Parenthesis String) 판단하기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;후위 표기법 계산&lt;/li&gt;
&lt;li&gt;지역변수 저장&lt;/li&gt;
&lt;li&gt;함수의 콜스택&lt;/li&gt;
&lt;li&gt;문자열을 역순으로 출력할 때, 연산자 후위표기법 등&lt;/li&gt;
&lt;li&gt;임시데이터 백업&lt;/li&gt;
&lt;li&gt;함수 호출의 순서 제어&lt;/li&gt;
&lt;li&gt;인터럽트 처리&lt;/li&gt;
&lt;li&gt;수식계산&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="c로-구현한-스택-stack"&gt;
 C++로 구현한 스택 (Stack)
 &lt;a class="heading-anchor" href="#c%eb%a1%9c-%ea%b5%ac%ed%98%84%ed%95%9c-%ec%8a%a4%ed%83%9d-stack" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/data-structures-linked-list-array/"&gt;이전에 작성한 양방향 링크드 리스트의 코드를 재활용&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;DoubleList&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;DoubleList&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;getdouble&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;display&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;Stack.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;doublelist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DoubleList&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="o"&gt;::~&lt;/span&gt;&lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;insertNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;delNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;displayNode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//Manager.cpp
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;StackRun&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;menu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;1.삽입&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;2.반환&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;3.출력&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;입력 : &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;cin&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;INSERT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;추가 할 데이터 : &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;cin&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;57&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;DEL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;58&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;59&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;60&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;61&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;COUT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;62&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getdouble&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getHead&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;63&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;데이터가 없습니다.&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;64&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;65&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;66&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;67&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;68&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;69&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;70&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;71&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;72&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>FSM이란?</title><link>https://kyungryeol-yoon.github.io/cs/sw-theory/game-fsm/</link><pubDate>Mon, 25 Jan 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/cs/sw-theory/game-fsm/</guid><description>&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;유한상태기계(finite state machine, FSM)는 게임 에이전트에게 환상적인 지능을 부여하기 위한 선택 도구로 사용되어왔다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;다시 말해, 유한상태기계는, 주어지는 모든 시간에서 처해 있을 수 있는 유한 개의 상태를 가지고 주어지는 입력에 따라 어떤 상태에서 다른 상태로 전환시키거나 출력이나 액션이 일어나게 하는 장치 또는 그런 장치를 나타낸 모델이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;FSM 이란 특정한 상태를 정의하기 위한 개념적 모델인 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;여러개의 제한된 상태(State)가 존재하고 그 존재들이 특정 조건에 물려 서로 연결되어있는 형태를 의미한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;유한 상태 기계의 간단한 예로는 집에 있는 전등 스위치를 들 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;스위치가 On일 때는 전등의 불이 들어오게 되고 그 상태가 유지된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;만약 누군가가 와서 스위치를 Off하게 되면 전등의 불은 꺼지게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이때도 마찬가지로 누군가가 스위치를 On하기 전까지는 불이 꺼진 상태를 유지 할 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이처럼 유한상태기계도 어떤 상태를 유지 하고 있다가 특정한 이벤트가 발생하게 되면 조건에 맞는 상태로 생태가 변하게 되는 방식이다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="게임에서의-fsm"&gt;
 게임에서의 FSM
 &lt;a class="heading-anchor" href="#%ea%b2%8c%ec%9e%84%ec%97%90%ec%84%9c%ec%9d%98-fsm" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;아래의 그림은 게임에서 NPC나 Monster 등에 적용되는 간단한 AI 상태이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/fsm/FSM-1.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/fsm/FSM-2.png" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;위의 그림같이 특정한 조건에 따라 그 조건으로 상태가 전환이 되면서 해당되는 상태를 처리하는 것을 FSM이라고 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="fsm을-왜-사용하는가"&gt;
 FSM을 왜 사용하는가?
 &lt;a class="heading-anchor" href="#fsm%ec%9d%84-%ec%99%9c-%ec%82%ac%ec%9a%a9%ed%95%98%eb%8a%94%ea%b0%80" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;FSM을 사용하는 이유는 간단하다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;쉬운 개념의 적립, 각 상태와 형태가 코드상이 아닌 도표로써 나타내짐으로써 AI의 개념을 프로그래머 이외에 기획자 또는 제 3자가 쉽게 확인, 설계가 가능하기 때문이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그리고 정해진 룰이 있기 때문에 프로그래머 입장에서 코딩시 조금 더 안정성이 높은 코드를 만들어낼수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그리고 각각의 상태는 나위어져 있기 때문에 새로운 상태의 추가 삭제가 용의하다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;FSM이 모든 AI를 대변하는 것은 아니다. Fuzzy, 하드코딩 AI 등 게임에서는 여러 가지 형태가 병합되어있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;위의 그림을 참고삼아 예를 들어보도록 하겠다. 아래의 몬스터 예상 공격패턴이 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;현재 한 마리의 Moster가 존재한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Moster의 공격대상은 당연히 Player이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Moster는 공격대상이 없을 때는 주위를 방황하며 걸어다니거나(Move) 제자리에서 혼자 무언가를 하고 있다.(Idle) 공격대상이 생겼을 경우 Moster는 해당 대상을 공격(Attack) 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;위의 패턴을 잘 보면 위의 그림으로 나타낸 도표로 다 표현할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그리고 FSM으로 구현되어져 있기 때문에 각각의 상태는 여러가지 형태로 변경될 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;예를 들자면 Attack 상태를 여러가지로 나위어 놓을 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;언제나 Critical한 공격만 하는 상태&lt;/li&gt;
&lt;li&gt;아주 약한 공격을 여러 번 하는 공격 상태&lt;/li&gt;
&lt;li&gt;장거리 공격을 하는 공격 상태&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;위와 같이 여러 가지 공격 상태를 정해두고 상태를 변환하는 것만으로도 다양한 형태의 AI를 가진 Moster가 구현될 수 있는 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="fsm-장점"&gt;
 FSM 장점
 &lt;a class="heading-anchor" href="#fsm-%ec%9e%a5%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;빠르고 코딩하기가 쉽다.&lt;/li&gt;
&lt;li&gt;오류수정이 용이하다.&lt;/li&gt;
&lt;li&gt;계산 부담이 없다.&lt;/li&gt;
&lt;li&gt;직관적이다.&lt;/li&gt;
&lt;li&gt;유연성이 있다.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Data Structures | C++] Queue &amp; Deque : 큐 &amp; 데큐</title><link>https://kyungryeol-yoon.github.io/cs/algorithms-ds/data-structures-queue-deque/</link><pubDate>Sun, 24 Jan 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/cs/algorithms-ds/data-structures-queue-deque/</guid><description>&lt;h2 id="큐queue"&gt;
 큐(Queue)
 &lt;a class="heading-anchor" href="#%ed%81%90queue" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;큐는 처음에 저장한 데이터를 가장 먼저 꺼내는 선입선출(FIFO:First In First Out) 구조로 되어 있다.&lt;/li&gt;
&lt;li&gt;입출력이 양방향에서 이루어지는 데이터 구조이다.&lt;/li&gt;
&lt;li&gt;FRONT)는 가장 먼저 삽입된 자료의 기억공간을 가리키는 포인터이고 , REAR는 가장 마지막에 삽입된 자료가 위치한 기억장소를 가리키는 포인터이다.&lt;/li&gt;
&lt;li&gt;데이터 입력은 FRONT 포인터를 통해서 하고, 데이터 삭제는 REAR 포인터를 통해서 한다.&lt;/li&gt;
&lt;li&gt;삽입연산을 Enqueue 또는 Put, 삭제연산을 Dequeue 또는 Get라고 한다.&lt;/li&gt;
&lt;li&gt;큐에서는 FRONT와 REAR가 같을 때 비어있는 공백큐 임을 알수 있다.&lt;/li&gt;
&lt;li&gt;overflow : 큐의 모든 기억장소가 꽉 채워져 있어서 더 이상 데이터를 삽입(Enqueue할 때)할 수 없다.&lt;/li&gt;
&lt;li&gt;underflow : 자료가 없다면 스택에는 삭제(Dequeue할 때)할 자료가 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="큐queue의-연산"&gt;
 큐(Queue)의 연산
 &lt;a class="heading-anchor" href="#%ed%81%90queue%ec%9d%98-%ec%97%b0%ec%82%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;큐(Queue)는 &lt;strong&gt;FIFO(First-In-First-Out)&lt;/strong&gt; 를 따른다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;add(item) : item을 리스트의 끝부분에 추가한다.&lt;/li&gt;
&lt;li&gt;remove() : 리스트의 첫 번째 항목을 제거한다.&lt;/li&gt;
&lt;li&gt;peek() : 큐에서 가장 위에 있는 항목을 반환한다.&lt;/li&gt;
&lt;li&gt;isEmpty() : 큐가 비어 있을 때에 true를 반환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;큐(Queue)에서 처음과 마지막 노드를 갱신할 때 실수가 나오기 쉽다.
{: .prompt-warning }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="큐의-단점"&gt;
 큐의 단점
 &lt;a class="heading-anchor" href="#%ed%81%90%ec%9d%98-%eb%8b%a8%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;데이터 삽입 후 계속 항목을 삭제하면 REAR와 FRONT가 만나게 되어 공백큐가 됨에도 불구하고 오버 플로우 현상이 발생한다. 즉, 메모리 낭비가 생기게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="개선된-원형-큐가-나옴"&gt;
 개선된 원형 큐가 나옴.
 &lt;a class="heading-anchor" href="#%ea%b0%9c%ec%84%a0%eb%90%9c-%ec%9b%90%ed%98%95-%ed%81%90%ea%b0%80-%eb%82%98%ec%98%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;원형 큐의 단점 : 메모리 공간은 잘 활용하나 배열로 구현되어 있기 때문에 큐의 크기가 제한되는 단점이 존재한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="링크드-리스트로-큐가-나옴"&gt;
 링크드 리스트로 큐가 나옴.
 &lt;a class="heading-anchor" href="#%eb%a7%81%ed%81%ac%eb%93%9c-%eb%a6%ac%ec%8a%a4%ed%8a%b8%eb%a1%9c-%ed%81%90%ea%b0%80-%eb%82%98%ec%98%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;링크드 리스트로 구현한 큐는 큐의 크기가 제한이 없고, 삽입, 삭제가 효과적이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="큐의-용도"&gt;
 큐의 용도
 &lt;a class="heading-anchor" href="#%ed%81%90%ec%9d%98-%ec%9a%a9%eb%8f%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;데이터가 입력된 시간 순서대로 처리해야 할 필요가 있는 상황에 이용한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;너비 우선 탐색(BFS, Breadth-First Search) 구현
&lt;ul&gt;
&lt;li&gt;처리해야 할 노드의 리스트를 저장하는 용도로 큐(Queue)를 사용한다.&lt;/li&gt;
&lt;li&gt;노드를 하나 처리할 때마다 해당 노드와 인접한 노드들을 큐에 다시 저장한다.&lt;/li&gt;
&lt;li&gt;노드를 접근한 순서대로 처리할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;캐시(Cache) 구현&lt;/li&gt;
&lt;li&gt;우선순위가 같은 작업 예약 (인쇄 대기열)&lt;/li&gt;
&lt;li&gt;선입선출이 필요한 대기열 (티켓 카운터)&lt;/li&gt;
&lt;li&gt;콜센터 고객 대기시간&lt;/li&gt;
&lt;li&gt;프린터의 출력 처리&lt;/li&gt;
&lt;li&gt;윈도 시스템의 메시지 처리기&lt;/li&gt;
&lt;li&gt;프로세스 관리&lt;/li&gt;
&lt;li&gt;운영체제 작업 스케쥴링&lt;/li&gt;
&lt;li&gt;컴퓨터 버퍼에서 주로 사용, 마구 입력이 되었으나 처리를 하지 못할 때, 버퍼(큐)를 만들어 대기 시킨다.&lt;/li&gt;
&lt;li&gt;대기행렬 처리&lt;/li&gt;
&lt;li&gt;인쇄작업 대기목록&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;큐는 데이터를 꺼낼 때 항상 첫 번째 저장된 데이터를 삭제하므로 배열리스트와 같은 배열 기반의 컬렉션 클래스를 사용한다면 데이터를 꺼낼 때마다 빈 공간을 채우기 위해서 데이터의 복사가 발생하므로 비효율적이다. 따라서 큐를 사용할때는 연결 리스트(Linked List)로 구현하는 것이 적합하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="데큐double-ended-queue"&gt;
 데큐(Double-Ended Queue)
 &lt;a class="heading-anchor" href="#%eb%8d%b0%ed%81%90double-ended-queue" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;큐와 스택의 장점을 합쳐놓은 개념이다.&lt;/li&gt;
&lt;li&gt;양쪽 끝에서 삽입과 삭제가 모두 가능한 자료구조이다.&lt;/li&gt;
&lt;li&gt;두 개의 포인터를 사용하여, 양쪽에서 삽입과 삭제를 발생시킬 수 있다.&lt;/li&gt;
&lt;li&gt;입력이 한쪽 끝으로만 가능하도록 설정한 데크인 입력제한데크(Scroll), 출력이 한쪽 끝으로만 가능하도록 설정한 데크인 출력제한데크(Shelf)가 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="c로-구현한-큐--덱-queue--deque"&gt;
 C++로 구현한 큐 &amp;amp; 덱 (Queue &amp;amp; Deque)
 &lt;a class="heading-anchor" href="#c%eb%a1%9c-%ea%b5%ac%ed%98%84%ed%95%9c-%ed%81%90--%eb%8d%b1-queue--deque" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kyungryeol-yoon.github.io/posts/data-structures-linked-list-array/"&gt;이전에 작성한 양방향 링크드 리스트의 코드를 재활용&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Queue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;DoubleList&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;DoubleList&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;getdouble&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;dequeue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;display&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;Queue.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;doublelist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DoubleList&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="o"&gt;::~&lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;insertNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_position&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;dequeue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;delNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;displayNode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//Manager.cpp
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;QueueRun&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;menu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;1.삽입&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;2.반환&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;3.출력&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;입력 : &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;cin&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;INSERT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;추가 할 데이터 : &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;cin&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;55&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;56&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;57&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;DEL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;58&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dequeue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;59&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;60&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;61&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;COUT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;62&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getdouble&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getHead&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;63&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;데이터가 없습니다.&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;64&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;65&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;66&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;67&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;68&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;69&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;70&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;71&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;72&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;73&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[Data Structures | C++] Linked List &amp; Array : 링크드리스트 &amp; 배열</title><link>https://kyungryeol-yoon.github.io/cs/algorithms-ds/data-structures-linked-list-array/</link><pubDate>Fri, 22 Jan 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/cs/algorithms-ds/data-structures-linked-list-array/</guid><description>&lt;h2 id="배열array"&gt;
 배열(Array)
 &lt;a class="heading-anchor" href="#%eb%b0%b0%ec%97%b4array" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/data-structures/array.jpg" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;데이터를 물리적 주소에 순차적으로 저장하며 인덱스를 가지고 있어 바로 접근할 수 있기 때문에 접근 속도가 매우 빠르다.\
그러나, 배열은 크가가 고정되어 있기 때문에 처음 지정된 사이즈보다 더 많은 데이터를 넣으려면 배열의 크기를 늘리는 연산을 해야하고 데이터 삽입/삭제시 해당 위치 다음칸에 있는 데이터를 모두 한칸씩 뒤로 밀거나 앞으로 당겨오는 연산을 해야하기 때문에 데이터 삽입/삭제에는 약한 모습을 보인다.&lt;/p&gt;
&lt;h2 id="연결리스트linkedlist"&gt;
 연결리스트(LinkedList)
 &lt;a class="heading-anchor" href="#%ec%97%b0%ea%b2%b0%eb%a6%ac%ec%8a%a4%ed%8a%b8linkedlist" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://kyungryeol-yoon.github.io/images/data-structures/linkedlist.jpg" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;데이터를 저장할 때 데이터만 저장하는 것이 아니라 다음 데이터의 물리적 주소까지 같이 저장한다.\
(단순 연결리스트는 다음 데이터의 주소를, 이중 연결리스트는 이전 주소와 다음 주소를 모두 저장) 특정 데이터에 접근할 때 인덱스로 바로 접근할 수 있었던 배열과 달리 첫 노드부터 원하는 노드까지 링크를 따라가야 접근이 가능하기 때문에 배열에 비해 접근 속도는 떨어진다.\
하지만 반대로, 데이터를 삽입/삭제 할 때에는 물리적 주소에 구애받지 않고 앞/뒤 노드의 주소만 끼워넣을 노드의 주소로 바꿔주면 되기 때문에 삽입/삭제는 배열보다 빠르다.&lt;/p&gt;
&lt;h2 id="c로-구현한-양방향-연결-리스트double-linked-list"&gt;
 C++로 구현한 양방향 연결 리스트(Double Linked List)
 &lt;a class="heading-anchor" href="#c%eb%a1%9c-%ea%b5%ac%ed%98%84%ed%95%9c-%ec%96%91%eb%b0%a9%ed%96%a5-%ec%97%b0%ea%b2%b0-%eb%a6%ac%ec%8a%a4%ed%8a%b8double-linked-list" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c++" data-lang="c++"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * 연결리스트(LinkedList)에 사용할 노드 클래스
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Llink&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Rlink&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 10&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;IDNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 11&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 13&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 14&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 16&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 17&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;getLlink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Llink&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 18&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Rlink&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 19&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 20&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;llink&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Llink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llink&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 21&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;rlink&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Rlink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rlink&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 22&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 23&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 24&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_Data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_Data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 25&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 26&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;GetID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;IDNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 27&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SetID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;idnum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;IDNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;idnum&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 29&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * Double Linked List 클래스
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DoubleList&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 36&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 37&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Tail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 38&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;IDCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 40&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;DoubleList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 41&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;DoubleList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 42&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 43&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;getHead&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 44&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;getTail&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Tail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 45&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 46&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;ArrangeNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 47&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 48&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;insertNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_location&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//삽입 추가 (위치 입력 가능)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 49&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;delNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_location&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//삭제 (위치 입력 가능)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 50&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;displayNode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;//출력
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 51&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;AllDel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;//모두 삭제
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 52&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;CountNode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;//현재 노드 갯수
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 53&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_location&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//위치를 찾아 노드 데이터 찾기
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 54&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Reverse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;//뒤집기
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 55&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 56&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 57&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 58&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * Double Linked List 메뉴
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 59&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 60&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Doublerun&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 61&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_menu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 62&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 63&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 64&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 65&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 66&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 67&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;1.추가 2.삭제 3.출력 4.전체삭제 5.노드 총 갯수&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;6.찾기 7.링크드 뒤집기&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;입력 : &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 68&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;cin&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_menu&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 69&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 70&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_menu&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 71&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 72&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;INSERT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 73&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;추가할 정수 : &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 74&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;cin&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 75&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;위치 입력 : &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 76&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;cin&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_position&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 77&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;insertNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_position&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 78&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 79&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;DEL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 80&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getHead&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 81&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;데이터가 없습니다.&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 82&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 83&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 84&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 85&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;데이터 삭제할 위치 : &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 86&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;cin&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_location&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 87&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;delNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_location&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 88&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 89&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 90&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;COUT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 91&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getHead&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 92&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;데이터가 없습니다.&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 93&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 94&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 95&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;displayNode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 96&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 97&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 98&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;ALLDEL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 99&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getHead&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;100&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;데이터가 없습니다.&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;101&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;102&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;103&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;AllDel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;104&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;105&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;106&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;COUNTNODE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;107&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;총 갯수 : &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;CountNode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;108&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;109&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;SEARCH&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;110&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getHead&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;111&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;데이터가 없습니다.&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;112&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;113&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;114&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;몇 번째 데이터 : &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;115&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;cin&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;116&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;당신이 찾는 데이터 : &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;117&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;118&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;119&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;REVERSE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;120&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;뒤집기 전 출력 : &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;121&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;displayNode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;122&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Reverse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;123&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;뒤집기 후 출력 : &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;124&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;doublelist&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;displayNode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;125&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;126&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;127&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;다시 입력해주세요&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;128&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;129&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;130&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;131&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;132&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;133&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;134&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * Node 추가
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;135&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;136&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;DoubleList&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;insertNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;137&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;IDCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;138&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;newNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;139&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;newNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;140&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;newNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;SetID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IDCount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;141&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;142&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Head&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;143&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;Head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;144&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;Tail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;145&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;146&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;147&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_position&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;148&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;newNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;149&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;150&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;Head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;151&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;152&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_position&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;153&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;newNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Tail&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;154&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;Tail&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;155&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;Tail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;156&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;157&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;158&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;159&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;_position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;160&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;161&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;162&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;163&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;164&lt;/span&gt;&lt;span class="cl"&gt;				&lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;165&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;166&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;newNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;167&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;newNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;168&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;169&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;170&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;171&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;172&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;173&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;174&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * Node 삭제
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;175&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;176&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;DoubleList&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;delNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;177&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_location&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;178&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;Head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;179&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Head&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;180&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;181&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;182&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;183&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;184&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;185&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;_location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;186&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;187&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;188&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;189&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;190&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;191&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;after&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;192&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;after&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;193&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;194&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;195&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;196&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;197&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;198&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;199&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;200&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;201&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * Node 출력
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;202&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;203&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;DoubleList&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;displayNode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;204&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;205&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;206&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;207&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Temp&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;208&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;209&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;210&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;211&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;ID:&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;Temp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;GetID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; Data:&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;Temp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;212&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;Temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Temp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;213&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;214&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;215&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;216&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;217&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;218&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * Node 모두 삭제
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;219&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;220&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;DoubleList&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AllDel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;221&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;222&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;223&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Head&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;224&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;225&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;226&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;227&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;delNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;228&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;229&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;230&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;231&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;232&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;233&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * 현재 Node 갯수
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;234&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;235&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;DoubleList&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CountNode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;236&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;237&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;238&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;239&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;240&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;241&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;242&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;243&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;244&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;245&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;246&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * Node 찾기
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;247&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;248&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;DoubleList&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;249&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;250&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;_location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;251&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;252&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;253&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;254&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;255&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;256&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;257&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * Node 뒤집기
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;258&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;259&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;DoubleList&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Reverse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;260&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;261&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;262&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;263&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;264&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getRlink&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;265&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setRlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getLlink&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;266&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setLlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;267&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;268&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;Tail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;269&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="n"&gt;Head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;270&lt;/span&gt;&lt;span class="cl"&gt;			&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;271&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;272&lt;/span&gt;&lt;span class="cl"&gt;		&lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;273&lt;/span&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;274&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Deep Copy &amp; Shallow Copy : 깊은 복사 &amp; 얕은 복사</title><link>https://kyungryeol-yoon.github.io/cs/algorithms-ds/deep-copy-shallow-copy/</link><pubDate>Wed, 20 Jan 2016 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/cs/algorithms-ds/deep-copy-shallow-copy/</guid><description>&lt;ul&gt;
&lt;li&gt;얕은 복사(shallow copy)와 깊은 복사(deep copy)는 객체 복사의 방식에 따라 차이가 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="python에서의-얕은-복사와-깊은-복사"&gt;
 Python에서의 얕은 복사와 깊은 복사
 &lt;a class="heading-anchor" href="#python%ec%97%90%ec%84%9c%ec%9d%98-%ec%96%95%ec%9d%80-%eb%b3%b5%ec%82%ac%ec%99%80-%ea%b9%8a%ec%9d%80-%eb%b3%b5%ec%82%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="얕은-복사-shallow-copy"&gt;
 얕은 복사 (Shallow Copy)
 &lt;a class="heading-anchor" href="#%ec%96%95%ec%9d%80-%eb%b3%b5%ec%82%ac-shallow-copy" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Python에서 &lt;strong&gt;얕은 복사&lt;/strong&gt;는 객체를 복사할 때, 원본 객체가 참조하는 객체들(즉, 리스트나 딕셔너리와 같은 복합 객체들)은 복사하지 않고 원본 객체의 참조만 복사하는 방식이다.&lt;/li&gt;
&lt;li&gt;즉, 새로운 객체가 생성되지만, 그 객체가 참조하는 내용은 여전히 원본 객체와 동일하다.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;list.copy()&lt;/code&gt; 또는 &lt;code&gt;copy.copy()&lt;/code&gt;를 사용하여 얕은 복사를 만들 수 있다.&lt;/li&gt;
&lt;li&gt;얕은 복사에서 복사된 객체는 독립적인 객체이지만, 그 객체 내부의 참조된 요소들은 여전히 원본 객체의 요소들과 연결되어 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;copy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 원본 리스트&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 얕은 복사&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;shallow_copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 복사된 객체 수정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;shallow_copy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;999&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;원본 리스트:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 원본 리스트가 수정됨&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;얕은 복사 리스트:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shallow_copy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 복사된 리스트도 수정됨&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;원본 리스트: [1, 2, [999, 4]]
얕은 복사 리스트: [1, 2, [999, 4]]&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;얕은 복사를 사용하면, 내부 리스트 **[3, 4]**는 복사되지 않고, 원본 객체와 복사된 객체 모두 같은 참조를 가진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="깊은-복사-deep-copy"&gt;
 깊은 복사 (Deep Copy)
 &lt;a class="heading-anchor" href="#%ea%b9%8a%ec%9d%80-%eb%b3%b5%ec%82%ac-deep-copy" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Python에서 &lt;strong&gt;깊은 복사&lt;/strong&gt;는 객체와 그 객체가 참조하는 모든 객체들까지 재귀적으로 복사하여, 완전히 독립적인 객체를 생성하는 방식이다.&lt;/li&gt;
&lt;li&gt;즉, 원본 객체와 복사된 객체는 완전히 별개이며, 복사된 객체는 원본 객체와의 참조 관계가 없다.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;copy.deepcopy()&lt;/code&gt;를 사용하여 깊은 복사를 만들 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;copy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 원본 리스트&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 깊은 복사&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;deep_copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deepcopy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 복사된 객체 수정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;deep_copy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;999&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;원본 리스트:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 원본 리스트는 수정되지 않음&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;깊은 복사 리스트:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;deep_copy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 복사된 리스트만 수정됨&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;원본 리스트: [1, 2, [3, 4]]
깊은 복사 리스트: [1, 2, [999, 4]]&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;깊은 복사를 사용하면, 내부 객체도 복사되므로 원본 객체와 복사된 객체는 완전히 독립적이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="java에서의-얕은-복사와-깊은-복사"&gt;
 Java에서의 얕은 복사와 깊은 복사
 &lt;a class="heading-anchor" href="#java%ec%97%90%ec%84%9c%ec%9d%98-%ec%96%95%ec%9d%80-%eb%b3%b5%ec%82%ac%ec%99%80-%ea%b9%8a%ec%9d%80-%eb%b3%b5%ec%82%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="얕은-복사-shallow-copy-1"&gt;
 얕은 복사 (Shallow Copy)
 &lt;a class="heading-anchor" href="#%ec%96%95%ec%9d%80-%eb%b3%b5%ec%82%ac-shallow-copy-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Java에서 &lt;strong&gt;얕은 복사&lt;/strong&gt;는 객체를 복사할 때, 객체의 &amp;ldquo;참조&amp;quot;만 복사하고, 객체 내부의 참조된 객체들은 복사하지 않고 원본 객체의 참조를 그대로 공유하는 방식이다.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Object.clone()&lt;/code&gt; 메서드를 사용하여 얕은 복사를 할 수 있습니다. 단, &lt;code&gt;clone()&lt;/code&gt; 메서드를 사용하려면 &lt;code&gt;Cloneable&lt;/code&gt; 인터페이스를 구현해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;implements&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Cloneable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CloneNotSupportedException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 얕은 복사&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;, &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CloneNotSupportedException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;person1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;John&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;25&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;person2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;person1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 얕은 복사&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Jane&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 이름을 변경&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;person1: &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;person1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;person2: &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;person1: John, 25
person2: Jane, 25&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;이 경우, person1과 person2는 Person 객체가 얕게 복사되었고, &lt;code&gt;name&lt;/code&gt; 필드는 별도로 수정된다.&lt;/li&gt;
&lt;li&gt;그러나 만약 Person 객체가 다른 객체를 필드로 가지고 있었다면, 그 필드는 참조만 복사된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="깊은-복사-deep-copy-1"&gt;
 깊은 복사 (Deep Copy)
 &lt;a class="heading-anchor" href="#%ea%b9%8a%ec%9d%80-%eb%b3%b5%ec%82%ac-deep-copy-1" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Java에서 &lt;strong&gt;깊은 복사&lt;/strong&gt;는 객체와 그 객체가 참조하는 모든 객체들을 재귀적으로 복사하여 독립적인 객체를 만드는 방식이다.&lt;/li&gt;
&lt;li&gt;복사하려는 객체가 참조하는 모든 객체들을 별도로 복사해야 하므로, 수동으로 깊은 복사를 구현해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;implements&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Cloneable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CloneNotSupportedException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 깊은 복사: Address도 복사&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cloned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cloned&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;street&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 새 객체 생성&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cloned&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;street&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;street&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;street&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;street&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CloneNotSupportedException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;123 Main St&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Springfield&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;person1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;John&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;person2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;person1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 깊은 복사&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;street&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;456 Elm St&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 주소를 변경&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;person1 address: &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;person1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;street&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 변경되지 않음&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;person2 address: &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;street&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 변경됨&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;person1 address: 123 Main St
person2 address: 456 Elm St&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;깊은 복사를 위해 Address 객체도 새로 생성하여 복사하였기 때문에, person1과 person2는 독립적인 Address 객체를 가지고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="c에서의-얕은-복사와-깊은-복사"&gt;
 C++에서의 얕은 복사와 깊은 복사
 &lt;a class="heading-anchor" href="#c%ec%97%90%ec%84%9c%ec%9d%98-%ec%96%95%ec%9d%80-%eb%b3%b5%ec%82%ac%ec%99%80-%ea%b9%8a%ec%9d%80-%eb%b3%b5%ec%82%ac" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="얕은-복사-shallow-copy-2"&gt;
 얕은 복사 (Shallow Copy)
 &lt;a class="heading-anchor" href="#%ec%96%95%ec%9d%80-%eb%b3%b5%ec%82%ac-shallow-copy-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;C++에서 얕은 복사는 객체를 복사할 때, 객체의 멤버 변수나 포인터는 복사하지만, 포인터가 가리키는 데이터는 복사하지 않는 방식이다.&lt;/li&gt;
&lt;li&gt;기본적으로 얕은 복사는 컴파일러가 제공하는 복사 생성자를 사용하여 수행된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 복사 생성자 (얕은 복사)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;person1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;John&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;person2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;person1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 얕은 복사
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;person1: &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;person1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;, &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;person1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;person2: &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;, &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;person2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;person1: John, 25
person2: John, 25&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;C++에서 기본적으로 제공하는 얕은 복사는 객체의 값만 복사하며, 포인터나 동적 할당된 메모리와 같은 복잡한 데이터를 처리하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="깊은-복사-deep-copy-2"&gt;
 깊은 복사 (Deep Copy)
 &lt;a class="heading-anchor" href="#%ea%b9%8a%ec%9d%80-%eb%b3%b5%ec%82%ac-deep-copy-2" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;C++에서 깊은 복사는 객체가 참조하는 동적 메모리나 자원을 새로 할당하고 복사하는 방식이다.&lt;/li&gt;
&lt;li&gt;깊은 복사를 위해서는 복사 생성자나 복사 대입 연산자를 수동으로 구현해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 동적 메모리 할당
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 복사 생성자 (깊은 복사)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="프로토-타입-패턴"&gt;
 프로토 타입 패턴
 &lt;a class="heading-anchor" href="#%ed%94%84%eb%a1%9c%ed%86%a0-%ed%83%80%ec%9e%85-%ed%8c%a8%ed%84%b4" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;객체 생성 패턴 중 하나로, 객체의 복제를 통해 새로운 객체를 생성하는 방법이다.&lt;/li&gt;
&lt;li&gt;즉, 객체를 &amp;ldquo;클론(clone)&amp;ldquo;해서 새 객체를 만드는 방식으로, 기존 객체를 복제하여 새로운 객체를 만들어낸다.&lt;/li&gt;
&lt;li&gt;이는 객체 생성 비용을 줄이고, 복잡한 객체를 효율적으로 생성할 수 있는 장점이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="프로토타입-패턴의-특징"&gt;
 프로토타입 패턴의 특징
 &lt;a class="heading-anchor" href="#%ed%94%84%eb%a1%9c%ed%86%a0%ed%83%80%ec%9e%85-%ed%8c%a8%ed%84%b4%ec%9d%98-%ed%8a%b9%ec%a7%95" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;복제(Cloning)&lt;/strong&gt;: 객체를 복제하여 새로 만들기 때문에, 복잡한 객체나 자원을 새로 생성하는 비용을 줄일 수 있다.&lt;/li&gt;
&lt;li&gt;새로운 인스턴스를 생성하는 데 필요한 정보를 프로토타입 객체에서 얻어온다.
&lt;ul&gt;
&lt;li&gt;즉, 기존 객체를 기반으로 새로운 객체를 만들어내는 방식이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;객체 생성 시점에서 어떤 구체적인 클래스를 사용해야 하는지 모를 때 유용하다.
&lt;ul&gt;
&lt;li&gt;기존 객체를 복사하여 새로운 객체를 생성할 수 있기 때문에, 특정 클래스에 종속되지 않고도 객체를 동적으로 생성할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="프로토타입-패턴의-구조"&gt;
 프로토타입 패턴의 구조
 &lt;a class="heading-anchor" href="#%ed%94%84%eb%a1%9c%ed%86%a0%ed%83%80%ec%9e%85-%ed%8c%a8%ed%84%b4%ec%9d%98-%ea%b5%ac%ec%a1%b0" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;프로토타입 패턴은 주로 다음과 같은 구성 요소로 이루어진다:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prototype (프로토타입)&lt;/strong&gt;: 이 인터페이스는 clone() 메서드를 정의합니다. 이 메서드는 객체를 복제할 수 있도록 한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ConcretePrototype (구체적인 프로토타입)&lt;/strong&gt;: Prototype을 구현한 실제 객체이다. clone() 메서드를 구현하여 객체를 복사하는 방법을 정의한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Client (클라이언트)&lt;/strong&gt;: 복제된 객체를 필요로 하는 클라이언트로, Prototype 객체를 통해 복제된 객체를 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="python에서-프로토타입-패턴-구현"&gt;
 Python에서 프로토타입 패턴 구현
 &lt;a class="heading-anchor" href="#python%ec%97%90%ec%84%9c-%ed%94%84%eb%a1%9c%ed%86%a0%ed%83%80%ec%9e%85-%ed%8c%a8%ed%84%b4-%ea%b5%ac%ed%98%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;얕은 복사&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;copy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Prototype 인터페이스&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Prototype&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;NotImplementedError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Subclass must implement abstract method.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ConcretePrototype (구체적인 프로토타입)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ConcretePrototype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Prototype&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 얕은 복사를 사용하여 복제&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ConcretePrototype with value &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 클라이언트 코드&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prototype&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConcretePrototype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Original Object&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 원본 객체&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;clone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prototype&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 복제된 객체&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Original:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Clone:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 복제 후 값 변경&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Cloned Object&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;After modification - Original:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;After modification - Clone:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;Original: ConcretePrototype with value Original Object
Clone: ConcretePrototype with value Original Object
After modification - Original: ConcretePrototype with value Original Object
After modification - Clone: ConcretePrototype with value Cloned Object&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Prototype 클래스는 &lt;code&gt;clone()&lt;/code&gt; 메서드를 선언하지만 구현하지 않으며, 실제 복제 작업은 이 클래스를 상속받은 ConcretePrototype 클래스에서 구현한다.&lt;/li&gt;
&lt;li&gt;ConcretePrototype 클래스에서 &lt;code&gt;clone()&lt;/code&gt; 메서드는 &lt;code&gt;copy.copy(self)&lt;/code&gt;를 사용하여 객체를 복제한다. 이는 얕은 복사를 사용한 복제이다.&lt;/li&gt;
&lt;li&gt;클라이언트는 ConcretePrototype 객체를 만들고, &lt;code&gt;clone()&lt;/code&gt; 메서드를 통해 새로운 객체를 생성할 수 있다. 이후 복제된 객체를 변경하더라도 원본 객체는 영향을 받지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;깊은 복사&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;copy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Prototype&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;NotImplementedError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Subclass must implement abstract method.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ConcretePrototype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Prototype&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deepcopy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 깊은 복사를 사용하여 복제&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ConcretePrototype with value &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; and data &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConcretePrototype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Original&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;# 복사될 객체&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;clone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 깊은 복사된 객체&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Original:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Clone:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 복제 후 데이터 수정&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;After modification - Original:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;After modification - Clone:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;Original: ConcretePrototype with value Original and data [1, 2, 3]
Clone: ConcretePrototype with value Original and data [1, 2, 3]
After modification - Original: ConcretePrototype with value Original and data [1, 2, 3]
After modification - Clone: ConcretePrototype with value Original and data [1, 2, 3, 4]&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;copy.deepcopy(self)&lt;/code&gt;를 사용하여 깊은 복사를 구현하였다. 이 방식은 객체 내에 포함된 리스트와 같은 가변 객체까지 복사한다.&lt;/li&gt;
&lt;li&gt;복제된 객체의 데이터를 변경하더라도 원본 객체의 데이터는 변경되지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="java에서-프로토타입-패턴-구현"&gt;
 Java에서 프로토타입 패턴 구현
 &lt;a class="heading-anchor" href="#java%ec%97%90%ec%84%9c-%ed%94%84%eb%a1%9c%ed%86%a0%ed%83%80%ec%9e%85-%ed%8c%a8%ed%84%b4-%ea%b5%ac%ed%98%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Java에서는 Cloneable 인터페이스와 Object.clone() 메서드를 이용하여 프로토타입 패턴을 구현한다.&lt;/li&gt;
&lt;li&gt;clone() 메서드는 객체를 복제하는 데 사용되며, 이를 구현하기 위해서는 클래스가 Cloneable 인터페이스를 구현해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Prototype Interface&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Prototype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Cloneable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Prototype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ConcretePrototype&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ConcretePrototype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;implements&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Prototype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;ConcretePrototype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// clone() 메서드 구현&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Prototype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Prototype&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 얕은 복사&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CloneNotSupportedException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 클라이언트 코드&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PrototypePatternExample&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ConcretePrototype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;prototype1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ConcretePrototype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Original Object&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 객체 복제&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ConcretePrototype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;clone1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ConcretePrototype&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;prototype1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Original: &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;prototype1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getField&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Clone: &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;clone1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getField&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;Original: Original Object
Clone: Original Object&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="c에서-프로토타입-패턴-구현"&gt;
 C++에서 프로토타입 패턴 구현
 &lt;a class="heading-anchor" href="#c%ec%97%90%ec%84%9c-%ed%94%84%eb%a1%9c%ed%86%a0%ed%83%80%ec%9e%85-%ed%8c%a8%ed%84%b4-%ea%b5%ac%ed%98%84" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;C++에서도 clone() 메서드를 사용하여 프로토타입 패턴을 구현할 수 있다.&lt;/li&gt;
&lt;li&gt;C++에서 객체 복사는 기본적으로 얕은 복사만 제공하므로, 깊은 복사를 구현하려면 복사 생성자를 오버라이드해야 할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Prototype Class
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Prototype&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;Prototype&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// clone 메서드 선언
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;display&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 객체를 출력할 display 메서드
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;Prototype&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c1"&gt;// 가상 소멸자
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ConcretePrototype Class
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ConcretePrototype&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Prototype&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ConcretePrototype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// clone 메서드 구현
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Prototype&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ConcretePrototype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 깊은 복사 (복사 생성자 호출)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;display&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Data: &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 클라이언트 코드
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ConcretePrototype&lt;/span&gt; &lt;span class="n"&gt;prototype1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Prototype Object&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 객체 복제
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ConcretePrototype&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;clone1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;dynamic_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ConcretePrototype&lt;/span&gt;&lt;span class="o"&gt;*&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prototype1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Original: &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prototype1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Clone: &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;clone1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;clone1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 동적 메모리 해제
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;Original: Data: Prototype Object
Clone: Data: Prototype Object&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="프로토타입-패턴의-장점"&gt;
 프로토타입 패턴의 장점
 &lt;a class="heading-anchor" href="#%ed%94%84%eb%a1%9c%ed%86%a0%ed%83%80%ec%9e%85-%ed%8c%a8%ed%84%b4%ec%9d%98-%ec%9e%a5%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;객체 생성 비용 절감&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;기존 객체를 복제하여 새로운 객체를 만드는 방식이기 때문에 객체를 새로 생성하는 비용을 절감할 수 있다.&lt;/li&gt;
&lt;li&gt;특히, 객체 생성이 비용이 많이 드는 경우 유용하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;복잡한 객체 생성의 단순화&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;객체를 복제하는 방식으로 복잡한 객체를 쉽게 생성할 수 있다.&lt;/li&gt;
&lt;li&gt;예를 들어, 복잡한 초기화 과정이 필요한 객체가 있을 때, 이를 복제하여 새 객체를 빠르게 생성할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;동적 객체 생성&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;어떤 클래스를 사용할지 알기 어려운 경우, 기존 객체를 복제하는 방식으로 동적으로 객체를 생성할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;메모리 관리 용이&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;복사하는 방식으로 객체를 생성하기 때문에, 객체가 다루는 자원(메모리)을 관리하는 데 있어 효율성을 높일 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="프로토타입-패턴의-단점"&gt;
 프로토타입 패턴의 단점
 &lt;a class="heading-anchor" href="#%ed%94%84%eb%a1%9c%ed%86%a0%ed%83%80%ec%9e%85-%ed%8c%a8%ed%84%b4%ec%9d%98-%eb%8b%a8%ec%a0%90" aria-label="이 섹션 링크 복사" data-anchor&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;복잡한 객체의 복사&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;객체를 복제할 때, 객체가 내부에 다른 객체를 참조하거나 복잡한 상태를 가질 경우 깊은 복사와 같은 추가적인 관리가 필요할 수 있다.&lt;/li&gt;
&lt;li&gt;특히, 객체 간의 참조가 중요한 경우, 복사 후에 참조 관계가 잘못 복제될 위험이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;성능 이슈&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;객체 복사가 복잡한 객체일 경우, 복사 과정에서 성능 저하가 발생할 수 있다.&lt;/li&gt;
&lt;li&gt;예를 들어, 매우 큰 객체나 복잡한 구조를 갖는 객체를 복제할 때 시간 소모가 클 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;복사본의 일관성 문제&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;복사본이 원본 객체와 다른 상태를 유지하게 되는 경우, 복사본과 원본 객체 간의 일관성을 관리하는 것이 어려울 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>검색</title><link>https://kyungryeol-yoon.github.io/search/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/search/</guid><description/></item><item><title>아카이브</title><link>https://kyungryeol-yoon.github.io/archives/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/archives/</guid><description/></item><item><title>카테고리</title><link>https://kyungryeol-yoon.github.io/categories/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyungryeol-yoon.github.io/categories/</guid><description/></item></channel></rss>