<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>테크믈리에의 리뷰 공간</title>
    <link>https://korjwl1.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 14 Apr 2026 12:33:19 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>테크믈리에</managingEditor>
    <item>
      <title>OPNsense 설정기 2. SSL 인증서 관리</title>
      <link>https://korjwl1.tistory.com/40</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 서론 -&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞선 글에서는 HA-Proxy를 사용해서 Reverse Proxy 서버를 구축하는 방법을 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 Reverse Proxy를 하면 빼놓을 수 없는 것 중 하나가 HTTPS 서버를 위한 SSL 인증서 관리이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 ACME Client를 통한 Let's Encrypt SSL 인증서 발급 및 자동갱신 방법 및 별도로 발급 받은 SSL 인증서의 등록 방법을 알아볼 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- ACME Client를 통한 SSL 관리 -&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;368&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yjsGn/btsKnrealTC/FSdV2nSwuSoIKbseWGIt2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yjsGn/btsKnrealTC/FSdV2nSwuSoIKbseWGIt2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yjsGn/btsKnrealTC/FSdV2nSwuSoIKbseWGIt2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyjsGn%2FbtsKnrealTC%2FFSdV2nSwuSoIKbseWGIt2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2048&quot; height=&quot;368&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;368&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. System - Firmware - Plugins에 들어가서 os-acme-client를 검색하여 설치하도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;976&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdbedi/btsKl36D010/61jokYLL2HIKGJiNjKHpVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdbedi/btsKl36D010/61jokYLL2HIKGJiNjKHpVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdbedi/btsKl36D010/61jokYLL2HIKGJiNjKHpVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcdbedi%2FbtsKl36D010%2F61jokYLL2HIKGJiNjKHpVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2048&quot; height=&quot;976&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;976&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Services - ACME Client - Settings로 들어가서 Enable Plugin을 체크해주고 Auto Renewal도 체크해주도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HAProxy Integration의 경우, HA-Proxy에서 사용하고자 하는 모든 SSL 인증서가 ACME Client를 통해 발급받았다면 문제가 없지만 가비아 등에서 따로 발급 받은 인증서랑 혼용해서 사용하고자 할 때에는 문제가 생겼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1782&quot; data-origin-height=&quot;1608&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bu90Rq/btsKnP6X1OE/d6CDUKg39fFkwc5os4ALL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bu90Rq/btsKnP6X1OE/d6CDUKg39fFkwc5os4ALL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bu90Rq/btsKnP6X1OE/d6CDUKg39fFkwc5os4ALL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbu90Rq%2FbtsKnP6X1OE%2Fd6CDUKg39fFkwc5os4ALL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1782&quot; height=&quot;1608&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1782&quot; data-origin-height=&quot;1608&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Services - ACME Client - Accounts - Accounts에 들어가서 새로운 계정을 하나 등록해주도록 한다. 이 때 ACME CA는 Let's Encrypt를 사용해보도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1750&quot; data-origin-height=&quot;2036&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ATuev/btsKoiniMph/ckkW07kFmohno4ixZkK3t1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ATuev/btsKoiniMph/ckkW07kFmohno4ixZkK3t1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ATuev/btsKoiniMph/ckkW07kFmohno4ixZkK3t1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FATuev%2FbtsKoiniMph%2FckkW07kFmohno4ixZkK3t1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1750&quot; height=&quot;2036&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1750&quot; data-origin-height=&quot;2036&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Services - ACME Client - Challenge Types - Challenge Types에서 새로운 Challenge Type을 생성하도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때, Challenge Type은 DNS-01, HTTP-01, TLS-ALPN-01 중 본인에게 맞는 걸 정독해보고 골라보도록 하자. Interface는 WAN으로 선택하고 IP Addresses에는 해당 WAN 포트에 할당된 공인 IP를 지정해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1792&quot; data-origin-height=&quot;816&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/51fxH/btsKm87iDYK/ft1SNdBgvurkerncK0aQa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/51fxH/btsKm87iDYK/ft1SNdBgvurkerncK0aQa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/51fxH/btsKm87iDYK/ft1SNdBgvurkerncK0aQa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F51fxH%2FbtsKm87iDYK%2Fft1SNdBgvurkerncK0aQa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1792&quot; height=&quot;816&quot; data-origin-width=&quot;1792&quot; data-origin-height=&quot;816&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Services - ACME Client - Automations - Automations에서 새로운 Automation을 등록한다. 설정은 위와 같이 하면 되고, 이걸 활성화하면 SSL 인증서가 갱신될 때마다 자동으로 HA-Proxy도 재시작해서 변경 사항을 적용해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;2160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cT72Vg/btsKnER6vwE/V29gSyJHxBG2GDuNnwHw11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cT72Vg/btsKnER6vwE/V29gSyJHxBG2GDuNnwHw11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cT72Vg/btsKnER6vwE/V29gSyJHxBG2GDuNnwHw11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcT72Vg%2FbtsKnER6vwE%2FV29gSyJHxBG2GDuNnwHw11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1772&quot; height=&quot;2160&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;2160&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. Services - ACME Client - Certificates - Certificates에서 새로운 인증서를 하나 발급받도록 한다. Common Name에는 host name 등을 적어주도록 하고 ACME Account는 앞서 만든 Account, Challenge Type도 앞서 생성한 Challenge Type을 골라주도록 하자. Automations에는 Restart HAProxy를 선택해야 갱신될 때마다 자동 적용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;423&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d7QzW0/btsKnSJBIZe/2A5QLqDfhANKV90bOR8yl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d7QzW0/btsKnSJBIZe/2A5QLqDfhANKV90bOR8yl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d7QzW0/btsKnSJBIZe/2A5QLqDfhANKV90bOR8yl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd7QzW0%2FbtsKnSJBIZe%2F2A5QLqDfhANKV90bOR8yl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2048&quot; height=&quot;423&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;423&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. 생성 후에는 위와 같이 나올텐데, 여기서 Commands에 있는 버튼들을 통하여 발급, 갱신, 삭제 등을 할 수 있다. 성공적으로 발급된다면 Last ACME Status에 OK가 찍힌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 직접 SSL 인증서를 등록하는 방법 -&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1739&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDjBbU/btsKnhpAi98/bybiMQktrCdyL2kXKfyst1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDjBbU/btsKnhpAi98/bybiMQktrCdyL2kXKfyst1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDjBbU/btsKnhpAi98/bybiMQktrCdyL2kXKfyst1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDjBbU%2FbtsKnhpAi98%2FbybiMQktrCdyL2kXKfyst1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;1739&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1739&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OPNsense에서 관리하는 모든 인증서들은 System - Trust - Certificates에 들어가면 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ACME Client로 발급받은 인증서들 뿐만아니라 OpenVPN, Self-Signed 인증서 등 OPNsense에서 발급된 인증서들도 확인이 가능하고 본인이 직접 올린 경우엔 external issuer로 올라가있는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1670&quot; data-origin-height=&quot;1400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkzsAG/btsKm7tYxvZ/8WXj8mgEUi0OEtvj9UYB8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkzsAG/btsKm7tYxvZ/8WXj8mgEUi0OEtvj9UYB8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkzsAG/btsKm7tYxvZ/8WXj8mgEUi0OEtvj9UYB8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkzsAG%2FbtsKm7tYxvZ%2F8WXj8mgEUi0OEtvj9UYB8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1670&quot; height=&quot;1400&quot; data-origin-width=&quot;1670&quot; data-origin-height=&quot;1400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상단에 add를 누르고 Import an existing Certificate을 고르면 직접 인증서를 등록할 수 있다.&lt;/p&gt;</description>
      <category>프로그래밍|소프트웨어</category>
      <author>테크믈리에</author>
      <guid isPermaLink="true">https://korjwl1.tistory.com/40</guid>
      <comments>https://korjwl1.tistory.com/40#entry40comment</comments>
      <pubDate>Tue, 29 Oct 2024 13:26:40 +0900</pubDate>
    </item>
    <item>
      <title>OPNsense 설정기 1. HA-Proxy를 이용한 Reverse Proxy 구축</title>
      <link>https://korjwl1.tistory.com/39</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 서론 -&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 사내에는 K8S 환경, 회사 홈페이지가 떠있는 서버, VPN 등 다양한 서비스가 돌아가고 있으며, 이를 외부 노출 용도인지 아닌지 등에 따라 다수의 DNS를 운용하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 외부로 나가는 통로는 메인 공유기 단 하나 뿐이라 단일 공용 IP에 다수의 DNS를 물려야했기에 원래는 상시 켜져있는 서버 중 한 대에 Nginx Proxy Manager를 도커로 올려 사용 중이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NPM은 원래라면 Nginx나 HA-Proxy에 복잡한 설정파일들을 적용해가며 해야할 작업을 간단한 마우스 클릭만으로 할 수 있게 해주었기 때문에 매우 편했지만 설치된 서버가 꺼지는 경우 나머지 서버에서 동작하는 서비스까지 전부 내려간다는 문제점이 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;438&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D1NJn/btsKmnp5MjF/ZZoS9KxVabLkPJZE1sz4O0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D1NJn/btsKmnp5MjF/ZZoS9KxVabLkPJZE1sz4O0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D1NJn/btsKmnp5MjF/ZZoS9KxVabLkPJZE1sz4O0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD1NJn%2FbtsKmnp5MjF%2FZZoS9KxVabLkPJZE1sz4O0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;520&quot; height=&quot;438&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;438&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 이유 때문에 방화벽 도입의 이유로 대표님께 OPNsense를 기반으로 한 자작 공유기를 사용할 것을 건의드렸고 이게 받아들여져 Hardkernel 사의 Odroid H4 Plus를 활용하여 최대한 저렴하고 저전력으로 자작 공유기를 맞추게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래는 여기에 Nginx를 기반으로 하여 Reverse Proxy를 올리고자 하였지만, 참고하기 위해 보는 모든 글마다 Nginx 및 Firewall 설정법이 다 다른데다가 아무리 따라하거나 과정들을 섞어봐도 쉽게 정상적으로 동작하는 방법을 찾기 어려웠다. 때문에 차선책으로 HA-Proxy를 사용하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고한 글은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://forum.opnsense.org/index.php?topic=23339.0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://forum.opnsense.org/index.php?topic=23339.0&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1730115536152&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Tutorial 2024/06: HAProxy + Let's Encrypt Wildcard Certificates + 100% A+ Rating&quot; data-og-description=&quot;&quot; data-og-host=&quot;forum.opnsense.org&quot; data-og-source-url=&quot;https://forum.opnsense.org/index.php?topic=23339.0&quot; data-og-url=&quot;https://forum.opnsense.org/index.php?topic=23339.0&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://forum.opnsense.org/index.php?topic=23339.0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://forum.opnsense.org/index.php?topic=23339.0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Tutorial 2024/06: HAProxy + Let's Encrypt Wildcard Certificates + 100% A+ Rating&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;forum.opnsense.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://community.spiceworks.com/t/opnsense-haproxy-as-reverse-proxy-for-self-hosted-services/1013494&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://community.spiceworks.com/t/opnsense-haproxy-as-reverse-proxy-for-self-hosted-services/1013494&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1730115572302&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Opnsense+HAProxy as reverse proxy for self-hosted services&quot; data-og-description=&quot;This how-to helps you setup haproxy as a reverse proxy to your self-hosted services. It also does SSL offloading for your services, so you can manage all Let&amp;rsquo;s Encrypt certificates in one place. If you don&amp;rsquo;t care about setting up SSL certs for all your&quot; data-og-host=&quot;community.spiceworks.com&quot; data-og-source-url=&quot;https://community.spiceworks.com/t/opnsense-haproxy-as-reverse-proxy-for-self-hosted-services/1013494&quot; data-og-url=&quot;https://community.spiceworks.com/t/opnsense-haproxy-as-reverse-proxy-for-self-hosted-services/1013494&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ePIAB/hyXppOjuvf/8pIWX5XpAoc7tl7xIkmjAk/img.png?width=852&amp;amp;height=768&amp;amp;face=0_0_852_768,https://scrap.kakaocdn.net/dn/KFx5B/hyXpyRZWhG/W1UNKpN5ekiU2KYaqB8KpK/img.png?width=852&amp;amp;height=768&amp;amp;face=0_0_852_768,https://scrap.kakaocdn.net/dn/1bSsd/hyXpxFzluL/GmOvxylonJ016GKhkrMGQ1/img.png?width=690&amp;amp;height=413&amp;amp;face=0_0_690_413&quot;&gt;&lt;a href=&quot;https://community.spiceworks.com/t/opnsense-haproxy-as-reverse-proxy-for-self-hosted-services/1013494&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://community.spiceworks.com/t/opnsense-haproxy-as-reverse-proxy-for-self-hosted-services/1013494&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ePIAB/hyXppOjuvf/8pIWX5XpAoc7tl7xIkmjAk/img.png?width=852&amp;amp;height=768&amp;amp;face=0_0_852_768,https://scrap.kakaocdn.net/dn/KFx5B/hyXpyRZWhG/W1UNKpN5ekiU2KYaqB8KpK/img.png?width=852&amp;amp;height=768&amp;amp;face=0_0_852_768,https://scrap.kakaocdn.net/dn/1bSsd/hyXpxFzluL/GmOvxylonJ016GKhkrMGQ1/img.png?width=690&amp;amp;height=413&amp;amp;face=0_0_690_413');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Opnsense+HAProxy as reverse proxy for self-hosted services&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This how-to helps you setup haproxy as a reverse proxy to your self-hosted services. It also does SSL offloading for your services, so you can manage all Let&amp;rsquo;s Encrypt certificates in one place. If you don&amp;rsquo;t care about setting up SSL certs for all your&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;community.spiceworks.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;참고로, ACME client를 통해 SSL 인증서를 발급받아 등록하거나 혹은 갖고 있는 SSL 인증서 파일을 등록하는 방법은 다음 글에서 다루도록 할 예정이니 만약 HTTPS 서버의 Reverse Proxy를 원한다면 다음 글을 먼저 읽고 오도록 하자. 혹은 위의 참조 글들을 읽어보도록 하자.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;-&lt;b&gt; HA Proxy 설치 및 기본 시스템 설정 -&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2786&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Sh3VG/btsKm8sv0rP/T1os3ACLrum5C7Iz36xle0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Sh3VG/btsKm8sv0rP/T1os3ACLrum5C7Iz36xle0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Sh3VG/btsKm8sv0rP/T1os3ACLrum5C7Iz36xle0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSh3VG%2FbtsKm8sv0rP%2FT1os3ACLrum5C7Iz36xle0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1720&quot; height=&quot;308&quot; data-origin-width=&quot;2786&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 우선은 당연하겠지만 HA-Proxy를 OPNsense에 설치해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치는 System - Firmware - Plugins에서 haproxy를 검색하여 할 수 있고, 까는 김에 겸사 겸사 on-acme-client도 설치하여 두도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ACME Client는 추후 Let's Encrypt를 통해 SSL 인증서를 발급받는데 사용할 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2692&quot; data-origin-height=&quot;1964&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z7NmD/btsKnklRtWL/vsDvqhzDmv9tiBGvKCRAsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z7NmD/btsKnklRtWL/vsDvqhzDmv9tiBGvKCRAsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z7NmD/btsKnklRtWL/vsDvqhzDmv9tiBGvKCRAsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz7NmD%2FbtsKnklRtWL%2FvsDvqhzDmv9tiBGvKCRAsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2692&quot; height=&quot;1964&quot; data-origin-width=&quot;2692&quot; data-origin-height=&quot;1964&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 설치하고 나면 Services 항목에 HAProxy가 추가되어있을 것이다. &amp;nbsp;Settings - Global Parameters로 이동하여 Cipher List와 Cipher Suites에 아래 값들을 복사해 넣고 Bind options는 prefer-client-ciphers로 지정하여 두자. (아마 필수 작업은 아닐 수도 있다. 참고 글 중 첫번 째 글에서 하라고 되어 있는 과정인데, SSL 인증서 등 보안 방면은 크게 잘 아는 편은 아니기 때문에 이 작업 관련해서 잘 아시는 분이 댓글 달아주시면 좋을 것 같다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cipher List: &lt;span style=&quot;background-color: #f2e3d9; color: #666666; text-align: start;&quot;&gt;ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666; text-align: start;&quot;&gt;Cipher Suites: &lt;/span&gt;&lt;span style=&quot;background-color: #f2e3d9; color: #666666; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #f2e3d9; color: #666666; text-align: start;&quot;&gt;TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;661&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/le9Fv/btsKnXDH8KY/vmnjNB52eC8SjkKCMkgKCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/le9Fv/btsKnXDH8KY/vmnjNB52eC8SjkKCMkgKCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/le9Fv/btsKnXDH8KY/vmnjNB52eC8SjkKCMkgKCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fle9Fv%2FbtsKnXDH8KY%2FvmnjNB52eC8SjkKCMkgKCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2048&quot; height=&quot;661&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;661&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;caret-color: #666666;&quot;&gt;3. 그 다음에는 System - Settings - Administraion으로 이동하여 TCP Port를 80, 443 외의 것으로 변경해주도록 하자. 변경 후에는 OPNSense 관리자 페이지 진입을 위해서 &amp;lt;IP&amp;gt;:&amp;lt;변경된 포트&amp;gt;로 접속해야할 것이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2378&quot; data-origin-height=&quot;1076&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/spMLY/btsKmJM9KKa/KTzC2ETN3RF6ZZwaoXD9K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/spMLY/btsKmJM9KKa/KTzC2ETN3RF6ZZwaoXD9K1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/spMLY/btsKmJM9KKa/KTzC2ETN3RF6ZZwaoXD9K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FspMLY%2FbtsKmJM9KKa%2FKTzC2ETN3RF6ZZwaoXD9K1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1720&quot; height=&quot;778&quot; data-origin-width=&quot;2378&quot; data-origin-height=&quot;1076&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Reverse Proxy를 수행하기 위해서는 HA-Proxy가 80, 443 포트로 들어오는 패킷을 다룰 수 있어야한다. Firewall - Aliases로 들어가 Alias를 위와 같이 하나 생성해주도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1627&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qxscD/btsKlr7To3N/o5Afx7c8VKCk9VTJbR04t0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qxscD/btsKlr7To3N/o5Afx7c8VKCk9VTJbR04t0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qxscD/btsKlr7To3N/o5Afx7c8VKCk9VTJbR04t0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqxscD%2FbtsKlr7To3N%2Fo5Afx7c8VKCk9VTJbR04t0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2048&quot; height=&quot;1627&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1627&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Firewall - Rules - WAN에서 새로운 룰을 하나 추가하는데, Action은 Pass, Interface는 WAN, Direction은 in, Protocol은 TCP로 지정하여 주고 Source는 any, Destination은 WAN address로 하여 from과 to 모두 방금 생성한 Alias로 지정해주도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- HA Proxy의 Reverse Proxy 설정 -&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1768&quot; data-origin-height=&quot;2160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2Fkzh/btsKn3jqvdV/KQ9My8EifbJVOluz66vv71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2Fkzh/btsKn3jqvdV/KQ9My8EifbJVOluz66vv71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2Fkzh/btsKn3jqvdV/KQ9My8EifbJVOluz66vv71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2Fkzh%2FbtsKn3jqvdV%2FKQ9My8EifbJVOluz66vv71%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1768&quot; height=&quot;2160&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1768&quot; data-origin-height=&quot;2160&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. HA-Proxy에서 Revese Proxy를 설정하기 위해 첫번째로 필요한 건 Real Servers에다가 내부 네트워크에 있는 Reverse Proxy 대상이 될 서비스의 주소를 등록하는 것이다. Services - HAProxy - Settings - Real Servers - Real Servers로 이동하여 새로운 서버를 등록해주도록 한다. 이 때, 중요한 세팅값은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Name or Prefix&lt;/b&gt;: 본인이 알아볼 수 있도록 해당 서버의 별칭을 지어주도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FQDN or IP&lt;/b&gt;: Reverse Proxy 대상이 될 서비스가 떠있는 서버의 내부 IP를 적어주도록 하자. (ex: 192.168.0.17)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Port&lt;/b&gt;: Reverse Proxy 대상이 될 서비스의 포트를 적어주도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SSL&lt;/b&gt;: 만약 HTTPS를 적용할 예정이라면 SSL을 체크해주도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Verify SSL Certificate&lt;/b&gt;: 만약 ACME Clients에서 관리가 되는 인증서거나 본인이 별도 CA 인증서 파일을 갖고 있다면 체크 후 SSL Verify CA에서 해당 CA를 지정해줘도 괜찮다. 하지만 귀찮거나 CA가 없는 경우에는 옵션을 체크해제 하여도 무방하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1766&quot; data-origin-height=&quot;1274&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/viwRO/btsKnFwwiYw/BMBV7aNMaecIbsJl51BhFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/viwRO/btsKnFwwiYw/BMBV7aNMaecIbsJl51BhFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/viwRO/btsKnFwwiYw/BMBV7aNMaecIbsJl51BhFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FviwRO%2FbtsKnFwwiYw%2FBMBV7aNMaecIbsJl51BhFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1766&quot; height=&quot;1274&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1766&quot; data-origin-height=&quot;1274&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 그 다음으로는 Services - HAProxy - Settings - Virtual Services - Backend Pools로 들어가 새로운 풀을 하나 생성해주도록 하자. 중요한 세팅값은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Name&lt;/b&gt;: 앞선 경우와 마찬가지로 본인이 알아볼 수 있도록 별칭을 하나 지어주도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Servers&lt;/b&gt;: 해당 Backend Pool에 연결될 Real Server들을 지정하도록 하자. 여러개 지정하면 Load-Balancing이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;X-Forwarded-For header&lt;/b&gt;: 리버스 프록시 후 원래 접근하려던 IP를 식별하기 위해선 체크해주도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;1228&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dJpwgp/btsKnSvGMlr/HT04jOwimHgYPojJ5IBojk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dJpwgp/btsKnSvGMlr/HT04jOwimHgYPojJ5IBojk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dJpwgp/btsKnSvGMlr/HT04jOwimHgYPojJ5IBojk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJpwgp%2FbtsKnSvGMlr%2FHT04jOwimHgYPojJ5IBojk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1772&quot; height=&quot;1228&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;1228&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Services - HAProxy - Settings - Rules &amp;amp; Checks - Conditions로 가서 새로운 Condition을 하나 생성하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때 Condition Type를 어떤거로 지정하느냐에 따라서 다양한 작업이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Host starts with / Host ends with / Host contains 등&lt;/b&gt;: subdomain 등 공통된 string이 포함된 주소를 묶어 관리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Host matches&lt;/b&gt;: 정확하게 매칭되는 Host만 지정하여 관리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Path starts with / Path ends with&lt;/b&gt; 등: 같은 호스트 내에서도 특정 경로만 지정하여 다른 서버로 보내고 싶을 때 사용한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1782&quot; data-origin-height=&quot;1652&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKPuPz/btsKm5JhZeX/cBuheIGsb5UNh1fWLvVcjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKPuPz/btsKm5JhZeX/cBuheIGsb5UNh1fWLvVcjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKPuPz/btsKm5JhZeX/cBuheIGsb5UNh1fWLvVcjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKPuPz%2FbtsKm5JhZeX%2FcBuheIGsb5UNh1fWLvVcjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1782&quot; height=&quot;1652&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1782&quot; data-origin-height=&quot;1652&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Services - HAProxy - Settings - Rules &amp;amp; Checks - Rules에서 새로운 Rule을 하나 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것 역시 Test Type이나 Logical operator for conditions는 본인의 시나리오에 맞게 사용하면 된다. Select conditions는 앞서 3에서 생성한 condition을 지정하고 Execute function을 Use specified Backend Pool로 지정 후 Use backend pool에서 앞서 2에서 생성한 backend pool을 지정한다면 해당 condition에 부합하는 모든 패킷들은 backend pool로 넘어간 다음 real server로 전달된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 HTTPS로 강제 리다이렉트를 시키는 동작을 원한다면 추가 Rule을 생성하여 Select conditions에는 해당하는 condition들을 지정한 다음 Logical operator for conditions에는 OR을 넣고 Execute function은 http-request-redirect로 지정 후 HTTP Redirect 파라미터에 scheme https code 301을 넣어주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;2030&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zwqkG/btsKmjhfJK2/n30WmAkJLyBUOtRY7uNLSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zwqkG/btsKmjhfJK2/n30WmAkJLyBUOtRY7uNLSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zwqkG/btsKmjhfJK2/n30WmAkJLyBUOtRY7uNLSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzwqkG%2FbtsKmjhfJK2%2Fn30WmAkJLyBUOtRY7uNLSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1772&quot; height=&quot;2030&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;2030&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1768&quot; data-origin-height=&quot;1566&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUVxT9/btsKnke7mUC/g0MNRzdQVYBBWRGk0YWvN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUVxT9/btsKnke7mUC/g0MNRzdQVYBBWRGk0YWvN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUVxT9/btsKnke7mUC/g0MNRzdQVYBBWRGk0YWvN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUVxT9%2FbtsKnke7mUC%2Fg0MNRzdQVYBBWRGk0YWvN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1768&quot; height=&quot;1566&quot; data-origin-width=&quot;1768&quot; data-origin-height=&quot;1566&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1774&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baqv1I/btsKl8mq48O/9ci5nKng2wyRMJ9tzadNkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baqv1I/btsKl8mq48O/9ci5nKng2wyRMJ9tzadNkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baqv1I/btsKl8mq48O/9ci5nKng2wyRMJ9tzadNkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbaqv1I%2FbtsKl8mq48O%2F9ci5nKng2wyRMJ9tzadNkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1774&quot; height=&quot;720&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1774&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Services - HAProxy - Settings - Virtual Services - Public Services 에서 새로운 Public Service를 두개 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나는 HTTPS용 하나는 HTTP용인데, 중요한 세팅값들은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Listen Addresses&lt;/b&gt;: (HTTPS의 경우) 0.0.0.0:443 / (HTTP의 경우) 0.0.0.0:80&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Enable SSL offloading&lt;/b&gt;: (HTTPS의 경우) 체크 / (HTTP의 경우) 체크 해제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Certificates&lt;/b&gt;: (HTTPS의 경우에만 필요한 SSL 인증서들 지정)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Cipher List&lt;/b&gt; 및 &lt;b&gt;Cipher Suites&lt;/b&gt;: (HTTPS의 경우에만 기본 설정 부분에 적힌 값을 그대로 넣어주자)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Enable HSTS&lt;/b&gt;: (HTTPS의 경우에만 선택)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Rules&lt;/b&gt;: 해당 Public Service와 관련되어 있는 룰들을 전부 선택해주도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;353&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCWA4E/btsKm4wNf5S/ReqFUmsnJcEqr0muSdq9fK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCWA4E/btsKm4wNf5S/ReqFUmsnJcEqr0muSdq9fK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCWA4E/btsKm4wNf5S/ReqFUmsnJcEqr0muSdq9fK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCWA4E%2FbtsKm4wNf5S%2FReqFUmsnJcEqr0muSdq9fK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2048&quot; height=&quot;353&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;353&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 마지막으로 Services - HAProxy - Settings -Settings - Service에서 Enable HAProxy를 체크해주면 완료다.&lt;/p&gt;</description>
      <category>프로그래밍|소프트웨어</category>
      <author>테크믈리에</author>
      <guid isPermaLink="true">https://korjwl1.tistory.com/39</guid>
      <comments>https://korjwl1.tistory.com/39#entry39comment</comments>
      <pubDate>Mon, 28 Oct 2024 21:39:16 +0900</pubDate>
    </item>
    <item>
      <title>K8S 환경에 CloudNativePG를 사용하여 PostgreSQL Cluster 구축하기</title>
      <link>https://korjwl1.tistory.com/38</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 서론 -&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;843&quot; data-origin-height=&quot;477&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D8oOd/btsKno9FA8J/vSYRXEKa25OBB9hbwV3sx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D8oOd/btsKno9FA8J/vSYRXEKa25OBB9hbwV3sx0/img.png&quot; data-alt=&quot;https://www.pgpool.net/docs/pgpool-II-4.3.1/en/html/example-kubernetes.html&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D8oOd/btsKno9FA8J/vSYRXEKa25OBB9hbwV3sx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD8oOd%2FbtsKno9FA8J%2FvSYRXEKa25OBB9hbwV3sx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;843&quot; height=&quot;477&quot; data-origin-width=&quot;843&quot; data-origin-height=&quot;477&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://www.pgpool.net/docs/pgpool-II-4.3.1/en/html/example-kubernetes.html&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kubernetes에 PostgreSQL 클러스터를 구축하는 방법은 몇가지가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 postgresql-ha 또는 postgresql cluster로 helm 차트 등을 검색하면 bitnami에서 제공하는 &lt;a href=&quot;https://artifacthub.io/packages/helm/bitnami/postgresql-ha&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;postgresql-ha&lt;/a&gt;가 나오는데, 해당 차트는 pgpool 미들웨어를 기반으로 High Availability를 제공할 수 있도록 구성된 차트이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 차트는 사용해보니 문제가 postgresql_conf 파일 수정이 번거로운데다가 잘 먹지 않는 값들도 있고 해서 안정적인 운용이 힘들었고, 부차적인 문제로 Reddit을 열심히 들여다보니 pgpool이라는 미들웨어를 통해 클러스터를 구축하기보다는 pgbouncer를 기반으로 k8s에 최적화된 CloudNativePG를 사용하는 것이 더 좋다고 하여 해당 방식으로 갈아타게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- CloudNativePG -&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1510&quot; data-origin-height=&quot;1095&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dL5Urc/btsKm5vEPC8/wDDXaYh0VnI07NnqEEJt2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dL5Urc/btsKm5vEPC8/wDDXaYh0VnI07NnqEEJt2k/img.png&quot; data-alt=&quot;https://cloudnative-pg.io/documentation/1.24/architecture/#deployments-across-kubernetes-clusters&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dL5Urc/btsKm5vEPC8/wDDXaYh0VnI07NnqEEJt2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdL5Urc%2FbtsKm5vEPC8%2FwDDXaYh0VnI07NnqEEJt2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1510&quot; height=&quot;1095&quot; data-origin-width=&quot;1510&quot; data-origin-height=&quot;1095&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://cloudnative-pg.io/documentation/1.24/architecture/#deployments-across-kubernetes-clusters&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;position: absolute;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CloudNativePG 공식 문서: &lt;a href=&quot;https://cloudnative-pg.io/documentation/1.24/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://cloudnative-pg.io/documentation/1.24/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1730111959261&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;CloudNativePG v1.24&quot; data-og-description=&quot;CloudNativePG CloudNativePG is an open-source operator designed to manage PostgreSQL workloads on any supported Kubernetes cluster. It supports deployment in private, public, hybrid, and multi-cloud environments, thanks to its distributed topology feature.&quot; data-og-host=&quot;cloudnative-pg.io&quot; data-og-source-url=&quot;https://cloudnative-pg.io/documentation/1.24/&quot; data-og-url=&quot;https://cloudnative-pg.io/documentation/1.24/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://cloudnative-pg.io/documentation/1.24/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cloudnative-pg.io/documentation/1.24/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;CloudNativePG v1.24&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CloudNativePG CloudNativePG is an open-source operator designed to manage PostgreSQL workloads on any supported Kubernetes cluster. It supports deployment in private, public, hybrid, and multi-cloud environments, thanks to its distributed topology feature.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;cloudnative-pg.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CloudNativePG 공식 GitHub: &lt;a href=&quot;https://github.com/cloudnative-pg/cloudnative-pg&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/cloudnative-pg/cloudnative-pg&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1730111981165&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - cloudnative-pg/cloudnative-pg: CloudNativePG is a comprehensive platform designed to seamlessly manage PostgreSQL datab&quot; data-og-description=&quot;CloudNativePG is a comprehensive platform designed to seamlessly manage PostgreSQL databases within Kubernetes environments, covering the entire operational lifecycle from initial deployment to ong...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/cloudnative-pg/cloudnative-pg&quot; data-og-url=&quot;https://github.com/cloudnative-pg/cloudnative-pg&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b8MfYR/hyXpqNbrT5/aBQrnUSqx7z5bRrEJsaAOK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/xj9zE/hyXps5h3tS/XKZJPnsrBoZfjydGqRoMkK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/cloudnative-pg/cloudnative-pg&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/cloudnative-pg/cloudnative-pg&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b8MfYR/hyXpqNbrT5/aBQrnUSqx7z5bRrEJsaAOK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/xj9zE/hyXps5h3tS/XKZJPnsrBoZfjydGqRoMkK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - cloudnative-pg/cloudnative-pg: CloudNativePG is a comprehensive platform designed to seamlessly manage PostgreSQL datab&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CloudNativePG is a comprehensive platform designed to seamlessly manage PostgreSQL databases within Kubernetes environments, covering the entire operational lifecycle from initial deployment to ong...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CloudNativePG는 Kubernetes 클러스터 상에서 PostgreSQL을 보다 더 쉽게 관리할 수 있게 만들어진 Operator로 PostgreSQL DB들을 관리하고 Pooling Layer를 PgBouncer 기반으로 관리하며 부가 기능으로 Failover, Security, Replication 등을 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 소개한 Bitnami와 비교하자면, Bitnami의 차트는 단순히 PgPool 및 PostgreSQL을 컨테이너화한 다음 묶어서 제공할 뿐인 느낌이라 PostgreSQL 및 PgPool 관련 설정들도 단순히 value.yaml 등으로 적용하는게 쉽지 않아 전체 postgresql.conf 파일을 하나의 ConfigMap에 담아 적용하여 강제로 덮어써지도록 해야했지만 CloudNative는 간단한게 postgresql.cnpg.io/v1의 Cluster 똑는 Pooler kind 등 Operator에서 제공하는 형식의 yaml 파일을 작성하여 적용만 하면 된다는 점에서 매우 K8S 지향적이라는 생각이 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 백업과 같은 것도 별도로 velero 같은 것을 사용하거나 PostgreSQL의 전통적인 백업 방법을 사용할 필요 없이 yaml 파일 하나만으로 스케쥴화해서 진행할 수 있다는 것도 큰 매력이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 설치 -&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 간단하게 cluster 및 pooler를 원하는 대로 설정하여 동작 확인을 하는 것까지만 소개할 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세한 나머지 세팅은 공식 문서에 매우 잘 나와있으니 참조하도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, CloudNativePG를 사용하기 위해서는 Operator부터 설치해야한다.&lt;/p&gt;
&lt;pre id=&quot;code_1730112507048&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl apply --server-side -f \
  https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.24/releases/cnpg-1.24.1.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2796&quot; data-origin-height=&quot;264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OyE9l/btsKnUfQ7Qs/EX2Vkr2eGEc5K74G5uFdyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OyE9l/btsKnUfQ7Qs/EX2Vkr2eGEc5K74G5uFdyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OyE9l/btsKnUfQ7Qs/EX2Vkr2eGEc5K74G5uFdyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOyE9l%2FbtsKnUfQ7Qs%2FEX2Vkr2eGEc5K74G5uFdyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2796&quot; height=&quot;264&quot; data-origin-width=&quot;2796&quot; data-origin-height=&quot;264&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치하고 나면 cnpg-system이라는 namespace가 생성되며, 그 아래에 cnpg-controller-manager가 떠있는 모습을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 클러스터를 구축해보도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 코드는 본인이 사용한 &lt;b&gt;cluster.yaml&lt;/b&gt; 파일로 본인의 환경에 맞게 수정하여 사용하도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 이전에 작성한 Elasticsearch 클러스터 구축 때와 마찬가지로 PostgreSQL 역시 저장소 I/O속도가 중요하며 자체적으로 Replica를 생성하기 때문에 Rook Ceph같은 분산 스토리지보다는 OpenEBS LocalPV 같은 저장소를 추천한다.&lt;/p&gt;
&lt;pre id=&quot;code_1730112846058&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: postgre-cluster
  namespace: cnpg-cluster
spec:
  imageName: ghcr.io/cloudnative-pg/postgresql:16.3-10
  instances: 3
  startDelay: 300
  stopDelay: 300

#  affinity:
#    nodeAffinity:
#      requiredDuringSchedulingIgnoredDuringExecution:
#        nodeSelectorTerms:
#          - matchExpressions:
#            - key: postgre
#              operator: Exists

  storage:
    size: 340Gi
    storageClass: &amp;lt;본인이 사용할 storageClass&amp;gt;
    
  walStorage:
    size: 45Gi
    storageClass: &amp;lt;본인이 사용할 storageClass&amp;gt;

  postgresql:
    parameters:
      shared_buffers: 1GB
      maintenance_work_mem: 256MB
      wal_level: 'logical'
      log_timezone: 'Asia/Seoul'
    pg_hba:
      - host all postgres all trust

  resources:
    requests:
      cpu: 2
      memory: 4Gi
    limits:
      cpu: 2
      memory: 4Gi
  
  # Rolling Update 관련 - https://cloudnative-pg.io/documentation/preview/rolling_update/
  primaryUpdateStrategy: unsupervised

  enableSuperuserAccess: true
  
  # Grafana등 관련
  monitoring:
    enablePodMonitor: true

  # 계정 관련
  managed:
    roles:
    - name: myaccount
      ensure: present
      login: true
      superuser: true
      passwordSecret:
        name: cnpg-user-myaccount

---
apiVersion: v1
kind: Secret
data:
  username: &amp;lt;base64 인코딩된 본인이 사용할 계정&amp;gt;
  password: &amp;lt;base64 인코딩된 본인이 사용할 비밀번호&amp;gt;
metadata:
  name: cnpg-user-myaccount
  namespace: cnpg-cluster
  labels:
    cnpg.io/reload: &quot;true&quot;
type: kubernetes.io/basic-auth&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 작성이 끝났다면 아래 명령어로 해당 파일을 적용하도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1730113080246&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl apply -f cluster.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 생성된 클러스터에 외부에서 접근할 수 있도록 하기 위해서는 pooler 설정이 필수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 본인이 사용한 &lt;b&gt;pooler.yaml&lt;/b&gt; 파일로 본인의 환경에 맞게 수정하여 사용하도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1730113155910&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apiVersion: postgresql.cnpg.io/v1
kind: Pooler
metadata:
  name: cnpg-pgbouncer
  namespace: cnpg-cluster
spec:
  cluster:
    name: postgre-cluster
  instances: 3
  type: rw

  template:
    spec:
      containers: []
#      affinity:
#        nodeAffinity:
#          requiredDuringSchedulingIgnoredDuringExecution:
#            nodeSelectorTerms:
#              - matchExpressions:
#                - key: postgre
#                  operator: Exists
  
  serviceTemplate:
    metadata:
      labels:
        app: pooler
    spec:
      type: LoadBalancer
      loadBalancerIP: &quot;&quot;

  pgbouncer:
    poolMode: session
    parameters:
      max_client_conn: &quot;100&quot;
      default_pool_size: &quot;10&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로 kubectl apply -f를 통하여 파일을 적용하도록 하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2788&quot; data-origin-height=&quot;606&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z4lAb/btsKnV6UeOp/x46I14Dpl7Gj7xfftoAnek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z4lAb/btsKnV6UeOp/x46I14Dpl7Gj7xfftoAnek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z4lAb/btsKnV6UeOp/x46I14Dpl7Gj7xfftoAnek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ4lAb%2FbtsKnV6UeOp%2Fx46I14Dpl7Gj7xfftoAnek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2788&quot; height=&quot;606&quot; data-origin-width=&quot;2788&quot; data-origin-height=&quot;606&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성공적으로 끝냈다면 위와 같이 postgre-cluster들과 cnpg-pgbouncer들이 cnpg-cluster namespace에 생성된 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍|소프트웨어</category>
      <author>테크믈리에</author>
      <guid isPermaLink="true">https://korjwl1.tistory.com/38</guid>
      <comments>https://korjwl1.tistory.com/38#entry38comment</comments>
      <pubDate>Mon, 28 Oct 2024 20:00:35 +0900</pubDate>
    </item>
    <item>
      <title>K8S 환경에 ElasticSearch Cluster 구축하기</title>
      <link>https://korjwl1.tistory.com/37</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 서론 -&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 K8S 환경에서 ElasticSearch Cluster를 구축하기 위한 방법에 관하여 알아볼 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 현재 일하고 있는 스타트업 내의 제한적인 컴퓨팅 리소스 내에서 PostgreSQL 클러스터, Redis 클러스터와 함께 ElasticSearch 클러스터를 올려놓았으며, 이 글은 해당 과정 중 본인이 한 작업을 순서대로 정리한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;K8S 클러스터 내에 노드들이 더 있긴 하지만 이번에 회사에서 작업한 내용 중 간단하게 ElasticSearch Cluster와 연관된 노드들만 정리하자면 아래와 같이 정리할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;그림1.png&quot; data-origin-width=&quot;1987&quot; data-origin-height=&quot;554&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bL19Dc/btsKjpVPgpk/mNUCmPfwHmwJWLAjRKSwK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bL19Dc/btsKjpVPgpk/mNUCmPfwHmwJWLAjRKSwK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bL19Dc/btsKjpVPgpk/mNUCmPfwHmwJWLAjRKSwK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbL19Dc%2FbtsKjpVPgpk%2FmNUCmPfwHmwJWLAjRKSwK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1987&quot; height=&quot;554&quot; data-filename=&quot;그림1.png&quot; data-origin-width=&quot;1987&quot; data-origin-height=&quot;554&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 이 글을 읽을 정도면 ES cluster에 관한 지식이 이미 있겠지만 간단하게 구성 요소를 설명하자면 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Master 노드: 클러스터 상태 관리와 관련된 작업을 수행하며 저장소에는 클러스터 메타데이터, 스냅샷 메타데이터, 클러스터 설정, 노드 및 샤드 정보 등을 담고 있다. 적당한 양의 vCPU와 메모리, 50GB~100GB의 저장소가 권장된다. 고가용성을 위해서 3개를 띄우는 것을 권장한다.&lt;/li&gt;
&lt;li&gt;Ingest 노드: Data 노드에 데이터가 들어가기 전에 전처리를 하기 위해 있는 노드로 임시 데이터 처리, 파이프라인 및 스크립트 캐싱, 에러 및 실패 로그 등을 담기 위하여 저장소를 활용한다. 많은 양의 vCPU와 메모리, 100GB~200GB의 빠른 속도의 저장소가 권장된다.&lt;/li&gt;
&lt;li&gt;Data 노드: 실제로 데이터가 저장되는 노드로 매우 많은 양의 메모리와 빠른 속도의 저장소가 권장된다. 메모리는 32GB 이상이 적당하다. 마찬가지로 고가용성을 위해 3개 이상을 띄우는 것을 권장한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 요구 사항에 맞출 수 있도록 각 노드의 여유 자원을 계산하여 본인은 Master, Ingest, Data 노드를 여러 노드에 위 그림과 할당하여 두었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ElasticSearch의 경우, 클러스터 구성을 할 시 기본적으로 Data 노드들은 자체적으로 고가용성을 위하여 분산 저장을 하도록 되어 있다. 때문에 ES Cluster를 위해서는 Rook CEPH 같은 분산 저장 스토리지를 사용하는 것이 아닌 OpenEBS LocalPV와 같은 저장소를 사용하는 것이 속도, 안전성 면에서 유리하다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 사전 준비 -&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 K8S 환경에 ES Cluster를 올리고 사용하기 위해서는 다음과 같은 사전 준비가 필요하다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;K8S Storage 준비 (OpenEBS LocalPV 권장)&lt;/li&gt;
&lt;li&gt;ElasticSearch Certificate 발급 (각 구성 요소간 성공적 통신 및 외부 접근을 위하여 필수)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 중 1번의 경우, 이 블로그에도 정리되어 있으니 참고하도록하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인증서 발급의 경우, 이 글에서는 ElasticSearch에서 제공하는 CertUtil을 활용하여 인증서 발급하는 방법을 사용해볼 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1729841498052&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Elasticsearch 도커 컨테이너 실행
sudo docker run --name elastic-certs -it -w --rm \
       /tmp docker.elastic.co/elasticsearch/elasticsearch:8.5.1 \
       /bin/sh
       
# 도커 컨테이너 내에서 명령 실행
# --pass의 경우 본인이 원하는 것을 지정하거나 혹은 비밀번호 없이 진행하려면 ''을 입력
# --ca-pass의 경우도 마찬가지
elasticsearch-certutil ca --out /tmp/elastic-stack-ca.p12 --pass ''

elasticsearch-certutil cert --name security-master \
    --dns elasticsearch-master,elasticsearch-master.elasticsearch.svc.cluster.local,es.s-core.ai \
    --ca /tmp/elastic-stack-ca.p12 \
    --pass '' --ca-pass '' --out /tmp/elastic-certificates.p12
    
# Ctrl P+Q로 컨테이너 밖으로 나간 다음 작업
sudo docker cp elastic-certs:/tmp/elastic-certificates.p12 ./
sudo docker stop elastic-certs

# OpenSSL 필요
sudo openssl pkcs12 -nodes -passin pass:'' -in elastic-certificates.p12 -out elastic-certificate.pem
sudo openssl x509 -outform der -in elastic-certificate.pem -out elastic-certificate.crt&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- ES Cluster 구축하기 -&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선은 앞서 생성한 Certificate들을 필요한 Namespace들에 등록해주도록 하자. (elasticsearch namespace는 필수)&lt;/p&gt;
&lt;pre id=&quot;code_1729841704587&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# ES Cluster를 위한 Namespace 생성
kubectl create namespace elasticsearch

# Namespace만 바꿔가며 아래 작업을 필요한만큼 반복하자
sudo kubectl create secret generic elastic-certificates -n elasticsearch --from-file elastic-certificates.p12
sudo kubectl create secret generic elastic-certificate-pem -n elasticsearch --from-file=elastic-certificate.pem
sudo kubectl create secret generic elastic-certificate-crt -n elasticsearch --from-file=elastic-certificate.crt&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음에는 Elastic operator를 올려주도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1729841931358&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;helm repo add elastic https://helm.elastic.co
helm repo update

helm install elastic-operator elastic/eck-operator -n elasticsearch --create-namespace&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제는 Master와 Ingest, Data를 올리기 위해 본인의 상황에 맞춰서 yaml파일 3개 작성해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세한 내용은 공식 문서를 참조하도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://artifacthub.io/packages/helm/elastic/elasticsearch&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://artifacthub.io/packages/helm/elastic/elasticsearch&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1729842113320&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;elasticsearch 8.5.1 &amp;middot; elastic/elastic&quot; data-og-description=&quot;Official Elastic helm chart for Elasticsearch&quot; data-og-host=&quot;artifacthub.io&quot; data-og-source-url=&quot;https://artifacthub.io/packages/helm/elastic/elasticsearch&quot; data-og-url=&quot;https://artifacthub.io/packages/helm/elastic/elasticsearch&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/q93YK/hyXlKspPSs/x0mieY4j0JPAqvgkUIBfh1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://artifacthub.io/packages/helm/elastic/elasticsearch&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://artifacthub.io/packages/helm/elastic/elasticsearch&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/q93YK/hyXlKspPSs/x0mieY4j0JPAqvgkUIBfh1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;elasticsearch 8.5.1 &amp;middot; elastic/elastic&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Official Elastic helm chart for Elasticsearch&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;artifacthub.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 본인이 사용한 예시이다.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;master.yaml&quot; data-text-less=&quot;master.yaml&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1729842409514&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;---
# 마스터 그룹 설정
clusterName: &quot;elasticsearch&quot;
nodeGroup: &quot;master&quot;

# The service that non master groups will try to connect to when joining the cluster
# This should be set to clusterName + &quot;-&quot; + nodeGroup for your master group
masterService: &quot;&quot;

createCert: false

roles:
  - master

replicas: 3
minimumMasterNodes: 1
clusterHealthCheckParams: 'wait_for_status=yellow&amp;amp;timeout=1s'

# Disable it to use your own elastic-credential Secret.
secret:
  enabled: true
  password: &quot;본인이 사용할 비밀번호&quot; # generated randomly if not defined

image: &quot;docker.elastic.co/elasticsearch/elasticsearch&quot;
imageTag: &quot;8.5.1&quot;
imagePullPolicy: &quot;IfNotPresent&quot;

esJavaOpts: &quot;-Des.allow_insecure_settings=true&quot; # example: &quot;-Xmx1g -Xms1g&quot;

# CORS 오류 관련 설정
esConfig:
  elasticsearch.yml: |
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.http.ssl.enabled: true
    xpack.security.http.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    http.cors.allow-origin: &quot;*&quot; # Only use unrestricted value for local development
    http.cors.enabled: true
    http.cors.allow-credentials: true
    http.cors.allow-methods: GET, POST, DELETE
    http.cors.allow-headers: X-Requested-With, X-Auth-Token, Content-Type, Content-Length

secretMounts:
  - name: elastic-certificates
    secretName: elastic-certificates
    path: /usr/share/elasticsearch/config/certs

# resources:
#   requests:
#     cpu: 
#     memory: 
#   limits:
#     cpu: 
#     memory:

volumeClaimTemplate:
  accessModes: [&quot;ReadWriteOnce&quot;]
  storageClassName: &quot;본인이 사용할 저장소 이름&quot;
  resources:
    requests:
      storage: 50Gi

persistence:
  enabled: true
  labels:
    # Add default labels for the volumeClaimTemplate of the StatefulSet
    enabled: false
  annotations: {}

# This is the node affinity settings as defined in
# https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity-beta-feature
# nodeAffinity: 
#   requiredDuringSchedulingIgnoredDuringExecution:
#     nodeSelectorTerms:
#       - matchExpressions:
#         - key: esmaster
#           operator: Exists

service:
  enabled: true
  labels: {}
  labelsHeadless: {}
#   type: LoadBalancer
  # Consider that all endpoints are considered &quot;ready&quot; even if the Pods themselves are not
  # https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec
  publishNotReadyAddresses: false
#   nodePort: &quot;31300&quot;
#   loadBalancerIP: &quot;&quot;
#   annotations:
#     metallb.universe.tf/allow-shared-ip: &quot;elasticsearch&quot;
  httpPortName: http
  transportPortName: transport
  loadBalancerSourceRanges: []
  externalTrafficPolicy: &quot;&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;ingest.yaml&quot; data-text-less=&quot;ingest.yaml&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1729842528073&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;---
# Ingest 그룹 설정
clusterName: &quot;elasticsearch&quot;
nodeGroup: &quot;ingest&quot;

# The service that non master groups will try to connect to when joining the cluster
# This should be set to clusterName + &quot;-&quot; + nodeGroup for your master group
masterService: &quot;elasticsearch-master&quot;

createCert: false

roles:
  - ingest

replicas: 2
minimumMasterNodes: 1
clusterHealthCheckParams: 'wait_for_status=yellow&amp;amp;timeout=1s'

# Disable it to use your own elastic-credential Secret.
secret:
  enabled: true
  password: &quot;본인이 사용할 비밀번호&quot; # generated randomly if not defined

image: &quot;docker.elastic.co/elasticsearch/elasticsearch&quot;
imageTag: &quot;8.5.1&quot;
imagePullPolicy: &quot;IfNotPresent&quot;

esJavaOpts: &quot;-Des.allow_insecure_settings=true&quot; # example: &quot;-Xmx1g -Xms1g&quot;

esConfig:
  elasticsearch.yml: |
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.http.ssl.enabled: true
    xpack.security.http.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    http.cors.allow-origin: &quot;*&quot; # Only use unrestricted value for local development
    http.cors.enabled: true
    http.cors.allow-credentials: true
    http.cors.allow-methods: GET, POST, DELETE
    http.cors.allow-headers: X-Requested-With, X-Auth-Token, Content-Type, Content-Length

secretMounts:
  - name: elastic-certificates
    secretName: elastic-certificates
    path: /usr/share/elasticsearch/config/certs

# resources:
#   requests:
#     cpu: 
#     memory: 
#   limits:
#     cpu: 
#     memory:

volumeClaimTemplate:
  accessModes: [&quot;ReadWriteOnce&quot;]
  storageClassName: &quot;본인이 사용할 저장소&quot;
  resources:
    requests:
      storage: 100Gi

persistence:
  enabled: true
  labels:
    # Add default labels for the volumeClaimTemplate of the StatefulSet
    enabled: false
  annotations: {}

protocol: https

# This is the node affinity settings as defined in
# https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity-beta-feature
# nodeAffinity:
#   requiredDuringSchedulingIgnoredDuringExecution:
#     nodeSelectorTerms:
#       - matchExpressions:
#         - key: esingest
#          operator: Exists&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;data.yaml&quot; data-text-less=&quot;data.yaml&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1729842602774&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;---
# 데이터 그룹 설정
clusterName: &quot;elasticsearch&quot;
nodeGroup: &quot;data&quot;

# The service that non master groups will try to connect to when joining the cluster
# This should be set to clusterName + &quot;-&quot; + nodeGroup for your master group
masterService: &quot;elasticsearch-master&quot;

createCert: false

roles:
  - data

replicas: 3
minimumMasterNodes: 1
clusterHealthCheckParams: 'wait_for_status=yellow&amp;amp;timeout=1s'

# Disable it to use your own elastic-credential Secret.
secret:
  enabled: true
  password: &quot;본인이 사용할 비밀번호&quot; # generated randomly if not defined

esConfig:
  elasticsearch.yml: |
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.http.ssl.enabled: true
    xpack.security.http.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    http.cors.allow-origin: &quot;*&quot; # Only use unrestricted value for local development
    http.cors.enabled: true
    http.cors.allow-credentials: true
    http.cors.allow-methods: GET, POST, DELETE
    http.cors.allow-headers: X-Requested-With, X-Auth-Token, Content-Type, Content-Length

secretMounts:
  - name: elastic-certificates
    secretName: elastic-certificates
    path: /usr/share/elasticsearch/config/certs

image: &quot;docker.elastic.co/elasticsearch/elasticsearch&quot;
imageTag: &quot;8.5.1&quot;
imagePullPolicy: &quot;IfNotPresent&quot;

esJavaOpts: &quot;-Des.allow_insecure_settings=true&quot; # example: &quot;-Xmx1g -Xms1g&quot;

# resources:
#   requests:
#     cpu: 
#     memory: 
#   limits:
#     cpu: 
#     memory: 

volumeClaimTemplate:
  accessModes: [&quot;ReadWriteOnce&quot;]
  storageClassName: &quot;본인이 사용할 저장소&quot;
  resources:
    requests:
      storage: 300Gi

persistence:
  enabled: true
  labels:
    # Add default labels for the volumeClaimTemplate of the StatefulSet
    enabled: false
  annotations: {}

protocol: https

# This is the node affinity settings as defined in
# https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity-beta-feature
# nodeAffinity:
#   requiredDuringSchedulingIgnoredDuringExecution:
#     nodeSelectorTerms:
#       - matchExpressions:
#         - key: esdata
#           operator: Exists&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예시 파일들의 경우 원하는 노드에 띄우기 위하여 Node Affinity를 사용했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인만의 파일 작성이 끝났다면 다음 명령어를 순차적으로 실행하여주도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1729842670471&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;helm install esmaster elastic/elasticsearch -f master.yaml -n elasticsearch
helm install esdata elastic/elasticsearch -f data.yaml -n elasticsearch
helm install esingest elastic/elasticsearch -f ingest.yaml -n elasticsearch&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2786&quot; data-origin-height=&quot;614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/obYx0/btsKjZimxmE/BglY4OjPxjQ5iR29GHrbeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/obYx0/btsKjZimxmE/BglY4OjPxjQ5iR29GHrbeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/obYx0/btsKjZimxmE/BglY4OjPxjQ5iR29GHrbeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FobYx0%2FbtsKjZimxmE%2FBglY4OjPxjQ5iR29GHrbeK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2786&quot; height=&quot;614&quot; data-origin-width=&quot;2786&quot; data-origin-height=&quot;614&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성공적으로 여기까지 진행했다면 위와 같이 모든 Pod들이 정상 실행되있는 것을 1~2분 후에 확인할 수 있을 것이다.&lt;/p&gt;</description>
      <category>프로그래밍|소프트웨어/ElasticSearch</category>
      <author>테크믈리에</author>
      <guid isPermaLink="true">https://korjwl1.tistory.com/37</guid>
      <comments>https://korjwl1.tistory.com/37#entry37comment</comments>
      <pubDate>Fri, 25 Oct 2024 16:52:55 +0900</pubDate>
    </item>
    <item>
      <title>Talos Linux를 통한 간편한 Production Level K8S 환경 구축하기 - 2 -</title>
      <link>https://korjwl1.tistory.com/36</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 편에서는 Talos Linux 설치 후 추가적으로 해줘야하거나 해주면 좋은 설정들 등에 관하여 알아볼 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;b&gt;1. Pod Security 해결법&lt;/b&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.talos.dev/v1.7/kubernetes-guides/configuration/pod-security/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.talos.dev/v1.7/kubernetes-guides/configuration/pod-security/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1724116577111&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Pod Security&quot; data-og-description=&quot;Enabling Pod Security Admission plugin to configure Pod Security Standards.&quot; data-og-host=&quot;www.talos.dev&quot; data-og-source-url=&quot;https://www.talos.dev/v1.7/kubernetes-guides/configuration/pod-security/&quot; data-og-url=&quot;https://www.talos.dev/v1.7/kubernetes-guides/configuration/pod-security/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dQbQxN/hyWOiDC0Mn/qd0gdZRiumtlkdPkK4lkp0/img.png?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260&quot;&gt;&lt;a href=&quot;https://www.talos.dev/v1.7/kubernetes-guides/configuration/pod-security/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.talos.dev/v1.7/kubernetes-guides/configuration/pod-security/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dQbQxN/hyWOiDC0Mn/qd0gdZRiumtlkdPkK4lkp0/img.png?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Pod Security&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Enabling Pod Security Admission plugin to configure Pod Security Standards.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.talos.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Talos Linux의 Pod Security 관련해서 자세한 내용은 위의 내용을 참고하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 특정 namespace에서 pod security를 해제하고 싶다 아래 명령어를 입력하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1724116715486&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl label ns &amp;lt;Namespace 이름&amp;gt; pod-security.kubernetes.io/enforce=privileged&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여전히 Pod Security관련 Warning은 뜨겠지만 문제없이 정상 동작하는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;b&gt;2. Metrics Server 활성화 시 발생하는 TLS 오류 해결법&lt;/b&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Metrics Server를 사용하기 위해 rotate-server-certificates 옵션을 준 경우, 각 노드의 대시보드에서 계속하여 certificate/tls 관련 오류가 나타나는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 간단하게 아래 명령어 한 줄로 해결이 가능하다.&lt;/p&gt;
&lt;pre id=&quot;code_1724116807388&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl get csr -o name | xargs kubectl certificate approve&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1032&quot; data-origin-height=&quot;284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUM8Rv/btsI7khRffe/ils7WR7UgwsYLeEJm3efo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUM8Rv/btsI7khRffe/ils7WR7UgwsYLeEJm3efo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUM8Rv/btsI7khRffe/ils7WR7UgwsYLeEJm3efo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUM8Rv%2FbtsI7khRffe%2Fils7WR7UgwsYLeEJm3efo1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1032&quot; height=&quot;284&quot; data-origin-width=&quot;1032&quot; data-origin-height=&quot;284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;b&gt;3. Nvidia Driver 활성화 방법&lt;/b&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;a href=&quot;https://www.talos.dev/v1.7/talos-guides/configuration/nvidia-gpu-proprietary/&quot;&gt;https://www.talos.dev/v1.7/talos-guides/configuration/nvidia-gpu-proprietary/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1724117064734&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;NVIDIA GPU (Proprietary drivers)&quot; data-og-description=&quot;In this guide we'll follow the procedure to support NVIDIA GPU using proprietary drivers on Talos.&quot; data-og-host=&quot;www.talos.dev&quot; data-og-source-url=&quot;https://www.talos.dev/v1.7/talos-guides/configuration/nvidia-gpu-proprietary/&quot; data-og-url=&quot;https://www.talos.dev/v1.7/talos-guides/configuration/nvidia-gpu-proprietary/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.talos.dev/v1.7/talos-guides/configuration/nvidia-gpu-proprietary/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.talos.dev/v1.7/talos-guides/configuration/nvidia-gpu-proprietary/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;NVIDIA GPU (Proprietary drivers)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;In this guide we'll follow the procedure to support NVIDIA GPU using proprietary drivers on Talos.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.talos.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞선 글에서 간단히 언급한 내용을 따라 Image Factory에서 Nvidia 드라이버가 추가된 Talos Linux 이미지를 생성하고, 이를 설치하였다면 반드시 아래 과정을 통해 Nvidia driver container를 활성화해야만 해당 노드가 Ready 상태로 돌입할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 아래 스크린샷과 같이 get extensions 명령어와 read /proc/driver/nvidia/version 명령어를 사용하여 해당 노드에 nvidia 드라이버 및 container toolkit이 설치되었는지, 또 어떤 버전의 드라이버가 설치되었는지 등의 여부를 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;253&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnBftJ/btsI7sNydVF/d5FKcCKFooaQ1K8RA8OaE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnBftJ/btsI7sNydVF/d5FKcCKFooaQ1K8RA8OaE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnBftJ/btsI7sNydVF/d5FKcCKFooaQ1K8RA8OaE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnBftJ%2FbtsI7sNydVF%2Fd5FKcCKFooaQ1K8RA8OaE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;253&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;253&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Nvidia driver는 Proprietary drivers를 선택했다고 할 때 관리자 컴퓨터에 다음과 같은 파일들을 생성하여 저장하도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(주석은 파일 이름을 지정하는 것이니 주석을 제외하고 파일로 넣어주면 된다.)&lt;/p&gt;
&lt;pre id=&quot;code_1724117110881&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# nvidia_patch.yaml

machine:
  kernel:
    modules:
      - name: nvidia
      - name: nvidia_uvm
      - name: nvidia_drm
      - name: nvidia_modeset
  sysctls:
    net.core.bpf_jit_harden: 1&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1724117130803&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# nvidia_runtime_patch.yaml

- op: add
  path: /machine/files
  value:
    - content: |
        [plugins]
          [plugins.&quot;io.containerd.grpc.v1.cri&quot;]
            [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd]
              default_runtime_name = &quot;nvidia&quot;        
      path: /etc/cri/conf.d/20-customization.part
      op: create&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1724117165186&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# nvidia_runtime_class.yaml

---
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: nvidia
handler: nvidia&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음, 다음 명령어를 사용하여 각 패치들을 적용하고 K8S에 Nvidia runtime을 생성하여주도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1724117315890&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Nvidia 모듈 활성화
# 이 명령어는 Reboot없이 적용되며, 적용된 이후 해당 노드는 바로 Ready상태로 돌입할 것이다.
talosctl patch mc --patch @nvidia_patch.yaml -n &amp;lt;적용할 노드 IP&amp;gt; -e &amp;lt;control node IP&amp;gt; --talosconfig=&amp;lt;본인 talosconfig경로&amp;gt;

# Nvidia Runtime을 기본으로 지정
# 이 명령어는 Reboot을 수반한다.
talosctl patch mc --patch @nvidia_runtime_patch.yaml -n &amp;lt;적용할 노드 IP&amp;gt; -e &amp;lt;control node IP&amp;gt; --talosconfig=&amp;lt;본인 talosconfig경로&amp;gt;

# Nvidia Runtime Class추가
kubectl apply -f nvidia_runtime_class.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로, 각 노드들에 올라갈 Pod에서 Nvidia GPU를 사용하기 위해서는 GPU-Operator가 올라가야만 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1724117464563&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl create namespace nvdp
kubectl label ns nvdp pod-security.kubernetes.io/enforce=privileged
helm install nvidia-device-plugin nvdp/nvidia-device-plugin --version=0.13.0 --namespace nvdp --set=runtimeClassName=nvidia --set gfd.enabled=true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어는 GPU operator와 NFD를 같이 올려준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;601&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGRzHG/btsI8i4EOhQ/Vjvq84I2gAgVS7CINPo3d1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGRzHG/btsI8i4EOhQ/Vjvq84I2gAgVS7CINPo3d1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGRzHG/btsI8i4EOhQ/Vjvq84I2gAgVS7CINPo3d1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGRzHG%2FbtsI8i4EOhQ%2FVjvq84I2gAgVS7CINPo3d1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;601&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;601&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;728&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tG9hN/btsI8qajDGP/McgqsW7Z73Soy6kAWfWbEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tG9hN/btsI8qajDGP/McgqsW7Z73Soy6kAWfWbEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tG9hN/btsI8qajDGP/McgqsW7Z73Soy6kAWfWbEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtG9hN%2FbtsI8qajDGP%2FMcgqsW7Z73Soy6kAWfWbEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;728&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;728&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;606&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9Jzec/btsI7GLFurN/7cScY6MVMsU1APKBynMi1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9Jzec/btsI7GLFurN/7cScY6MVMsU1APKBynMi1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9Jzec/btsI7GLFurN/7cScY6MVMsU1APKBynMi1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9Jzec%2FbtsI7GLFurN%2F7cScY6MVMsU1APKBynMi1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;606&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;606&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성공적으로 올라갔다면 위의 사진들과 같이 Pod들이 정상적으로 올라가고 Node Labeling도 정상적으로 되며 실행한 Pod 내에서 Nvidia 명령어가 잘 동작하는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;b&gt;4. Ephemeral Storage 추가 방법&lt;/b&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.talos.dev/v1.7/kubernetes-guides/configuration/local-storage/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.talos.dev/v1.7/kubernetes-guides/configuration/local-storage/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1724118065234&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Local Storage&quot; data-og-description=&quot;Using local storage for Kubernetes workloads.&quot; data-og-host=&quot;www.talos.dev&quot; data-og-source-url=&quot;https://www.talos.dev/v1.7/kubernetes-guides/configuration/local-storage/&quot; data-og-url=&quot;https://www.talos.dev/v1.7/kubernetes-guides/configuration/local-storage/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/gvrwg/hyWOk9hxym/7iEEv7dCATJFhIJ10TPUpk/img.png?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260&quot;&gt;&lt;a href=&quot;https://www.talos.dev/v1.7/kubernetes-guides/configuration/local-storage/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.talos.dev/v1.7/kubernetes-guides/configuration/local-storage/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/gvrwg/hyWOk9hxym/7iEEv7dCATJFhIJ10TPUpk/img.png?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Local Storage&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Using local storage for Kubernetes workloads.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.talos.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Talos Linux에서 추가 저장장치를 사용할 수 있는 방법은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. OpenEBS Local Device나 Rook Ceph와 같이 파티션이 없는 디스크를 갖고 Block 스토리지 기술을 사용하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. /var 아래에 디스크를 마운트하여 Longhorn이나 OpenEBS Local Hostpath와 같은 스토리지를 운영하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때, /var 경로를 Ephemeral Storage라고 부르고 Talos Linux는 외장 디스크를 마운트할 수 있는 위치로 Ephemeral Storage만을 허용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로는 반드시 Longhorn을 사용하여야 한다 등의 이유가 있는 것이 아니라면 1번의 방법을 통해 스토리지를 구축하는 것을 강력 추천한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Talos Linux는 위의 Local Storage 문서에서도 볼 수 있는 것처럼 클러스터를 업그레이드 하는 경우 --preserve 옵션을 빼먹게 된다면 자동으로 Ephemeral 영역을 초기화하기 때문에 데이터를 전부 잃어버릴 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 추후 설명하겠지만, Talos Linux에서 추가 저장 장치를 사용할 때 Node Config를 직접 수정, 혹은 Patch를 통해서 저장 장치 경로를 지정하고 파티션을 지정하여 해당 저장 장치를 포맷한 다음 지정된 경로에 마운트하는 방식을 취한다. 근데 이게 일회성이 아니라 노드 재실행 시마다 해당 Config를 기반으로 저장 장치를 재포맷하려고 하는데, 이 때문에 만약 USB나 추가 HDD/SSD 등이 연결되어 저장 장치의 경로가 바뀐다면 의도하지 않은 저장 장치의 포맷이 발생할 수 있고, 혹은 이미 존재하는 파티션 레이블로 인하여 OS에서 지속적인 에러가 발생할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 그리고 개인적인 경험으로는 OpenEBS Local Hostpath를 기반으로 노드를 굴리다가 아래와 같은 Ephemeral partition 오류를 겪은적이 있다. 이 때, debug container를 띄워 확인해본 바로는 정상적으로 추가 저장 장치가 마운트가 되긴 하였으나 아마 모종의 이유로 OpenEBS와 해당 저장 장치가 정상적으로 연결이 되지 않고 Talos Linux가 설치된 저장 장치의 /var 영역으로 침범하게 된 것 같다. 해당 문제는 칼같이 각 Pod가 사용할 최대 용량을 계산하고 OpenEBS Local Device로 스토리지를 구축한 이후부터는 나타나지 않았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1312&quot; data-origin-height=&quot;68&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lJL5U/btsI7q904gO/fVF3cKlZ33gfUBbnzp4X40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lJL5U/btsI7q904gO/fVF3cKlZ33gfUBbnzp4X40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lJL5U/btsI7q904gO/fVF3cKlZ33gfUBbnzp4X40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlJL5U%2FbtsI7q904gO%2FfVF3cKlZ33gfUBbnzp4X40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1312&quot; height=&quot;68&quot; data-origin-width=&quot;1312&quot; data-origin-height=&quot;68&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어쨋든 만약 반드시 저장 장치를 마운트하여 사용해야 한다면 다음을 참고하여 patch 파일을 만들어주도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1724118872663&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# disk_patch 예시 파일.yaml

machine:
    kubelet:
        extraMounts:
            - destination: /var/mount1
              type: bind
              source: /var/mnt/mount1
              options:
                - bind
                - rshared
                - rw
            - destination: /var/mount2
              type: bind
              source: /var/mnt/mount2
              options:
                - bind
                - rshared
                - rw
    disks:
        - device: /dev/sda
          # 파티션을 설정할 때, 무조건 위에서 아래 순서로 파티션을 생성하게 된다.
          # 이 때, size 옵션 없이 mountpoint만 지정하는 파티션은 남은 용량을 전부 할당받는다.
          partitions:
            - size: 240G
              mountpoint: /var/mount1
            - mountpoint: /var/mount2&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1724118906764&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;talosctl patch mc --patch @disk_patch.yaml -n &amp;lt;적용할 노드 IP&amp;gt; -e &amp;lt;control node IP&amp;gt; --talosconfig=&amp;lt;본인 talosconfig경로&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음 위의 명령어를 실행한다면 노드를 재실행하면서 저장 장치를 포맷하고 파티션을 나눈 다음 마운트하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때, Talos Linux는 기본적으로 XFS 포맷으로 파티션을 생성한다.&lt;/p&gt;</description>
      <category>프로그래밍|소프트웨어/Talos Linux</category>
      <category>k8s</category>
      <category>talos linux</category>
      <author>테크믈리에</author>
      <guid isPermaLink="true">https://korjwl1.tistory.com/36</guid>
      <comments>https://korjwl1.tistory.com/36#entry36comment</comments>
      <pubDate>Tue, 20 Aug 2024 10:56:20 +0900</pubDate>
    </item>
    <item>
      <title>Talos Linux를 통한 간편한 Production Level K8S 환경 구축하기 - 1 -</title>
      <link>https://korjwl1.tistory.com/35</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.talos.dev/v1.7/introduction/getting-started/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.talos.dev/v1.7/introduction/getting-started/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722489053688&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Getting Started&quot; data-og-description=&quot;A guide to setting up a Talos Linux cluster.&quot; data-og-host=&quot;www.talos.dev&quot; data-og-source-url=&quot;https://www.talos.dev/v1.7/introduction/getting-started/&quot; data-og-url=&quot;https://www.talos.dev/v1.7/introduction/getting-started/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/huOoZ/hyWGYEM7Mu/HQ1ajcN5o1Lb8tZLfi9mzk/img.png?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260&quot;&gt;&lt;a href=&quot;https://www.talos.dev/v1.7/introduction/getting-started/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.talos.dev/v1.7/introduction/getting-started/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/huOoZ/hyWGYEM7Mu/HQ1ajcN5o1Lb8tZLfi9mzk/img.png?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Getting Started&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A guide to setting up a Talos Linux cluster.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.talos.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Talos Linux는 Sidero Labs에서 개발한 K8S 특화형 Linux 배포판이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특징으로는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;u&gt;SSH 접속 등 전통적인 리눅스 접근 방식 대신 talosctl&lt;/u&gt;이라는 자체 프로그램을 통해서만 노드를 다룰 수 있게 되어 있으며, 모든 연결은 mTLS 인증을 기반으로 동작하기 때문에 보안면에서 관리자가 신경쓸 부분이 적다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Production Level의 안정적인 K8S 구축을 위해서 기존에는 RHEL의 CoreOS나 SUSE의 MicroOS등 보다 마이너한 불변성 OS를 갖고 네트워크 설정, 디스크 파티션 설정, 그래픽 카드 및 각종 드라이버 설치 등의 OS 설정도 전부 수동으로 해줘야하는 등 불편하고 어려운 부분이 많았지만, Talos Linux는 설치하는 단계에서 K8S 동작에 가장 적합한 OS 설정을 자동으로 해주기 때문에 보다 편하고 신뢰할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 기존 블로그에서 K0S 등을 다뤄봤던 이유는 번거로운 CNI 설정 부분을 간편하게 건너뛰고 작업하여 소수 작업자에 의한 K8S환경 구축 및 유지 보수를 편하게 해보기 위해서였는데, Talos Linux는 &lt;u&gt;Flannel CNI&lt;/u&gt;를 자동으로 최적화하여 설치해주기 때문에 해당 목적에 부합하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. &lt;u&gt;DDNS 또는 Virtual IP&lt;/u&gt; 등을 통하여 단 몇 줄만의 설정으로 복수의 &lt;u&gt;Control Plane을 쉽게 Load Balancing&lt;/u&gt; 하게끔 도와주며 &lt;u&gt;Wireguard&lt;/u&gt; 기반으로 다른 개인 네트워크 영역에 속해있는 노드들을 묶을 수 있게 도와준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 파일의 경우, 만약 NVIDIA GPU 지원이나 Proxmox/VMWare 등 위에서 돌리기 위한 가상 환경 지원 등의 시스템 확장 프로그램이 필요하지 않다면 위의 Getting Started 링크에서 본인에게 맞는 버전으로 다운받으면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템 확장 프로그램이 필요한 경우에는 &lt;a href=&quot;https://www.talos.dev/v1.7/talos-guides/install/boot-assets/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.talos.dev/v1.7/talos-guides/install/boot-assets/&lt;/a&gt; 해당 링크를 통하여 본인에게 필요한 시스템 확장을 추가한 설치파일 및 해당 파일의 ID를 발급받으면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 가능한 확장 목록은 다음 링크를 참고하면 된다. &lt;a href=&quot;https://github.com/siderolabs/extensions&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/siderolabs/extensions&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722490033099&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - siderolabs/extensions: Talos Linux System Extensions&quot; data-og-description=&quot;Talos Linux System Extensions. Contribute to siderolabs/extensions development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/siderolabs/extensions&quot; data-og-url=&quot;https://github.com/siderolabs/extensions&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Wbe4i/hyWGPnzzXw/l0cY2yTNx9HdnOM54Ns0BK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/siderolabs/extensions&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/siderolabs/extensions&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Wbe4i/hyWGPnzzXw/l0cY2yTNx9HdnOM54Ns0BK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - siderolabs/extensions: Talos Linux System Extensions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Talos Linux System Extensions. Contribute to siderolabs/extensions development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선은 준비한 설치파일을 USB / PXE Boot 등을 통하여 설치하고자 하는 노드에서 실행해주도록 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2762&quot; data-origin-height=&quot;586&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6MzlR/btsIR0QEXVF/p4WMwX1EffdA7zQkrzExd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6MzlR/btsIR0QEXVF/p4WMwX1EffdA7zQkrzExd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6MzlR/btsIR0QEXVF/p4WMwX1EffdA7zQkrzExd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6MzlR%2FbtsIR0QEXVF%2Fp4WMwX1EffdA7zQkrzExd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2762&quot; height=&quot;586&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2762&quot; data-origin-height=&quot;586&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때, Talos Linux를 설치하고자 하는 노드에서 고정 IP를 제대로 먹이기 위해서는 &lt;b&gt;&lt;u&gt;공유기 단에서 MAC 주소를 기반으로 고정 IP 설정&lt;/u&gt;&lt;/b&gt; 해놓는 것을 추천한다. (Talos Linux 설정을 통해서도 고정 IP를 할당할 수 있지만, 이 경우 Control Node의 VIP 설정 시 문제가 발생하는 것을 확인하였다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인은&amp;nbsp;&lt;a title=&quot;Ventoy&quot; href=&quot;https://www.ventoy.net/en/index.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.ventoy.net/en/index.html&lt;/a&gt;를 사용하여 부팅 디스크를 만들고, 안에 Lubuntu와 같은 가벼운 리눅스 배포판을 같이 넣어두는 것을 추천한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 Talos Linux로 부팅하기 전에 리눅스로 먼저 진입하여 ip addr 명령어로 MAC 주소를 확인하여 공유기 단 고정 IP 설정을 위한 MAC 주소를 확인할 수 있고 Rook Ceph나 OpenEBS Maystor 같이 Unformatted, Unpartitioned 저장장치를 필요로 하는 CSI를 쓸 경우를 위해 설치 전 저장장치들의 검토 및 재설정을 해줄 수 있기 때문이다. Talos Linux도 하드디스크 Wipe &amp;amp; Partition &amp;amp; Mount 기능들을 제공하기는 하지만 오직 XFS 타입으로 포맷하여 특정 경로에 마운트해주는 정도이기 때문에 사용하던 장비를 Unformatted, Unpartitioned 상태로 되돌리는 것에는 한계가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bszej0/btsISK0R9w2/tkjbkt9eBXQvhEjqKGDIM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bszej0/btsISK0R9w2/tkjbkt9eBXQvhEjqKGDIM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bszej0/btsISK0R9w2/tkjbkt9eBXQvhEjqKGDIM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbszej0%2FbtsISK0R9w2%2Ftkjbkt9eBXQvhEjqKGDIM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1653&quot; height=&quot;1240&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 준비를 마친 다음 Talos Linux로 부팅을하면 다음과 같은 화면이 반겨줄 것이다. 이 상태에서 키보드 조작을 하려고 하면 F1/F2/F3를 제외한 나머지 동작은 로그 갱신에 문제를 일으킨다던지 하는 문제가 있기 때문에 노드에 연결된 키보드는 살포시 치워두는 것을 권장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 Linux나 Mac 기반의 관리자 컴퓨터를 준비하여 주도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1722491151457&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;brew install siderolabs/tap/talosctl&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Talos Linux 노드들을 관리하기 위해서는 talosctl이란 프로그램이 필수인데, 이는 brew를 통해서 배포된다.&lt;/p&gt;
&lt;pre id=&quot;code_1722491246712&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;talosctl gen secrets -o secrets.yaml
talosctl gen config --with-secrets secrets.yaml \
                    --kubernetes-version &amp;lt;버전&amp;gt; \
					&amp;lt;클러스터 이름&amp;gt; &amp;lt;클러스터 Endpoint&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1856&quot; data-origin-height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpZAw1/btsITibQ04I/w6vpXk4XMSuwJxHKplxm91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpZAw1/btsITibQ04I/w6vpXk4XMSuwJxHKplxm91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpZAw1/btsITibQ04I/w6vpXk4XMSuwJxHKplxm91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpZAw1%2FbtsITibQ04I%2Fw6vpXk4XMSuwJxHKplxm91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1720&quot; height=&quot;157&quot; data-origin-width=&quot;1856&quot; data-origin-height=&quot;170&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;talosctl 설치 후에는 위의 명령어를 통하여 mTLS 연결을 위한 인증서를 생성하고 이를 기반으로 Talos Linux의 기본 설정 파일들을 생성하도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 클러스터 &lt;b&gt;Endpoint&lt;/b&gt;는 &lt;u&gt;HA-Proxy / Nginx 등의 Reverse Proxy 기능을 통하여 Control Plane들로 연결될 DDNS 주소&lt;/u&gt;를 적어주거나 혹은 &lt;u&gt;Virtual IP로 사용될 IP 기반 주소&lt;/u&gt;를 적어주도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과물로 나오는 &lt;b&gt;controlplane.yaml&lt;/b&gt; 및 &lt;b&gt;worker.yaml&lt;/b&gt;은 모든 노드 설정에 쓰일 템플릿 설정 파일이며 &lt;b&gt;talosconfig&lt;/b&gt; 파일은 해당 클러스터 내 노드들에 talosctl로 접속하기 위해 필요한 인증파일이다. 아직 한번도 설정되지 않은 노드의 경우에는 talosconfig 없이 --insecure 옵션으로 접속이 가능하지만 한번 설정된 다음부터는 해당 클러스터의 talosconfig 파일 없이는 접속이 안 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722491601008&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;talosctl -n &amp;lt;노드 IP&amp;gt; disks --insecure&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2986&quot; data-origin-height=&quot;210&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcfCzG/btsIQ2BGrN9/LcmkLra69IZzRkLDiFn1oK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcfCzG/btsIQ2BGrN9/LcmkLra69IZzRkLDiFn1oK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcfCzG/btsIQ2BGrN9/LcmkLra69IZzRkLDiFn1oK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcfCzG%2FbtsIQ2BGrN9%2FLcmkLra69IZzRkLDiFn1oK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1720&quot; height=&quot;120&quot; data-origin-width=&quot;2986&quot; data-origin-height=&quot;210&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선은 설치할 경로 파악을 위해 위 명령어로 어떠한 저장 장치들이 해당 노드 내에 꽂혀있는지 확인하여 주도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인의 경우 해당 노드에서는 /dev/sdc 상의 SSD를 OS 설치 장소로 사용할 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722491710115&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;talosctl get address -n &amp;lt;노드 IP&amp;gt; address --insecure&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1656&quot; data-origin-height=&quot;100&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b10qOC/btsIThxcoWK/nhpJSkc7CZmhWkNkjtzs0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b10qOC/btsIThxcoWK/nhpJSkc7CZmhWkNkjtzs0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b10qOC/btsIThxcoWK/nhpJSkc7CZmhWkNkjtzs0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb10qOC%2FbtsIThxcoWK%2FnhpJSkc7CZmhWkNkjtzs0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1656&quot; height=&quot;100&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1656&quot; data-origin-height=&quot;100&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;position: absolute;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;position: absolute;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음에는 위 명령어를 통하여 어떤 네트워크 어댑터들이 있는지 확인을 한 다음, 어떤 어댑터를 통신에 사용할 것인지 정하도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전부 확인이 끝났다면, 아래 링크와 본인이 작성하여둔 템플릿을 참고하여 본인만의 .patch 파일을 만들어보도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.talos.dev/v1.7/reference/configuration/v1alpha1/config/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.talos.dev/v1.7/reference/configuration/v1alpha1/config/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1724109208493&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Config&quot; data-og-description=&quot;Config defines the v1alpha1.Config Talos machine configuration document.&quot; data-og-host=&quot;www.talos.dev&quot; data-og-source-url=&quot;https://www.talos.dev/v1.7/reference/configuration/v1alpha1/config/&quot; data-og-url=&quot;https://www.talos.dev/v1.7/reference/configuration/v1alpha1/config/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/VwSL2/hyWOnSpZn1/EKR7WZeQZHx1XlFDFVmTSK/img.png?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260&quot;&gt;&lt;a href=&quot;https://www.talos.dev/v1.7/reference/configuration/v1alpha1/config/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.talos.dev/v1.7/reference/configuration/v1alpha1/config/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/VwSL2/hyWOnSpZn1/EKR7WZeQZHx1XlFDFVmTSK/img.png?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Config&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Config defines the v1alpha1.Config Talos machine configuration document.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.talos.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1724110560462&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Control Plane용 .patch 파일

machine:
  kubelet:
    nodeIP:
      validSubnets:
        -  &amp;lt;본인의 IP 대역&amp;gt;
        # 본인이 사용할 IP 대역에 맞게 설정하도록 하자.
        # 보통 많이 쓰는 사설 IP 대역인 192.168.0.1 ~ 192.168.0.255의 경우 아래와 같다.
        # - 192.168.0.1/24
    
    # 만약 Metrics Server를 클러스터 내에서 사용하고 싶다면 노드 간 인증서를 교환하도록 하여야 한다.
    # 자세한건 아래 링크를 참고하도록 하자.
    # https://www.talos.dev/v1.7/kubernetes-guides/configuration/deploy-metrics-server/    
    # extraArgs:
      # rotate-server-certificates: true

  network:
    interfaces:
    # 아래 interface 항목에는 앞서 get address 명령어로 확인한 LINK 이름을 적어주도록 하자. (ex. eno1)
    - interface: eno1
      # 만약 Shared VIP를 기반으로 동작하게 하고 싶다고 한다면 
      # 무조건 공유기 단에서 MAC을 기반으로 고정 IP를 설정한 다음
      # Talos Control Plane 설정에서는 고정 IP 설정을 하지 않아야 한다.
      # 만약 고정 IP 설정을 하게 되면 Shared VIP와 충돌이 생기는 것 같다.
      dhcp: true
      # Shared VIP일 때는 아래와 같이 vip 항목을 만들어줘야하고 해당 IP는 실제로 점유되지 않은 IP여야 한다.
      # 또한, vip 값은 모든 control plane 노드가 똑같은 값을 공유하여야 한다.
      vip:
        ip: &amp;lt;본인의 가상 IP&amp;gt;
        # ex) ip: 192.168.0.100
    
    # 본인의 클러스터에서 사용할 Name Server 목록
    # nameservers:
      # - 192.168.0.1
      # - 8.8.8.8
      # - 8.8.4.4
      # - 1.1.1.1
      
    # 본인 클러스터 내에서 해당 노드가 사용할 hostname
    # 절대로 겹치는 hostname을 사용하면 안 된다.
    # hostname: control-1
    
    # 클러스터 내 노드들에 대하여 hostname 기반 통신을 할 수 있게 등록
    # 본인은 무조건 control plane은 3개를 고정적으로 사용할 생각이기에 control plane 3개는 등록해놨다.
    # extraHostEntries:
    #   - ip: 192.168.0.101
    #     aliases:
    #       - control-1
    #   - ip: 192.168.0.102
    #     aliases:
    #       - control-2
    #   - ip: 192.168.0.103
    #     aliases:
    #       - control-3
  
  # Talos OS가 설치되었으면 하는 경로
  # 앞서 disks 옵션으로 확인하였던 것을 참조하자
  install:
  	disk: &amp;lt;설치할 디스크 경로&amp;gt;
    # ex) disk: /dev/sda
    wipe: true
    
  # 사설 Docker Registry 접속 정보를 등록하고자 하는 경우
  # registries:
    # config:
      # &amp;lt;사설 Docker Registry 주소 (https 등 붙는 것 없이)&amp;gt;:
        # auth:
          # username: &amp;lt;사설 Docker Registry ID&amp;gt;
          # password: &amp;lt;사설 Docker Registry PWD&amp;gt;

cluster:
  # API 서버의 인증서에서 사용될 alternative name
  # 아마 control plane 노드들의 IP를 등록하여두면 도움이 되는거 같다.
  # apiServer:
    # certSANs:
      # - 192.168.0.101
      # - 192.168.0.102
      # - 192.168.0.103
      
  # Talos Linux의 기본 ETCD 가용 용량은 2GiB로 설정되어 있다.
  # 권장하는 Maximum 값은 8GiB로, 2~8GiB 사이에서 본인 필요에 따라 가용 용량을 조절하여 설치할 수 있다.
  # 아래 예시는 4GiB로 설정하는 설정값이다.
  # etcd:
  #   extraArgs:
  #     quota-backend-bytes: 4294967296&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1724111513432&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Worker Node용 .patch

machine:
  kubelet:
    nodeIP:
      validSubnets:
        - &amp;lt;본인이 사용할 IP 대역&amp;gt;
        
    # extraArgs:
    #   rotate-server-certificates: true

  network:
    interfaces:
    - interface: &amp;lt;본인 네트워크 인터페이스&amp;gt;
      # Worker 노드의 경우, Shared VIP일 때의 Control Plane과 달리 Talos에서 고정 IP를 할당하여도 문제가 없다.
      addresses:
        - &amp;lt;고정 IP/Subnet mask&amp;gt;
        # ex) - 192.168.0.105/24
      # 고정 네트워크 설정 시 Network Route 정보를 주는 것도 고려해볼 수 있다.
      # 아래는 예시다.
      # routes:
      #   - network: 0.0.0.0/0
      #     gateway: 192.168.0.1
      
    # nameservers:
    #   - 192.168.0.1
    #   - 8.8.8.8
    #   - 8.8.4.4
    #   - 1.1.1.1
    
    # hostname은 반드시 각 노드가 다른 값을 쓰도록 해주자
    hostname: worker-1
    
    # extraHostEntries:
    #   - ip: 192.168.0.101
    #     aliases:
    #       - control-1
    #   - ip: 192.168.0.102
    #     aliases:
    #       - control-2
    #   - ip: 192.168.0.103
    #     aliases:
    #       - control-3

  install:
    disk: &amp;lt;설치할 저장장치&amp;gt;
    wipe: true
    # 만약 Nvidia 그래픽카드 지원이라던가 ISCSI 등의 모듈을 사용하고 싶은 경우, 알맞은 image 옵션을 반드시 줘야한다.
    # 이미지를 생성하는 방법은 아래 링크를 참조하자. (Image Factory 참고)
    # https://www.talos.dev/v1.7/talos-guides/install/boot-assets/
    # WEB GUI를 기반으로 이미지를 생성해보려면 아래 링크에서 생성하자
    # https://factory.talos.dev
    # 사용 가능한 시스템 확장들은 아래와 같다.
    # https://github.com/siderolabs/extensions
    # 아래 예시는 iscsi, nvidia driver를 추가하여 만든 본인의 이미지 예시이다.
    # image: factory.talos.dev/installer/aefe418d4647eb3ecb93d2c5d583c663aa54c790165493b0414bf01442d93897:v1.7.5

  # registries:
  #   config:
  #     &amp;lt;사설 Docker Registry&amp;gt;:
  #       auth:
  #         username: &amp;lt;사설 Docker Registry ID&amp;gt;
  #         password: &amp;lt;사설 Docker Registry PWD&amp;gt;

# cluster:
#   apiServer:
#     certSANs:
#       - 192.168.0.101
#       - 192.168.0.102
#       - 192.168.0.103&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 노드별로 .patch 파일 작성을 완료하였다면 아래 명령어셋을 참고하여 각 노드들에 설정을 적용하고 Talos Linux 설치를 진행한다.&lt;/p&gt;
&lt;pre id=&quot;code_1724111669400&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Control Plane의 경우
talosctl machineconfig patch controlplane.yaml --patch @&amp;lt;패치 파일명&amp;gt; --output &amp;lt;출력 파일명&amp;gt; 

# Worker의 경우
talosctl machineconfig patch worker.yaml --patch @&amp;lt;패치 파일명&amp;gt; --output &amp;lt;출력 파일명&amp;gt;

# 설정파일 적용
talosctl apply-config --insecure -n &amp;lt;노드 IP&amp;gt; --file &amp;lt;설정 파일명&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled-2.png&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/delmNV/btsI8h5Krz6/YdD8vxkaLF8md8Ww2PNJmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/delmNV/btsI8h5Krz6/YdD8vxkaLF8md8Ww2PNJmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/delmNV/btsI8h5Krz6/YdD8vxkaLF8md8Ww2PNJmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdelmNV%2FbtsI8h5Krz6%2FYdD8vxkaLF8md8Ww2PNJmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;Untitled-2.png&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/92EIN/btsI9flAEqR/XBDHiGAKhfbekCmW5fDZkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/92EIN/btsI9flAEqR/XBDHiGAKhfbekCmW5fDZkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/92EIN/btsI9flAEqR/XBDHiGAKhfbekCmW5fDZkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F92EIN%2FbtsI9flAEqR%2FXBDHiGAKhfbekCmW5fDZkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Talos Linux Cluster를 활성화 하기 위해서는 해당 Cluster 내 Control Plane들 중 하나의 노드에 Bootstrap 신호를 보내야만 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유의할 것은, &lt;u&gt;&lt;b&gt;정확히 한 개의 노드에서 Bootstrap 과정이 일어나야한다는 것&lt;/b&gt;&lt;/u&gt;이다.&lt;/p&gt;
&lt;pre id=&quot;code_1724111990581&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;talosctl bootstrap --nodes &amp;lt;Bootstrap할 Control Plane 노드 IP&amp;gt; --endpoints &amp;lt;Control Plane 노드들의 IP를 ,으로만 구분지어 넣어준다&amp;gt; --talosconfig=talosconfig&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvoJa9/btsI8g6NcUn/dzt8kVtSHkkG2tzldkWad1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvoJa9/btsI8g6NcUn/dzt8kVtSHkkG2tzldkWad1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvoJa9/btsI8g6NcUn/dzt8kVtSHkkG2tzldkWad1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvoJa9%2FbtsI8g6NcUn%2Fdzt8kVtSHkkG2tzldkWad1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든게 성공적이었다면, 모든 노드들에서 READY값이 True가 되는 것을 확인할 수 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹은 아래 명령어로 상태 점검을 해볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1724112124935&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;talosctl --nodes &amp;lt;control plane 노드 IP&amp;gt; --endpoints &amp;lt;control plane 노드 IP&amp;gt; health --talosconfig=talosconfig&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2536&quot; data-origin-height=&quot;1092&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmDond/btsI8hxQ8zD/MefBp1pTNIyV56ePuvWPt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmDond/btsI8hxQ8zD/MefBp1pTNIyV56ePuvWPt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmDond/btsI8hxQ8zD/MefBp1pTNIyV56ePuvWPt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmDond%2FbtsI8hxQ8zD%2FMefBp1pTNIyV56ePuvWPt1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2536&quot; height=&quot;1092&quot; data-origin-width=&quot;2536&quot; data-origin-height=&quot;1092&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(참고로 Talos Linux만 막 설치하고 아무런 Pod도 올리지 않았다면 missing static pods on node란 문제가 나올 수 있는데 당연한 상태이니 무시하여도 괜찮다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, Nvidia Driver 모듈을 추가로 넣은 이미지로 Talos Linux를 설치한 경우, 해당 노드의 대시보드에 계속하여 nvidia 관련 오류가 출력되며 READY가 FALSE인 상태를 계속 유지할 것인데, 해당 이슈는 다음 글을 통하여 해결 방법을 설명하도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 기본적으로 Talos Linux는 Pod Security가 엄격하게 적용되어 있기에 필요한 프로그램을 올리는데 문제가 있을 수 있는데, 해당 해결 방법 역시 다음 글을 통해 설명할 것이며, metrics server 동작을 위하여 rotate-server-certificates 옵션을 준 경우에는 TLS 관련 오류가 발생할 것인데 이 역시 다음 글에서 설명하도록 하겠다.&lt;/p&gt;</description>
      <category>프로그래밍|소프트웨어/Talos Linux</category>
      <category>k8s</category>
      <category>talos linux</category>
      <author>테크믈리에</author>
      <guid isPermaLink="true">https://korjwl1.tistory.com/35</guid>
      <comments>https://korjwl1.tistory.com/35#entry35comment</comments>
      <pubDate>Thu, 1 Aug 2024 14:56:59 +0900</pubDate>
    </item>
    <item>
      <title>[k8s] KubeFlow 설치 방법 및 각종 설정 방법</title>
      <link>https://korjwl1.tistory.com/34</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;KubeFlow?&amp;nbsp;&lt;/h3&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.kubeflow.org&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.kubeflow.org&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1706776193008&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Kubeflow&quot; data-og-description=&quot;Kubeflow makes deployment of ML Workflows on Kubernetes straightforward and automated&quot; data-og-host=&quot;www.kubeflow.org&quot; data-og-source-url=&quot;https://www.kubeflow.org&quot; data-og-url=&quot;https://www.kubeflow.org/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/OPsyC/hyVf8N4sNK/n810rqj6DDbkmwaarCIiuK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000,https://scrap.kakaocdn.net/dn/V3KSi/hyVcbeDRqw/YjPfKd5jtG2xLTuKV1OkM1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000,https://scrap.kakaocdn.net/dn/dqxWIB/hyVb1iOoIT/jj84676Fz4Un2YYy9iSpl1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://www.kubeflow.org&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.kubeflow.org&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/OPsyC/hyVf8N4sNK/n810rqj6DDbkmwaarCIiuK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000,https://scrap.kakaocdn.net/dn/V3KSi/hyVcbeDRqw/YjPfKd5jtG2xLTuKV1OkM1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000,https://scrap.kakaocdn.net/dn/dqxWIB/hyVb1iOoIT/jj84676Fz4Un2YYy9iSpl1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Kubeflow&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Kubeflow makes deployment of ML Workflows on Kubernetes straightforward and automated&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.kubeflow.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kubeflow/manifests&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kubeflow/manifests&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1706776225420&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - kubeflow/manifests: A repository for Kustomize manifests&quot; data-og-description=&quot;A repository for Kustomize manifests. Contribute to kubeflow/manifests development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/kubeflow/manifests&quot; data-og-url=&quot;https://github.com/kubeflow/manifests&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b6Qhiv/hyVceCrirJ/CLZ664h5sn7HHNTmlakGG1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/kubeflow/manifests&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/kubeflow/manifests&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b6Qhiv/hyVceCrirJ/CLZ664h5sn7HHNTmlakGG1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - kubeflow/manifests: A repository for Kustomize manifests&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A repository for Kustomize manifests. Contribute to kubeflow/manifests development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;설치 전 준비 작업&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 하기에 앞서서 필요한 것들을 확인해보도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;1. Kubernetes 환경이 필요하다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인이 사용한 Kubernetes 버전은 k0s의 v1.25.16+k0s.0이다. (kubeflow 권장 up to 1.26)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1508&quot; data-origin-height=&quot;276&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oJ3WQ/btsEfoIZtZp/QXyTTeKuJyFZjtf6CkUwZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oJ3WQ/btsEfoIZtZp/QXyTTeKuJyFZjtf6CkUwZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oJ3WQ/btsEfoIZtZp/QXyTTeKuJyFZjtf6CkUwZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoJ3WQ%2FbtsEfoIZtZp%2FQXyTTeKuJyFZjtf6CkUwZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1508&quot; height=&quot;276&quot; data-origin-width=&quot;1508&quot; data-origin-height=&quot;276&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://korjwl1.tistory.com/28&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://korjwl1.tistory.com/28&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1706776334285&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[k0s Cluster 구축] 1. Ansible을 통한 기초 세팅&quot; data-og-description=&quot;목차 0. Rocky Linux 8.5 설치 1. Ansible을 통한 기초 세팅 2. k0s 클러스터 구축 및 OpenLens 기초 사용법 3. OpenLens의 기초 세팅법 4. k0s 클러스터에서 Nvidia GPU 사용하기 5. k0s 클러스터에서 Rook Ceph Block Storage&quot; data-og-host=&quot;korjwl1.tistory.com&quot; data-og-source-url=&quot;https://korjwl1.tistory.com/28&quot; data-og-url=&quot;https://korjwl1.tistory.com/28&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/TayjT/hyVf2mNcqL/d26pLavT0ykzHLZ7wPkRZK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/djK9Yu/hyVf03zQ6u/dVU86vkv7sPNFiunbkB5aK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/Za1Nx/hyVb6j6KYV/f46wEyYX2wwHT85AZ4oCl1/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://korjwl1.tistory.com/28&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://korjwl1.tistory.com/28&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/TayjT/hyVf2mNcqL/d26pLavT0ykzHLZ7wPkRZK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/djK9Yu/hyVf03zQ6u/dVU86vkv7sPNFiunbkB5aK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/Za1Nx/hyVb6j6KYV/f46wEyYX2wwHT85AZ4oCl1/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[k0s Cluster 구축] 1. Ansible을 통한 기초 세팅&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;목차 0. Rocky Linux 8.5 설치 1. Ansible을 통한 기초 세팅 2. k0s 클러스터 구축 및 OpenLens 기초 사용법 3. OpenLens의 기초 세팅법 4. k0s 클러스터에서 Nvidia GPU 사용하기 5. k0s 클러스터에서 Rook Ceph Block Storage&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;korjwl1.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 어떻게 환경을 준비할 지 모르겠다면 본인이 쓴 시리즈 글을 참고하여보도록하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(이 때, k0s_setup.yml 파일 내의 Install latest k0s 내용을 조금 수정해야한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;*수정 전 shell: curl -sSLf &lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://get.k0s.sh&quot;&gt;https://get.k0s.sh&lt;/a&gt; | DEBUG=true sh &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;-&amp;gt; * 수정 후 shell: curl -sSLf &lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://get.k0s.sh&quot;&gt;https://get.k0s.sh&lt;/a&gt; | &lt;span style=&quot;text-align: start;&quot;&gt;K0S_VERSION=v1.25.16+k0s.0 sh)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;2. Default Storage Class가 설정되어 있어야 한다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 많이 쓰는 Storage는 LongHorn, Rook Ceph, OpenEBS, Minio 등이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노드 3개 이상이라면 Rook Ceph를 추천하고 본인은 Rook Ceph 1.13.3 버전을 사용하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://korjwl1.tistory.com/32&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://korjwl1.tistory.com/32&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1706776659237&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[k0s Cluster 구축] 5. k0s 클러스터에서 Rook Ceph Block Storage 사용하기&quot; data-og-description=&quot;목차 0. Rocky Linux 8.5 설치 1. Ansible을 통한 기초 세팅 2. k0s 클러스터 구축 및 OpenLens 기초 사용법 3. OpenLens의 기초 세팅법 4. k0s 클러스터에서 Nvidia GPU 사용하기 5. k0s 클러스터에서 Rook Ceph Block Storage&quot; data-og-host=&quot;korjwl1.tistory.com&quot; data-og-source-url=&quot;https://korjwl1.tistory.com/32&quot; data-og-url=&quot;https://korjwl1.tistory.com/32&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bi7kRX/hyVf3F02Aw/KkecTSZKHpL54xMvHEZajK/img.png?width=800&amp;amp;height=404&amp;amp;face=0_0_800_404,https://scrap.kakaocdn.net/dn/DpKe3/hyVgcwaWhx/S6atZFr2BKzDQFIo7lmrfK/img.png?width=800&amp;amp;height=404&amp;amp;face=0_0_800_404&quot;&gt;&lt;a href=&quot;https://korjwl1.tistory.com/32&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://korjwl1.tistory.com/32&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bi7kRX/hyVf3F02Aw/KkecTSZKHpL54xMvHEZajK/img.png?width=800&amp;amp;height=404&amp;amp;face=0_0_800_404,https://scrap.kakaocdn.net/dn/DpKe3/hyVgcwaWhx/S6atZFr2BKzDQFIo7lmrfK/img.png?width=800&amp;amp;height=404&amp;amp;face=0_0_800_404');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[k0s Cluster 구축] 5. k0s 클러스터에서 Rook Ceph Block Storage 사용하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;목차 0. Rocky Linux 8.5 설치 1. Ansible을 통한 기초 세팅 2. k0s 클러스터 구축 및 OpenLens 기초 사용법 3. OpenLens의 기초 세팅법 4. k0s 클러스터에서 Nvidia GPU 사용하기 5. k0s 클러스터에서 Rook Ceph Block Storage&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;korjwl1.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;k0s에 Rook Ceph를 사용하고자 한다면 위의 글을 참고해보도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1706776701572&quot; class=&quot;gherkin&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# 기존 기본 저장장소 해제
kubectl patch storageclass &amp;lt;이름&amp;gt; -p '{&quot;metadata&quot;: {&quot;annotations&quot;:{&quot;storageclass.kubernetes.io/is-default-class&quot;:&quot;false&quot;}}}'

# 새 기본 저장장소 지정
kubectl patch storageclass &amp;lt;이름&amp;gt; -p '{&quot;metadata&quot;: {&quot;annotations&quot;:{&quot;storageclass.kubernetes.io/is-default-class&quot;:&quot;true&quot;}}}'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인만의 Storage를 구축한 다음에는 위의 코드를 참고하여 Default Storage를 하나 지정해주도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;3. Kustomize 설치&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 명령어를 참고하여 Kustomize를 설치해두도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1706673350728&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;curl -s &quot;https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh&quot;  | bash
sudo mv kustomize /usr/local/bin&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;번외. MetalLB를 통한 Load Balancer 준비&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;/u&gt;아래 명령어를 통해 MetalLB를 설치하도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1706761754080&quot; class=&quot;oxygene&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;helm repo add metallb https://metallb.github.io/metallb
helm --namespace metallb-system install --create-namespace metallb metallb/metallb&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 후에는 아래 내용을 &lt;b&gt;metallb_config.yaml&lt;/b&gt;로 저장하고 &lt;b&gt;kubectl apply -f metallb_config.yaml&lt;/b&gt;로 반영하도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1706761846213&quot; class=&quot;yaml&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  namespace: metallb-system
  name: nat
spec:
  addresses:
    - [시작 IP]-[끝 IP]
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: empty
  namespace: metallb-system&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;설치 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선은 k0s 등의 환경에서는 미리 istio를 설치해두고 istio 관련 설정을 적용해놔야 KubeFlow가 정상적으로 올라간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Rancher + Calico 조합에서는 아래 작업 없이 올라갔었다)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(만약 istio 관련 설정이 제대로 되지 않았다면 command error output: xtables parameter problem: iptables-restore: unable to initialize table 'nat' 에러가 발생할 것이고 dashboard에서는 unhealthy upstream 에러가 발생하고 있을 것인데, 아래 istio 설정 관련 내용을 진행한 다음 각 노드를 재부팅해주고 pending 상태인 pod들을 강제로 끄기를 반복해주다보면 정상화 될 것이다.)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1706771754992&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# 모든 참여 노드에서 아래 내용을 진행한다.
sudo nano /etc/modules-load.d/k8s.conf

# 아래 내용 추가
overlay
br_netfilter
nf_nat
xt_REDIRECT
xt_owner
iptable_nat
iptable_mangle
iptable_filter

# 내용 추가 및 저장 후에는 노드를 재시작한다.
sudo reboot&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 KubeFlow 설치파일을 다운받도록 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1706777100480&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;git clone https://github.com/kubeflow/manifests.git
cd manifests

# 아래 명령어로 설치
while ! kustomize build example | awk '!/well-defined/' | kubectl apply -f -; do echo &quot;Retrying to apply resources&quot;; sleep 10; done&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 Pod가 정상적으로 올라간 다음에 대시보드에 접속해보려면 아래 명령어를 통하여 LoadBalancer나 NodePort 설정을 해주도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1706777240022&quot; class=&quot;routeros&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;KUBE_EDITOR=&quot;nano&quot; kubectl edit svc istio-ingressgateway -n istio-system&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기 ID는 &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;b&gt;user@example.com&lt;/b&gt;이고 초기 PWD는 &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;b&gt;12341234&lt;/b&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;성공적으로 설치가 되었다면 아래와 같은 화면이 보일 것이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3414&quot; data-origin-height=&quot;2482&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/E36NB/btsEkywbDO5/WGjFDHT9091vnPHbkUC1xk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/E36NB/btsEkywbDO5/WGjFDHT9091vnPHbkUC1xk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/E36NB/btsEkywbDO5/WGjFDHT9091vnPHbkUC1xk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FE36NB%2FbtsEkywbDO5%2FWGjFDHT9091vnPHbkUC1xk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3414&quot; height=&quot;2482&quot; data-origin-width=&quot;3414&quot; data-origin-height=&quot;2482&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;오류 해결 방법 및 KubeFlow 설정 방법&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. HTTP 상에서 정상적으로 동작하게 하는 방법&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1706777353696&quot; class=&quot;dts&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;nano apps/jupyter/jupyter-web-app/upstream/base/params.env

# 내부에서 - name: APP_SECURE_COOKIES 항목을 value: &quot;false&quot;로 변경

kustomize build apps/jupyter/jupyter-web-app/upstream/overlays/istio | kubectl apply -f -&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1706777366102&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nano apps/volumes-web-app/upstream/base/params.env

# 내부에서 - name: APP_SECURE_COOKIES 항목을 value: &quot;false&quot;로 변경

kustomize build apps/volumes-web-app/upstream/overlays/istio | kubectl apply -f -&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 로그아웃 버튼이 동작하지 않을 때 고치는 방법&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1706777401328&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 아래 내용을 아무 이름으로나 저장한 다음 kubectl apply -f 명령어로 적용하도록 하자.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: authservice-logout
  namespace: istio-system
spec:
  gateways:
    - kubeflow/kubeflow-gateway
  hosts:
    - '*'
  http:
    - match:
        - uri:
            prefix: /logout
      rewrite:
        uri: /authservice/logout
      route:
        - destination:
            host: authservice.istio-system.svc.cluster.local
            port:
              number: 8080&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. LDAP 로그인 방법을 추가하는 방법&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1706777751313&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 아래 명령어로 dex-config.yaml 파일을 생성한다
kubectl get configmap dex -n auth -o jsonpath='{.data.config\.yaml}' &amp;gt; dex-config.yaml

# 파일 내용 수정 -&amp;gt; dex-config.yaml 제일 아래에 # LDAP Configuration 부터의 내용을 추가한다.
# 만약 STARTTLS 미적용 상태라면 startTLS: false로 두고 rootCAData: 줄을 삭제한다.
# LDAP Configuration
connectors:
- type: ldap
  name: OpenLDAP
  id: ldap
  config:
    host: &amp;lt;Host 주소&amp;gt;
    insecureNoSSL: false
    insecureSkipVerify: false
    startTLS: true
    rootCAData: &quot;&amp;lt;CA 증명서 내용 삽입&amp;gt;&quot;
    bindDN: &amp;lt;Bind DN 정보&amp;gt;
    bindPW: &amp;lt;Bind DN 비밀번호&amp;gt;
    usernamePrompt: LDAP Username
    userSearch:
      baseDN: &amp;lt;Base DN 정보&amp;gt;
      filter: &quot;(objectClass=posixAccount)&quot;
      username: uid
      idAttr: uid
      emailAttr: mail
      nameAttr: cn
    groupSearch:
      baseDN: &amp;lt;Group Base DN 정보&amp;gt;
      filter: &quot;(objectClass=posixGroup)&quot;
      nameAttr: cn
      
# 파일 저장 후 아래 명령어를 통하여 변경 사항을 적용한다.
kubectl create configmap dex --from-file=config.yaml=dex-config.yaml -n auth --dry-run -oyaml | kubectl apply -f -
kubectl rollout restart deployment dex -n auth&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5. LDAP 등 로그인 방식 추가 후 계정의 자체 NameSpace를 생성할 수 없는 문제 해결 방법&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1706777806577&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nano apps/centraldashboard/upstream/base/params.env

# registration flow true

kustomize build apps/centraldashboard/upstream/overlays/istio | kubectl apply -f -&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;6. GPU Vendor 선택 안 되는 이슈 해결 방법&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1606&quot; data-origin-height=&quot;1102&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tNElx/btsEeNhMsL9/GwcgQDbJsUr0WxKPg19Fx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tNElx/btsEeNhMsL9/GwcgQDbJsUr0WxKPg19Fx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tNElx/btsEeNhMsL9/GwcgQDbJsUr0WxKPg19Fx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtNElx%2FbtsEeNhMsL9%2FGwcgQDbJsUr0WxKPg19Fx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1606&quot; height=&quot;1102&quot; data-origin-width=&quot;1606&quot; data-origin-height=&quot;1102&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KubeFlow 1.8 버전에서는 기본 소스 코드에서 왜인지 몰라도 GPU Vendor 내용이 위의 사진과 같이 빈 Array 상태로 오는 것을 확인할 수 있다. 이를 해결하기 위해서는 vendors: [] 줄을 삭제하고 그 아래 vendors: 부터 uiName: &quot;AMD&quot; 까지를 전부 주석 해제하도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내용을 전부 수정한 다음 변경 사항을 반영하기 위해서는 설치 코드를 다시 돌려주도록 하자.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;314&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B62M1/btsEj6Uk5Fy/qSkMJXYjKxxm98x4ZZKR1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B62M1/btsEj6Uk5Fy/qSkMJXYjKxxm98x4ZZKR1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B62M1/btsEj6Uk5Fy/qSkMJXYjKxxm98x4ZZKR1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB62M1%2FbtsEj6Uk5Fy%2FqSkMJXYjKxxm98x4ZZKR1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1260&quot; height=&quot;314&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;314&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;7. NodeAffinity를 통한 GPU 선택권 제공하기&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1616&quot; data-origin-height=&quot;1068&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqQjTu/btsEkB0MLTj/1HHbJTGhLL7s39KL2TJKNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqQjTu/btsEkB0MLTj/1HHbJTGhLL7s39KL2TJKNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqQjTu/btsEkB0MLTj/1HHbJTGhLL7s39KL2TJKNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqQjTu%2FbtsEkB0MLTj%2F1HHbJTGhLL7s39KL2TJKNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1616&quot; height=&quot;1068&quot; data-origin-width=&quot;1616&quot; data-origin-height=&quot;1068&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KubeFlow는 기본적으로 AWS나 GKE 등에서 돌아가도록 나왔기에 GPU를 선택하는 옵션이 기본적으로 들어있지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 일반 사용자 입장에서는 노드를 구매한 시기가 제각각이고 때문에 GPU가 제각각인 일이 많을텐데, 기본적으로 GPU 종류에 무관하게 랜덤 Pod 생성이 일어나는 점이 여간 신경쓰이지 않을 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 해결하기 위해서는 NodeAffinity를 통해 Pod 생성 시 GPU를 고르도록 할 필요가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NodeAffinity가 무엇인지 모르는 사람은 해당 내용을 제대로 공부한 다음 위의 스크린샷을 참고하여 파일을 수정하고 설치 코드를 다시 돌려 변경 사항을 반영해주도록 하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1324&quot; data-origin-height=&quot;770&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XZQCV/btsEft4xPn5/qMW4ruubSjia0bkLehH5fK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XZQCV/btsEft4xPn5/qMW4ruubSjia0bkLehH5fK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XZQCV/btsEft4xPn5/qMW4ruubSjia0bkLehH5fK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXZQCV%2FbtsEft4xPn5%2FqMW4ruubSjia0bkLehH5fK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1324&quot; height=&quot;770&quot; data-origin-width=&quot;1324&quot; data-origin-height=&quot;770&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;8. 설치 코드 때문에 LoadBalancer / NodePort 설정 변경되는 것 방지하기&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5OkU5/btsEf0ul4Ll/7HJIHBJT9lLmYEWAT4JcfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5OkU5/btsEf0ul4Ll/7HJIHBJT9lLmYEWAT4JcfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5OkU5/btsEf0ul4Ll/7HJIHBJT9lLmYEWAT4JcfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5OkU5%2FbtsEf0ul4Ll%2F7HJIHBJT9lLmYEWAT4JcfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1018&quot; height=&quot;432&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPU의 새로운 종류가 추가되어서 NodeAffinity 정보를 수정한다던지의 이유로 인해 설치 코드를 통해 해당 내용을 반영할 때마다 service 정보가 기본으로 돌아가버려 LoadBalancer / NodePort 설정정보가 바뀐다면 여간 귀찮은 일이 아닐 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 방지하기 위해서는 위의 스크린샷을 참고하여 아예 설치 파일을 수정해두도록 하자.&lt;/p&gt;</description>
      <category>프로그래밍|소프트웨어/기타</category>
      <author>테크믈리에</author>
      <guid isPermaLink="true">https://korjwl1.tistory.com/34</guid>
      <comments>https://korjwl1.tistory.com/34#entry34comment</comments>
      <pubDate>Thu, 1 Feb 2024 13:29:17 +0900</pubDate>
    </item>
    <item>
      <title>[k8s] OpenEBS를 통한 Local Device, Local HostPath 구축방법</title>
      <link>https://korjwl1.tistory.com/33</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;OpenEBS?&lt;/h3&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://openebs.io&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://openebs.io&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1701419047906&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;Website&quot; data-og-title=&quot;OpenEBS - Kubernetes storage simplified.&quot; data-og-description=&quot;OpenEBS makes it easy to attach Dynamic Local PV or Replicated Volumes to any Kubernetes application by abstracting all of the complex commands involved in creating robust multi-zone storage in a simple one-line command.&quot; data-og-host=&quot;openebs.io&quot; data-og-source-url=&quot;https://openebs.io&quot; data-og-url=&quot;https://openebs.io/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bTRc2I/hyUE5S5Fa5/UM3oeNGyvAxe8F2AHK6ouk/img.png?width=1042&amp;amp;height=625&amp;amp;face=0_0_1042_625,https://scrap.kakaocdn.net/dn/PTfKG/hyUE5ZPYMc/AOzRFZP1dEGpxee9W07Mb1/img.png?width=1042&amp;amp;height=625&amp;amp;face=0_0_1042_625&quot;&gt;&lt;a href=&quot;https://openebs.io&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://openebs.io&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bTRc2I/hyUE5S5Fa5/UM3oeNGyvAxe8F2AHK6ouk/img.png?width=1042&amp;amp;height=625&amp;amp;face=0_0_1042_625,https://scrap.kakaocdn.net/dn/PTfKG/hyUE5ZPYMc/AOzRFZP1dEGpxee9W07Mb1/img.png?width=1042&amp;amp;height=625&amp;amp;face=0_0_1042_625');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;OpenEBS - Kubernetes storage simplified.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;OpenEBS makes it easy to attach Dynamic Local PV or Replicated Volumes to any Kubernetes application by abstracting all of the complex commands involved in creating robust multi-zone storage in a simple one-line command.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;openebs.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenEBS는 Rook Ceph, Longhorn 등과 함께 무료로 사용할 수 있는 k8s 저장소 관리 방법 중 하나로 Mayastor, cStor, Jiva, LocalPV 등의 다양한 옵션을 제공한다. 앞의 방법들도 강력하지만, 특히 뒤의 LocalPV 때문에 OpenEBS를 많이 쓰는데, 몇 안되는 Dynamic Local Provisioner이기 때문에 대체안이 없기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rook Ceph 등의 분산 저장소는 데이터 안정성이 매우 높은 대신 특히 단일 읽기/쓰기 성능이 떨어지는 것이 문제인데 LocalPV를 사용하면 Pod가 돌아가는 노드의 물리적 저장장소를 바로 사용하기 때문에 원 저장 장치 성능을 큰 손해 없이 끌어다 쓸 수 있다는 것이 장점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 특성 때문에 ElasticSearch 등의 이미 분산 저장 기법이 적용된 DB를 운용할 때 특히 추천한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Local Device 사용을 위한 저장 장치 준비&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이것저것 테스트 해본 결과, Local Device로 잘 인식되게 하기 위해서는 해당 저장 장치에 파티션을 1개 이상 생성 후, 사용하고자 하는 파티션을 ext4로 포맷하는 것이 좋았다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Local Device 방식의 장점이라면 Block Storage 기반으로 동작한다는 것이고, 단점이라면 무조건 하나의 Persistent Volume 당 하나의 저장 장치가 온전하게 점유된다는 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;가령 예를 들어, 저장 장치가 1TB의 용량을 갖고 있고 Persistent Volume Claim이 20GB라 해도 저장 장치의 나머지 용량에 다른 Persistent Volume을 선언할 수 없는 상태가 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 때문에, 이번 글의 예시에서는 1TB의 저장 용량을 2개의 파티션으로 나눠 하나는 Local Device에서, 나머지는 Local Host에서 쓰도록 해보겠다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JiG2G/btsBikV32yc/6brQyuCKnokMsgghk9CgxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JiG2G/btsBikV32yc/6brQyuCKnokMsgghk9CgxK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JiG2G/btsBikV32yc/6brQyuCKnokMsgghk9CgxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJiG2G%2FbtsBikV32yc%2F6brQyuCKnokMsgghk9CgxK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;978&quot; height=&quot;222&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;222&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실험에 사용할 저장 장치는 /dev/sdb에 있는 1TB SSD로 하도록 하겠다.&lt;/p&gt;
&lt;pre id=&quot;code_1701421089523&quot; class=&quot;vala&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;sudo fdisk /dev/sdb

# fdisk 프로그램 내에서
# 우선 기존 파티션 전부 삭제 (다 삭제될 때까지 반복 실행)
d

# 새로운 파티션 생성
n
# 본인이 희망하는 대로 설정값을 적용하도록 하자 (본인은 파티션 2개 생성)

# 설정 반영
w

# fdisk 종료 후
sudo mkfs.ext4 /dev/sdb1
sudo mkfs.ext4 /dev/sdb2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;358&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qrGcY/btsBjqg0SFi/ah5dNRq59KBIaDuXO1aIEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qrGcY/btsBjqg0SFi/ah5dNRq59KBIaDuXO1aIEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qrGcY/btsBjqg0SFi/ah5dNRq59KBIaDuXO1aIEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqrGcY%2FbtsBjqg0SFi%2Fah5dNRq59KBIaDuXO1aIEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;974&quot; height=&quot;358&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;358&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 결과 이렇게 2개의 파티션이 생성된 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Local Device로 사용할 /dev/sdb1은 이제 더 이상 건들이지 않아도 충분하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;Local Hostpath 사용을 위한 저장 장치 준비&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Local Hostpath로 사용하는 경우에는 OS의 파일 시스템을 그대로 사용하여 저장소를 관리하게 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 때문에 Hostpath 용도로 사용하고자 하는 저장 장치의 경우에는 반드시 마운트가 되어 있어야 하며 마운트 위치는 모든 노드에서 동일해야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 특성 때문에 귀찮은 점은, 하나의 StorageClass 당 하나의 마운트 위치를 사용할 수 밖에 없으며 2개 이상의 저장 장치가 한 노드에 있는 경우에는 LVM으로 하나의 가상 저장 장치로 묶어서 사용하거나 2개 이상의 StorageClass를 사용하거나 Local Device로 사용하는 수밖에는 없다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;본 예시에서는 /mnt/openebs-local이라는 곳에 마운트 위치를 만들어 /dev/sdb2를 마운트하도록 하겠다.&lt;/p&gt;
&lt;pre id=&quot;code_1701421425386&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo mkdir /mnt/openebs-local

# /dev/sdb2의 UUID 확인
sudo blkid | grep /dev/sdb2

# fstab 수정
sudo nano /etc/fstab
# 파일 최하단에 다음 내용 추가 후 저장
# UUID=&amp;lt;/dev/sdb2의 UUID&amp;gt; /mnt/openebs-local ext4 defaults 0 0

sudo mount -a
# 아마 systemctl daemon-reload인가 하라고 나올텐데 해당 명령어 실행

sudo chmod -R 777 /mnt/openebs-local&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;OpenEBS LocalPV 설치&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선은 Rocky Linux OS를 기준으로 설명하도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenEBS는 기본적으로 ISCSI 드라이버를 사용하기 때문에 ISCSI 드라이버를 설치해야하는데, Rocky Linux는 기본 설치가 된 상태이기 때문에 활성화만 해줘도 충분하다.&lt;/p&gt;
&lt;pre id=&quot;code_1701419591101&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cat /etc/iscsi/initiatorname.iscsi

sudo systemctl status iscsid

sudo systemctl enable --now iscsid&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그 다음에는 OpenEBS를 올리면 되는데, LocalPV 용도로만 사용할 경우에는 경량화된 버전을 따로 제공한다.&lt;/p&gt;
&lt;pre id=&quot;code_1701419689183&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl apply -f https://openebs.github.io/charts/openebs-operator-lite.yaml
kubectl apply -f https://openebs.github.io/charts/openebs-lite-sc.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 올린 다음에는 OpenEBS가 인식한 장치를 openebs.io/BlockDevice에서 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;952&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/co2pMR/btsBgy1mCHj/KjkEshrAu8H8ZU1CYd8pak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/co2pMR/btsBgy1mCHj/KjkEshrAu8H8ZU1CYd8pak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/co2pMR/btsBgy1mCHj/KjkEshrAu8H8ZU1CYd8pak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fco2pMR%2FbtsBgy1mCHj%2FKjkEshrAu8H8ZU1CYd8pak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;952&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;952&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 저장 장치를 자세하게 들여다보면 어떤 노드의 어떤 장치의 어떤 파티션인지 여부까지 다 나오는데, 여기서 OpenEBS가 관리하기 원치 않는 항목이 있다고 하면 미리 삭제를 해두도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 예시에서는 일부러 파티션을 나눠서 몇몇 파티션은 Local Device 용도로, 몇몇 파티션은 Local Host 용도로 사용할 것이기 때문에 각각 방법을 설명하도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;Local Device 설정 방법&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Local Device로 사용하기 위한 장치의 경우, OpenEBS가 해당 장치를 포맷하고 블록 스토리지 기반으로 완전 점유하기 때문에 불시의 상황을 예방하기 위하여 미리 사용할 장치만 따로 걸러주는 것이 안전하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해서는 우선 장치 레이블링 작업이 필요하다.&lt;/p&gt;
&lt;pre id=&quot;code_1701419913203&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl label bd -n openebs &amp;lt;장치 이름&amp;gt; openebs.io/block-device-tag=&amp;lt;태그 이름&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장치를 레이블링 한 다음에는 해당 장치만 사용하는 새로운 StorageClass를 하나 만들어주도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1701419950199&quot; class=&quot;dts&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-device
  annotations:
    openebs.io/cas-type: local
    cas.openebs.io/config: |
      - name: StorageType
        value: device
      - name: FSType
        value: ext4
      - name: BlockDeviceSelectors
        data:
          openebs.io/block-device-tag: &amp;lt;태그 이름&amp;gt;
provisioner: openebs.io/local
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성공적으로 Local Device 세팅이 되었으며 이를 사용해 Persistent Volume을 생성하였다면 아래와 같이 저장 장치가 Claimed된 상황을 확인할 수 있다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2780&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baQ3oS/btsBhVhL0U2/D9NJXV3oVAPlC4Gf9OFXUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baQ3oS/btsBhVhL0U2/D9NJXV3oVAPlC4Gf9OFXUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baQ3oS/btsBhVhL0U2/D9NJXV3oVAPlC4Gf9OFXUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaQ3oS%2FbtsBhVhL0U2%2FD9NJXV3oVAPlC4Gf9OFXUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2780&quot; height=&quot;374&quot; data-origin-width=&quot;2780&quot; data-origin-height=&quot;374&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2788&quot; data-origin-height=&quot;536&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dFJT80/btsBfbeUamy/pAjU8sHKPV2lgTG7aaNDu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dFJT80/btsBfbeUamy/pAjU8sHKPV2lgTG7aaNDu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dFJT80/btsBfbeUamy/pAjU8sHKPV2lgTG7aaNDu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdFJT80%2FbtsBfbeUamy%2FpAjU8sHKPV2lgTG7aaNDu1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2788&quot; height=&quot;536&quot; data-origin-width=&quot;2788&quot; data-origin-height=&quot;536&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;Local Hostpath 설정 방법&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Local Hostpath로 사용하기 위한 장치의 경우에는 단순하게 StorageClass 하나만 생성해주면 충분하다.&lt;/p&gt;
&lt;pre id=&quot;code_1701420030902&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-hostpath
  annotations:
    openebs.io/cas-type: local
    cas.openebs.io/config: |
      - name: StorageType
        value: hostpath
      - name: BasePath
        value: /mnt/openebs-local
provisioner: openebs.io/local
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약에 저장 장소의 마운트 위치가 다르거나 OS가 설치된 것과 같은 저장 장소를 사용하고자 하는 경우 등에는 BasePath를 본인 환경에 맞게 변경하도록 하자.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, OpenEBS로 만든 StorageClass를 기본 저장 장소로 변경하고자 하는 경우에는 아래 명령어를 사용하도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1701420134490&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 기존 기본 저장장소 해제
kubectl patch storageclass &amp;lt;이름&amp;gt; -p '{&quot;metadata&quot;: {&quot;annotations&quot;:{&quot;storageclass.kubernetes.io/is-default-class&quot;:&quot;false&quot;}}}'

# 새 기본 저장장소 지정
kubectl patch storageclass &amp;lt;이름&amp;gt; -p '{&quot;metadata&quot;: {&quot;annotations&quot;:{&quot;storageclass.kubernetes.io/is-default-class&quot;:&quot;true&quot;}}}'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;** OpenEBS 버그: 메모리 누수&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2122&quot; data-origin-height=&quot;810&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4Clyf/btsEqwgaGEs/WpN2y70bAURZ5XW6L4TLak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4Clyf/btsEqwgaGEs/WpN2y70bAURZ5XW6L4TLak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4Clyf/btsEqwgaGEs/WpN2y70bAURZ5XW6L4TLak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4Clyf%2FbtsEqwgaGEs%2FWpN2y70bAURZ5XW6L4TLak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2122&quot; height=&quot;810&quot; data-origin-width=&quot;2122&quot; data-origin-height=&quot;810&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenEBS + ElasticSearch를 운영하면서 가끔씩 ElasticSearch에 무거운 작업을 돌리면 서버가 설정된 Memory Request 및 Limit 범위를 벗어나 아예 멈춰버리는 현상이 발생하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 현상 발생 시 서버의 Calico 등도 같이 나가버려서 서버 재부팅, 심하면 서버의 k0s를 재설치하고 해당 노드 내 모든 서비스를 재시작해야만 복구가 됐는데, 정작 ElasticSearch의 메모리 사용률에는 변화가 없다는 것을 확인할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원인은 OpenEBS의 NDM Deployment 내 메모리 누수 현상으로 분명 평상시에 1GB 미만으로 메모리가 사용되어야 할 파드들이 메모리를 30GB 넘게도 먹는 것을 확인할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결방법은 상단의 OpenEBS 설치 코드를 바로 적용하지 말고 다운 받은 다음 resource 항목을 수정하여 적용해도 되고, 혹은 openebs-ndm DaemonSet 설정값에 접근하여 직접 변경하여도 된다. 설정값은 본인의 상황에 맞추어 수정하도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2120&quot; data-origin-height=&quot;532&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cf2hXG/btsExRQW5gJ/XoqklSKeyAMS4cNrVo4LqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cf2hXG/btsExRQW5gJ/XoqklSKeyAMS4cNrVo4LqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cf2hXG/btsExRQW5gJ/XoqklSKeyAMS4cNrVo4LqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcf2hXG%2FbtsExRQW5gJ%2FXoqklSKeyAMS4cNrVo4LqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2120&quot; height=&quot;532&quot; data-origin-width=&quot;2120&quot; data-origin-height=&quot;532&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2148&quot; data-origin-height=&quot;954&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHWvZR/btsEqvIjgbk/2AqcePfHzmcgv7jBoCWCy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHWvZR/btsEqvIjgbk/2AqcePfHzmcgv7jBoCWCy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHWvZR/btsEqvIjgbk/2AqcePfHzmcgv7jBoCWCy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHWvZR%2FbtsEqvIjgbk%2F2AqcePfHzmcgv7jBoCWCy1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2148&quot; height=&quot;954&quot; data-origin-width=&quot;2148&quot; data-origin-height=&quot;954&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; font-family: dotum, sans-serif; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;caret-color: #ff327f; font-size: 21px;&quot;&gt;Reference&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://openebs.io/docs/concepts/localpv&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://openebs.io/docs/concepts/localpv&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍|소프트웨어/기타</category>
      <author>테크믈리에</author>
      <guid isPermaLink="true">https://korjwl1.tistory.com/33</guid>
      <comments>https://korjwl1.tistory.com/33#entry33comment</comments>
      <pubDate>Fri, 1 Dec 2023 17:45:40 +0900</pubDate>
    </item>
    <item>
      <title>[k0s Cluster 구축] 5. k0s 클러스터에서 Rook Ceph Block Storage 사용하기</title>
      <link>https://korjwl1.tistory.com/32</link>
      <description>&lt;div style=&quot;background-color: #eeeeee; padding: 10px; border: 1px solid #c1c1c1;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;목차&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #eeeeee; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://korjwl1.tistory.com/27&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;0. Rocky Linux 8.5 설치&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #eeeeee; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://korjwl1.tistory.com/28&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;1. Ansible을 통한 기초 세팅&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #eeeeee; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://korjwl1.tistory.com/29&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2. k0s 클러스터 구축 및 OpenLens 기초 사용법&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #eeeeee; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://korjwl1.tistory.com/30&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;3. OpenLens의 기초 세팅법&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #eeeeee; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://korjwl1.tistory.com/31&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;4. k0s 클러스터에서 Nvidia GPU 사용하기&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #eeeeee; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://korjwl1.tistory.com/32&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;5. k0s 클러스터에서 Rook Ceph Block Storage 사용하기&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;Rook Ceph란?&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2320&quot; data-origin-height=&quot;1172&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Qti2m/btsBiRslhDC/ZN66xwd6fIj5orJD5bwWMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Qti2m/btsBiRslhDC/ZN66xwd6fIj5orJD5bwWMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Qti2m/btsBiRslhDC/ZN66xwd6fIj5orJD5bwWMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQti2m%2FbtsBiRslhDC%2FZN66xwd6fIj5orJD5bwWMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2320&quot; height=&quot;1172&quot; data-origin-width=&quot;2320&quot; data-origin-height=&quot;1172&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://rook.io&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://rook.io&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1701417491785&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Rook&quot; data-og-description=&quot;Storage Operators for Kubernetes Rook turns distributed storage systems into self-managing, self-scaling, self-healing storage services. It automates the tasks of a storage administrator: deployment, bootstrapping, configuration, provisioning, scaling, upg&quot; data-og-host=&quot;rook.io&quot; data-og-source-url=&quot;https://rook.io&quot; data-og-url=&quot;https://rook.io&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://rook.io&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://rook.io&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Rook&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Storage Operators for Kubernetes Rook turns distributed storage systems into self-managing, self-scaling, self-healing storage services. It automates the tasks of a storage administrator: deployment, bootstrapping, configuration, provisioning, scaling, upg&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;rook.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rook Ceph는 k8s 환경에서 가장 인기 많은 Persistence Storage 관리 방식으로, Ceph 기반 저장소를 관리하는 다수의 Agent를 자동으로 띄워 사용자가 보다 관리하기 쉽게 도와준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비교 대상으로는 Portworx, Robin, Longhorn, OpenEBS 등이 있는데, 앞선 2개는 유료이지만 강력한 저장 방식을 원할 때 사용하면 좋고 Longhorn 및 OpenEBS는 Local 저장소를 사용하여 Best-Effort로 Pod가 동작하게 하고 싶을 때 선택하는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rook Ceph는 분산 저장소이기 때문에 I/O 속도가 민감하기 보단 데이터의 안정성이 보다 중요할 때 선택하는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;caret-color: #5d5d5d; font-size: 21px;&quot;&gt;사전 준비&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1460&quot; data-origin-height=&quot;490&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cklJC7/btsBfe9ZSPH/GNu6tyW51RE9nMKw0sTUGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cklJC7/btsBfe9ZSPH/GNu6tyW51RE9nMKw0sTUGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cklJC7/btsBfe9ZSPH/GNu6tyW51RE9nMKw0sTUGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcklJC7%2FbtsBfe9ZSPH%2FGNu6tyW51RE9nMKw0sTUGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1460&quot; height=&quot;490&quot; data-origin-width=&quot;1460&quot; data-origin-height=&quot;490&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우선, 공식 홈페이지에 나온 설명대로라면 Rook Ceph를 올릴 수 있는 저장 장치 종류는 위와 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만, 실험해본 결과 순수 Raw devices와 LVM Logical Volumes 등은 잘 인식이 되지 않는 것을 확인했다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;테스트 해본 결과로는 파티션이 하나라도 생성되어 있고, 해당 파티션에 ext4 파일 포맷으로 포맷까지 해둔 경우 인식이 잘 되는 것을 확인했는데, 파티션만 있어도 되는지 혹은 ext4 등으로 포맷 해두는 것도 필수 조건인지는 모르겠다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다만, ext4로 포맷을 했을 때 잘 됐던 기억이 있기 때문에 이를 기준으로 내용을 설명하도록 하겠다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우선은, 각 노드에서 아래 명령어로 현재 장치에 연결되어 있는 디스크 현황을 확인하도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1701415688952&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 장치 이름까지 확인하려면
sudo fdisk -l

# 파티션, UUID, FSTYPE, MOUNTPOINT를 확인하려면
sudo lsblk -f&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1148&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5kZnU/btsBffHQMzb/Ija53Fwqgf4xUY09lVRNc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5kZnU/btsBffHQMzb/Ija53Fwqgf4xUY09lVRNc0/img.png&quot; data-alt=&quot;위의 사진 예시에서는 /dev/sda에 OS가 설치되어 있으며 /dev/sdb는 파티션 1개가 ext4로 포맷되었지만 마운트가 되지 않았다는 것을 알 수 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5kZnU/btsBffHQMzb/Ija53Fwqgf4xUY09lVRNc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5kZnU%2FbtsBffHQMzb%2FIja53Fwqgf4xUY09lVRNc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1148&quot; height=&quot;374&quot; data-origin-width=&quot;1148&quot; data-origin-height=&quot;374&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;위의 사진 예시에서는 /dev/sda에 OS가 설치되어 있으며 /dev/sdb는 파티션 1개가 ext4로 포맷되었지만 마운트가 되지 않았다는 것을 알 수 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위 명령어를 통하여 어떤 장치가 현재 연결되어 있고, 어떻게 파티션이 나뉘어 있고, 어떻게 포맷 되어 있는지 정보 등을 확인한 다음 Rook Ceph를 설치할 장치를 선정하도록 하자. (모든 노드에서 Rook Ceph를 설치할 디스크의 종류는 nvme, ssd, hdd 중 하나로 통일되어야 한다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 때, 유의할 것은 만약 &lt;i&gt;Rook Ceph에 사용하고 싶지 않은 장치라고 한다면 미리 어떠한 위치에든 마운트를 시켜놓는 것이 좋다는 것이다.&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Rook Ceph를 설치할 때 장치를 지정해서 설치할 수도 있지만, 귀찮다면 전체 검색 후 사용 가능한 모든 장비를 사용하게 할 수도 있는데, 이 경우 마운트 되어 있지 않고 파티션이 ext4로 포맷되어 있는 모든 장치는 Rook Ceph가 점유하게 되며 안에 들어 있는 모든 데이터는 삭제된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;가령 예를 들어, 현재 /dev/nvme0n1에 OS가 설치되어 있고 /dev/sda에 SSD가, /dev/sdb에 HDD가 연결되어 있으며 Rook Ceph를 위해서 /dev/sda만을 사용하고 싶다고 가정해보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;OS가 설치된 저장 장치는 무시하고, Rook Ceph에 사용할 /dev/sda를 먼저 보도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1701416325421&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# fdisk로 /dev/sda 해당 저장장치 선택 (sda는 예시일 뿐, 본인에 맞게 수정)
# 만약 한번도 사용한 적 없는 장치이거나 이미 FileSystem이 있는 장치라면 wipefs만 돌려도 충분하다 
sudo fdisk /dev/sda

# Command (m for help)라고 나타난 프롬프트에서 나머지 진행
# 우선 남은 파티션을 전부 삭제한다. (모든 파티션이 삭제되었다고 할 때까지 반복)
d

# 전체 파티션 삭제 후에는 새로운 파티션을 생성한다.
n
# 단일 파티션인 경우에는 엔터만 계속 입력

# 파티션 생성 후 해당 내용 확인
p

# 파티션 변경 정보 저장
w

# 파티션을 포맷한다
sudo mkfs.ext4 /dev/sda1

# 초기화
sudo wipefs -a /dev/sda1&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 진행을 하면 아래와 같이 /dev/sda가 FSTYPE이 아예 없는 상태가 되어있을 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cx86WB/btsEhkZ4VU4/VQzEyBTXx7xzFhWO6dpKC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cx86WB/btsEhkZ4VU4/VQzEyBTXx7xzFhWO6dpKC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cx86WB/btsEhkZ4VU4/VQzEyBTXx7xzFhWO6dpKC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcx86WB%2FbtsEhkZ4VU4%2FVQzEyBTXx7xzFhWO6dpKC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1128&quot; height=&quot;312&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그 다음에는 /dev/sdb를 Rook Ceph에 안 잡히게 하기 위한 방법이다.&lt;/p&gt;
&lt;pre id=&quot;code_1701416662544&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# ext4 파일 포맷으로 포맷되어 있다고 가정
# 우선, UUID값을 확인한다.
sudo blkid | grep /dev/sdb

# nano나 vi 등으로 fstab 파일 열기
sudo nano /etc/fstab

# fstab 내부 마지막 줄에 아래와 같은 내용을 삽입한다
UUID=&amp;lt;앞서 확인한 ID값&amp;gt; &amp;lt;마운트 위치&amp;gt; ext4 defaults 0 0

# 파일 저장 후 내용 반영
sudo mount -a

# 이 때, 만약 systemctl 명령어를 사용하라고 나오면 해당 명령어 그대로 실행&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 Rook Ceph에서 쓸 저장 장치는 unmount 상태로 놔두고 사용하지 않을 장치는 전부 mount 해두었다면 준비가 끝났다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Rook Ceph 설치&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우선은 Git으로부터 Rook Ceph 레포지토리를 다운받아 두자.&lt;/p&gt;
&lt;pre id=&quot;code_1701417763419&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git clone --single-branch --branch v1.13.3 https://github.com/rook/rook.git&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;본격적으로 올리기에 앞서서 Rook Ceph Operator가 k0s와 정상적으로 소통할 수 있게 파일 내용을 수정해야한다.&lt;/p&gt;
&lt;pre id=&quot;code_1701417946300&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd rook/deploy/examples

nano operator.yaml
# operator.yaml파일 수정
# ROOK_CSI_KUBELET_DIR_PATH를 찾아서 값을 &quot;/var/lib/k0s/kubelet&quot;으로 변경
# ROOK_ENABLE_DISCOVERY_DAEMON를 찾아서 true로 변경&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그 다음에는 cluster.yaml을 열어 본인 입맛에 맞게 고치도록 하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;(ex. dashboard를 ssl 없이 사용 하려면 dashboard 아래의 enabled: true / &lt;span style=&quot;background-color: #f5f5f5; color: #36464e; text-align: start;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #000000; text-align: start;&quot;&gt;mgr&lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #000000; text-align: start;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #36464e; text-align: start;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #36464e; text-align: start;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #000000; text-align: start;&quot;&gt;modules&lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #000000; text-align: start;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #36464e; text-align: start;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #36464e; text-align: start;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #000000; text-align: start;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #36464e; text-align: start;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #000000; text-align: start;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #000000; text-align: start;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #36464e; text-align: start;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #000000; text-align: start;&quot;&gt;rook&lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #36464e; text-align: start;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #36464e; text-align: start;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #000000; text-align: start;&quot;&gt;enabled&lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #000000; text-align: start;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #36464e; text-align: start;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #f5f5f5; color: #000000; text-align: start;&quot;&gt;true 추가&lt;/span&gt;)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이제 Rook Ceph를 올려보도록 하자. (RBD 기준)&lt;/p&gt;
&lt;pre id=&quot;code_1701418162985&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl apply -f crds.yaml -f common.yaml -f operator.yaml

# 위의 명령어 입력 후 Pod가 정상적으로 뜰 때까지 기다린 다음 진행
# OpenLens로 rook-ceph Namespace를 보거나 kubectl get pods -n rook-ceph --watch
kubectl apply -f cluster.yaml

# 다시 Pod들을 보면서 정상적으로 올라가는지 확인한다.
# 전부 정상적으로 올라갔다면 다음으로 진행
kubectl apply -f ./csi/rbd/storageclass.yaml

# 만약 Dashboard를 MetalLB 등으로 LoadBalancer로 접근하려면
kubectl apply -f dashboard-loadbalancer.yaml

# 만약 Node Port로 접근하려면
kubectl apply -f dashboard-external-https.yaml

# Dashboard 로그인 비밀번호 확인 방법 (아이디는 admin)
kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath=&quot;{['data']['password']}&quot; | base64 --decode &amp;amp;&amp;amp; echo

# ToolBox를 띄우는 방법
kubectl apply -f toolbox.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;정상적으로 전부 띄웠다면 대시보드에 접근 시 아래와 같은 화면을 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1919&quot; data-origin-height=&quot;1002&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9M7M0/btsBhV23ryK/gggDXnIygoUsPI0BHQrCa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9M7M0/btsBhV23ryK/gggDXnIygoUsPI0BHQrCa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9M7M0/btsBhV23ryK/gggDXnIygoUsPI0BHQrCa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9M7M0%2FbtsBhV23ryK%2FgggDXnIygoUsPI0BHQrCa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1919&quot; height=&quot;1002&quot; data-origin-width=&quot;1919&quot; data-origin-height=&quot;1002&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Rook Ceph Dashboard 설정&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;정상적으로 Rook Ceph가 올라갔다면 이제 Persistent Storage를 할당하는데 문제는 없을 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다만, cluster.yaml 값에 따라 Dashboard에 접근하여 사용하려다보면 몇몇 설정값이 안 보이면서 Orchestrator 관련 오류 문구가 뜰 것인데, 이를 해결하는 방법은 다음과 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1701418770278&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# ToolBox 진입
kubectl -n rook-ceph exec -it &amp;lt;toolbox Pod 이름&amp;gt; -- /bin/bash

ceph mgr module enable rook
ceph orch set backend rook
ceph orch status&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; font-family: dotum, sans-serif; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;caret-color: #ff327f; font-size: 21px;&quot;&gt;Reference&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.k0sproject.io/v1.28.4+k0s.0/examples/rook-ceph/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.k0sproject.io/v1.28.4+k0s.0/examples/rook-ceph/&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://rook.io/docs/rook/latest-release/Getting-Started/quickstart/#create-a-ceph-cluster&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://rook.io/docs/rook/latest-release/Getting-Started/quickstart/#create-a-ceph-cluster&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P.S. Rook Ceph를 삭제하기 위해서는 다음을 참고하자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://rook.io/docs/rook/v1.12/Getting-Started/ceph-teardown/#delete-the-block-and-file-artifacts&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://rook.io/docs/rook/v1.12/Getting-Started/ceph-teardown/#delete-the-block-and-file-artifacts&lt;/a&gt;&lt;/p&gt;</description>
      <category>프로그래밍|소프트웨어/K0S</category>
      <author>테크믈리에</author>
      <guid isPermaLink="true">https://korjwl1.tistory.com/32</guid>
      <comments>https://korjwl1.tistory.com/32#entry32comment</comments>
      <pubDate>Fri, 1 Dec 2023 17:19:35 +0900</pubDate>
    </item>
    <item>
      <title>[k0s Cluster 구축] 4. k0s 클러스터에서 Nvidia GPU 사용하기</title>
      <link>https://korjwl1.tistory.com/31</link>
      <description>&lt;div style=&quot;background-color: #eeeeee; padding: 10px; border: 1px solid #c1c1c1;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;목차&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #eeeeee; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://korjwl1.tistory.com/27&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;0. Rocky Linux 8.5 설치&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #eeeeee; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://korjwl1.tistory.com/28&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;1. Ansible을 통한 기초 세팅&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #eeeeee; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://korjwl1.tistory.com/29&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2. k0s 클러스터 구축 및 OpenLens 기초 사용법&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #eeeeee; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://korjwl1.tistory.com/30&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;3. OpenLens의 기초 세팅법&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #eeeeee; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://korjwl1.tistory.com/31&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;4. k0s 클러스터에서 Nvidia GPU 사용하기&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #eeeeee; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://korjwl1.tistory.com/32&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;5. k0s 클러스터에서 Rook Ceph Block Storage 사용하기&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;k0s 클러스터에서 Nvidia GPU를 사용하기 위해서는 Rancher 시리즈에서 했던 것과 마찬가지로 Containerd 환경 설정을 변경하고 Node Feature Discovery를 설치한 다음 GPU Operator를 설치하는 과정이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, Nvidia GPU를 가상 컨테이너에서 접근하여 사용하기 위한 전제 조건은 Nvidia GPU Driver가 설치되어 있고 Nouveau 드라이버가 꺼져 있으며 Nvidia Container Toolkit이 설치되어 있을 것인데, 이 시리즈의 1번 글인 Ansible을 통한 기초 세팅을 따라했다면 이미 해당 전제 조건은 충족되어 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;k0s Containerd 설정파일 변경&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;제일 먼저 해줄 것은 k0s의 Containerd 설정파일을 변경하여 Containerd의 기본 Runtime으로 Nvidia-Container-Runtime을 지정하는 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;보다 자세한 k0s의 Runtime 설정 방법은 하단 Reference 항목을 참고하도록 하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;제일 먼저 할 것은 우선 동작 중인 클러스터를 잠시 멈춰주는 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1700729566401&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 루트 권한
su

# 각 k0s worker 노드에 접속하여 해당 노드 종료
# 만약 --enable-worker 옵션을 줬다면 마스터에서도 종료한다
k0s stop&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그 다음으로는 각 GPU 장착된 워커노드에서&amp;nbsp;&lt;b&gt;/etc/k0s/containerd.d/nvidia.toml&lt;/b&gt; 파일을 생성하여 아래 내용을 붙여넣는다.&lt;/p&gt;
&lt;pre id=&quot;code_1700729641069&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.runtimes.nvidia]
    privileged_without_host_devices = false
    runtime_engine = &quot;&quot;
    runtime_root = &quot;&quot;
    runtime_type = &quot;io.containerd.runc.v2&quot;
[plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.runtimes.nvidia.options]
    BinaryName = &quot;/usr/bin/nvidia-container-runtime&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;붙여 넣고 &lt;b&gt;k0s start&lt;/b&gt;를 통하여 각 노드를 다시 실행해준다면 해당 설정이 적용될 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;적용 이후 다시 k0s 클러스터를 멈춰주고 &lt;b&gt;/etc/k0s/containerd.toml&lt;/b&gt; 파일을 열어보도록 하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1702&quot; data-origin-height=&quot;338&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8IrIK/btsATOCo48X/73sokkyTHo4qbpozBT8SXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8IrIK/btsATOCo48X/73sokkyTHo4qbpozBT8SXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8IrIK/btsATOCo48X/73sokkyTHo4qbpozBT8SXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8IrIK%2FbtsATOCo48X%2F73sokkyTHo4qbpozBT8SXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1702&quot; height=&quot;338&quot; data-origin-width=&quot;1702&quot; data-origin-height=&quot;338&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;파일을 열어보면 위와 같이 정의가 되어있을텐데, 내용은 결국 &lt;b&gt;/run/k0s/containerd-cri.toml&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;파일을 참조한다는 것 뿐이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이제 우리는 수동으로 설정을 적용해야하기 때문에 최상단의 &lt;span style=&quot;color: #409d00;&quot;&gt;#k0s_managed=true&lt;/span&gt;를 &lt;span style=&quot;color: #409d00;&quot;&gt;false&lt;/span&gt;로 변경해주도록 하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그 다음 &lt;b&gt;/run/k0s/containerd-cri.toml &lt;/b&gt;파일을 열어서 중간에 &lt;b&gt;nvidia.toml&lt;/b&gt; 파일에 적어두었던 내용이 삽입되어 있는지 확인해주도록 하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;236&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MWKjU/btsAPYyltxP/ZJbxRKlJ73kxIU7uwhApp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MWKjU/btsAPYyltxP/ZJbxRKlJ73kxIU7uwhApp0/img.png&quot; data-alt=&quot;vi나 nano의 검색 기능을 활용하여 .containerd.runtimes.nvidia를 검색한다면 금방 해당 내용을 찾을 수 있을 것이다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MWKjU/btsAPYyltxP/ZJbxRKlJ73kxIU7uwhApp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMWKjU%2FbtsAPYyltxP%2FZJbxRKlJ73kxIU7uwhApp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;626&quot; height=&quot;236&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;236&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;vi나 nano의 검색 기능을 활용하여 .containerd.runtimes.nvidia를 검색한다면 금방 해당 내용을 찾을 수 있을 것이다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;정상적으로 내용이 삽입되어 있다면 이번에는 &lt;b&gt;default_runtime_name&lt;/b&gt;을 검색한 다음 값을 &lt;b&gt;&quot;nvidia&quot;&lt;/b&gt;로 변경해주도록 하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDLF39/btsANt0wOMF/FDU39tygR2n6g1RvG7ssH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDLF39/btsANt0wOMF/FDU39tygR2n6g1RvG7ssH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDLF39/btsANt0wOMF/FDU39tygR2n6g1RvG7ssH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDLF39%2FbtsANt0wOMF%2FFDU39tygR2n6g1RvG7ssH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;222&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;222&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;설정을 변경하였다면 값을 저장하고 다시 &lt;b&gt;k0s start&lt;/b&gt;를 통해 클러스터를 활성화하도록 하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1182&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/M0wxe/btsAMlog06Q/iJ9GjESibZmlOETG3NYr2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/M0wxe/btsAMlog06Q/iJ9GjESibZmlOETG3NYr2K/img.png&quot; data-alt=&quot;/run/k0s/containerd-cri.toml&amp;amp;amp;nbsp;파일 내용을 덮어씌운 후의 /etc/k0s/containerd.toml 파일 내용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/M0wxe/btsAMlog06Q/iJ9GjESibZmlOETG3NYr2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FM0wxe%2FbtsAMlog06Q%2FiJ9GjESibZmlOETG3NYr2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1182&quot; height=&quot;270&quot; data-origin-width=&quot;1182&quot; data-origin-height=&quot;270&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;/run/k0s/containerd-cri.toml&amp;amp;nbsp;파일 내용을 덮어씌운 후의 /etc/k0s/containerd.toml 파일 내용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;만약 일일히 모든 GPU 워커 노드에서 이 작업을 하기 귀찮다면, 첫 노드에서만 위 작업을 진행한 다음 &lt;b&gt;/run/k0s/containerd-cri.toml &lt;/b&gt;파일 내용을 전체 복사하여 &lt;b&gt;/etc/k0s/containerd.toml&lt;/b&gt; 파일의 주석 아래 부분을 전부 지워버린 다음 덮어씌워버리자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그 다음 &lt;b&gt;/etc/k0s/containerd.toml&lt;/b&gt; 파일 내용을 전체 복사하여 굳이 &lt;b&gt;nvidia.toml&lt;/b&gt; 파일 생성 없이 바로 나머지 GPU 워커 노드의 &lt;b&gt;/etc/k0s/containerd.toml&lt;/b&gt; 파일에 똑같이 덮어 씌운 다음 k0s를 재시작해주면 정상적으로 동작할 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아래는 본인이 사용한&lt;b&gt; /etc/k0s/containerd.toml&lt;/b&gt; 파일 내용이다.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;** /etc/k0s/containerd.toml 예시&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1700730656061&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# k0s_managed=false
# This is a placeholder configuration for k0s managed containerD.
# If you wish to override the config, remove the first line and replace this file with your custom configuration.
# For reference see https://github.com/containerd/containerd/blob/main/docs/man/containerd-config.toml.5.md

version = 2

[plugins]
  [plugins.&quot;io.containerd.grpc.v1.cri&quot;]
    cdi_spec_dirs = [&quot;/etc/cdi&quot;, &quot;/var/run/cdi&quot;]
    device_ownership_from_security_context = false
    disable_apparmor = false
    disable_cgroup = false
    disable_hugetlb_controller = true
    disable_proc_mount = false
    disable_tcp_service = true
    drain_exec_sync_io_timeout = &quot;0s&quot;
    enable_cdi = false
    enable_selinux = false
    enable_tls_streaming = false
    enable_unprivileged_icmp = false
    enable_unprivileged_ports = false
    ignore_image_defined_volumes = false
    image_pull_progress_timeout = &quot;1m0s&quot;
    max_concurrent_downloads = 3
    max_container_log_line_size = 16384
    netns_mounts_under_state_dir = false
    restrict_oom_score_adj = false
    sandbox_image = &quot;registry.k8s.io/pause:3.8&quot;
    selinux_category_range = 1024
    stats_collect_period = 10
    stream_idle_timeout = &quot;4h0m0s&quot;
    stream_server_address = &quot;127.0.0.1&quot;
    stream_server_port = &quot;0&quot;
    systemd_cgroup = false
    tolerate_missing_hugetlb_controller = true
    unset_seccomp_profile = &quot;&quot;
    [plugins.&quot;io.containerd.grpc.v1.cri&quot;.cni]
      bin_dir = &quot;/opt/cni/bin&quot;
      conf_dir = &quot;/etc/cni/net.d&quot;
      conf_template = &quot;&quot;
      ip_pref = &quot;&quot;
      max_conf_num = 1
      setup_serially = false
    [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd]
      default_runtime_name = &quot;nvidia&quot;
      disable_snapshot_annotations = true
      discard_unpacked_layers = false
      ignore_blockio_not_enabled_errors = false
      ignore_rdt_not_enabled_errors = false
      no_pivot = false
      snapshotter = &quot;overlayfs&quot;
      [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.default_runtime]
        base_runtime_spec = &quot;&quot;
        cni_conf_dir = &quot;&quot;
        cni_max_conf_num = 0
        container_annotations = []
        pod_annotations = []
        privileged_without_host_devices = false
        privileged_without_host_devices_all_devices_allowed = false
        runtime_engine = &quot;&quot;
        runtime_path = &quot;&quot;
        runtime_root = &quot;&quot;
        runtime_type = &quot;&quot;
        sandbox_mode = &quot;&quot;
        snapshotter = &quot;&quot;
        [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.default_runtime.options]
      [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.runtimes]
        [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.runtimes.nvidia]
          privileged_without_host_devices = false
          runtime_engine = &quot;&quot;
          runtime_root = &quot;&quot;
          runtime_type = &quot;io.containerd.runc.v2&quot;
          [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.runtimes.nvidia.options]
            BinaryName = &quot;/usr/bin/nvidia-container-runtime&quot;
        [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.runtimes.runc]
          base_runtime_spec = &quot;&quot;
          cni_conf_dir = &quot;&quot;
          cni_max_conf_num = 0
          container_annotations = []
          pod_annotations = []
          privileged_without_host_devices = false
          privileged_without_host_devices_all_devices_allowed = false
          runtime_engine = &quot;&quot;
          runtime_path = &quot;&quot;
          runtime_root = &quot;&quot;
          runtime_type = &quot;io.containerd.runc.v2&quot;
          sandbox_mode = &quot;podsandbox&quot;
          snapshotter = &quot;&quot;
          [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.runtimes.runc.options]
            BinaryName = &quot;&quot;
            CriuImagePath = &quot;&quot;
            CriuPath = &quot;&quot;
            CriuWorkPath = &quot;&quot;
            IoGid = 0
            IoUid = 0
            NoNewKeyring = false
            NoPivotRoot = false
            Root = &quot;&quot;
            ShimCgroup = &quot;&quot;
            SystemdCgroup = false
      [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.untrusted_workload_runtime]
        base_runtime_spec = &quot;&quot;
        cni_conf_dir = &quot;&quot;
        cni_max_conf_num = 0
        container_annotations = []
        pod_annotations = []
        privileged_without_host_devices = false
        privileged_without_host_devices_all_devices_allowed = false
        runtime_engine = &quot;&quot;
        runtime_path = &quot;&quot;
        runtime_root = &quot;&quot;
        runtime_type = &quot;&quot;
        sandbox_mode = &quot;&quot;
        snapshotter = &quot;&quot;
        [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.untrusted_workload_runtime.options]
    [plugins.&quot;io.containerd.grpc.v1.cri&quot;.image_decryption]
      key_model = &quot;node&quot;
    [plugins.&quot;io.containerd.grpc.v1.cri&quot;.registry]
      config_path = &quot;&quot;
      [plugins.&quot;io.containerd.grpc.v1.cri&quot;.registry.auths]
      [plugins.&quot;io.containerd.grpc.v1.cri&quot;.registry.configs]
      [plugins.&quot;io.containerd.grpc.v1.cri&quot;.registry.headers]
      [plugins.&quot;io.containerd.grpc.v1.cri&quot;.registry.mirrors]
    [plugins.&quot;io.containerd.grpc.v1.cri&quot;.x509_key_pair_streaming]
      tls_cert_file = &quot;&quot;
      tls_key_file = &quot;&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;caret-color: #5d5d5d; font-size: 21px;&quot;&gt;Node Feature Discovery &amp;amp; GPU Operator&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;*** 만약 Helm이 아직 설치 안 되어 있다면?&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1700814999311&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우선은 Node Feature Discovery부터 올리도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1700730851472&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;helm repo add nfd https://kubernetes-sigs.github.io/node-feature-discovery/charts
helm repo update

helm install nfd/node-feature-discovery --namespace node-feature-discovery --create-namespace --generate-name&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;설치 후 정상적으로 NFD 파드들이 전부 생성될 때까지 기다린 다음 GPU Operator를 올리도록 하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우선은 GPU Operator의 Repository부터 등록하자.&lt;/p&gt;
&lt;pre id=&quot;code_1700730907330&quot; class=&quot;pgsql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;helm repo add nvidia https://nvidia.github.io/gpu-operator &amp;amp;&amp;amp; helm repo update&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음에는 k0s 값에 맞도록 values.yaml을 수정해서 설치해야하는데, 우선 gpu-operator의 전체 values.yaml을 확인하는 방법은 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1700731036017&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;helm show values nvidia/gpu-operator &amp;gt;&amp;gt; gpu-operator-values.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 values 내용 중 우리가 변경해야할 요소는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;330&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D3rkZ/btsAPy0XRF3/k4eH6M45YKMsmqGKvuQMU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D3rkZ/btsAPy0XRF3/k4eH6M45YKMsmqGKvuQMU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D3rkZ/btsAPy0XRF3/k4eH6M45YKMsmqGKvuQMU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD3rkZ%2FbtsAPy0XRF3%2Fk4eH6M45YKMsmqGKvuQMU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;990&quot; height=&quot;330&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;330&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;operator.defaultRuntime = containerd&lt;/li&gt;
&lt;li&gt;driver.enabled = false&lt;/li&gt;
&lt;li&gt;toolkit.enabled = false&lt;/li&gt;
&lt;li&gt;toolkit.env[0].name = CONTAINERD_CONFIG, toolkit.env[0].value = &quot;/etc/k0s/containerd.toml&quot;&lt;/li&gt;
&lt;li&gt;toolkit.env[1].name = &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;CONTAINERD_SOCKET&lt;/span&gt;, toolkit.env[1].value = &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&quot;/run/k0s/containerd.sock&quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;toolkit.env[2].name =&lt;span&gt; &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;CONTAINERD_RUNTIME_CLASS&lt;/span&gt;&lt;/span&gt;, toolkit.env[2].value =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&quot;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;nvidia&lt;/span&gt;&quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;toolkit.env[3].name =&lt;span&gt;&lt;span&gt; &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;CONTAINERD_SET_AS_DEFAULT&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, toolkit.env[3].value =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;위의 사진과 내용을 확인하여 valeus 파일을 수정해주도록 하자.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1700731647944&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;helm install gpu-operator -n gpu-operator --create-namespace nvidia/gpu-operator -f gpu-operator-values.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음에 위 명령어를 사용하여 GPU Operator를 설치하여주도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfyUzd/btsAMqJ21G3/cxa2XMPftiVmsR3ey9DR70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfyUzd/btsAMqJ21G3/cxa2XMPftiVmsR3ey9DR70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfyUzd/btsAMqJ21G3/cxa2XMPftiVmsR3ey9DR70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfyUzd%2FbtsAMqJ21G3%2Fcxa2XMPftiVmsR3ey9DR70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;640&quot; height=&quot;242&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;242&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성공적으로 설치되었다면, 어느 정도 시간 뒤에 Node Labels를 확인하면 위와 같이 GPU 정보가 노출될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;** 만약 보다 자세하게 GPU 환경 구축 성공 여부를 보고 싶다면?&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보다 자세하게 검증하기 위해서는 우선 아래 내용을 gpu_test.yaml 이란 이름으로 저장해주도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1700731783442&quot; class=&quot;less&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  name: ubuntu-18.04
spec:
  containers:
  - name: ubuntu
    image: nvidia/cuda:11.1.1-devel-ubuntu20.04
    command:
    - &quot;/bin/sleep&quot;
    - &quot;604800&quot;
    resources:
      limits:
        cpu: &quot;2&quot;
        memory: &quot;8G&quot;
        nvidia.com/gpu: &quot;1&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1700731818315&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl apply -f gpu_test.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음에는 위 명령어를 통하여 테스트용 Pod를 올리도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pod가 활성화 된 이후에는 아래 명령어를 통하여 테스트해볼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1700731875797&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Pod 접속
kubectl exec -it ubuntu-18.04 -- /bin/bash

# 접속 후에
nvidia-smi&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 정상적으로 nvidia-smi 결과값이 나온다면 성공이다.&lt;/p&gt;
&lt;pre id=&quot;code_1700731901193&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl delete -f gpu_test.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트가 끝난 후에는 위의 명령어로 Pod를 삭제하자.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Symlink 관련해서 오류가 나 제대로 설치되지 않는 상황이라면 gpu-operator-values.yaml에 다음 항목을 추가하도록 하자.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;624&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cc8q6t/btsEf5InWSd/sVFKfl6vCl6sWwYX3ekBLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cc8q6t/btsEf5InWSd/sVFKfl6vCl6sWwYX3ekBLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cc8q6t/btsEf5InWSd/sVFKfl6vCl6sWwYX3ekBLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcc8q6t%2FbtsEf5InWSd%2FsVFKfl6vCl6sWwYX3ekBLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1058&quot; height=&quot;624&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;624&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;pre id=&quot;code_1706692106502&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;validator:
  driver:
    env:
      - name: DISABLE_DEV_CHAR_SYMLINK_CREATION
        value: &quot;true&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; font-family: dotum, sans-serif; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f; font-family: Arial;&quot;&gt; Reference&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.k0sproject.io/v1.28.4+k0s.0/runtime/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.k0sproject.io/v1.28.4+k0s.0/runtime/&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍|소프트웨어/K0S</category>
      <author>테크믈리에</author>
      <guid isPermaLink="true">https://korjwl1.tistory.com/31</guid>
      <comments>https://korjwl1.tistory.com/31#entry31comment</comments>
      <pubDate>Thu, 23 Nov 2023 18:11:34 +0900</pubDate>
    </item>
  </channel>
</rss>