<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>인생은 여행</title>
    <link>https://shanta.tistory.com/</link>
    <description>자바 백엔드 개발이 주가 되겠지만 개발에대한 전반적인 이야기를 다루고 싶다.</description>
    <language>ko</language>
    <pubDate>Sun, 5 Jul 2026 21:06:49 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>산떠 버하둘</managingEditor>
    <image>
      <title>인생은 여행</title>
      <url>https://tistory1.daumcdn.net/tistory/4334613/attach/72c7f791697b407e86bbdcefd4f9041f</url>
      <link>https://shanta.tistory.com</link>
    </image>
    <item>
      <title>태국 삼마차</title>
      <link>https://shanta.tistory.com/23</link>
      <description>&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;565&quot; data-origin-height=&quot;584&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wbV3F/btsPEpnZKvF/3s6gllRopQAei8IK467AH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wbV3F/btsPEpnZKvF/3s6gllRopQAei8IK467AH0/img.png&quot; data-alt=&quot;태국 삼마차&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wbV3F/btsPEpnZKvF/3s6gllRopQAei8IK467AH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwbV3F%2FbtsPEpnZKvF%2F3s6gllRopQAei8IK467AH0%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;565&quot; height=&quot;584&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;565&quot; data-origin-height=&quot;584&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;태국 삼마차&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;태국 여행 중 쇼핑을 위해 BigC 마트에 갔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차에 원래 관심이 많은 터라 차 코너를 찾아 가 보았는데 마침 중년 여성분이 진열장 최상단에 위치한 차 하나를 까치발을 해가며 어렵게 꺼내서 쇼핑 카트에 담는 것이였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;얼핏 성냥곽을 연상시키는 누가 봐도 로컬 브랜드임을 알 수 있는 오색찬란한 디자인의 태국어와 한자가 섞인 포장이였다. 그리고 가격은 22밧 한국돈으로 대략 950원 정도, 용량은 40g 이였다. 호기심에 바로 카트에 담았다.&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호차'였다. 처음 포장지를 뜯어 찻잎 모양이나 향을 보았을 때 녹차라고 판단했는데 우롱차였다. 1호차는 부드럽고, 더 저렴한 3호차는 진하고 강한 맛이 난다고 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_7127.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0elWR/btsPCI99hjy/pbfjwtilpNyMAZGwvwjJhK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0elWR/btsPCI99hjy/pbfjwtilpNyMAZGwvwjJhK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0elWR/btsPCI99hjy/pbfjwtilpNyMAZGwvwjJhK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0elWR%2FbtsPCI99hjy%2FpbfjwtilpNyMAZGwvwjJhK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;461&quot; height=&quot;615&quot; data-filename=&quot;IMG_7127.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맛과 향은 부드럽고 무난했다. 즐겨 마시던 대만 우롱차 같은 독특하고 비릿한(좋아 한다) 향은 없지만 가격을 생각하면 훌륭한 수준이였다. 일상에서 부담 없이 즐기기에 충분한 맛이였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삼마차 홈페이지를 chatGPT 이용해서 찾아 보았다. &lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;홈페이지를 보면 태국에 차밭을 운영하지는 않는 것 같다. 아마 차 원료를 중국에서 가져와 가공해서 파는 형태일 것이다. 그리고 홈페이지에 삼마차 유래를 자세히 적고 있는데 흥미로웠다.&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.3horsestea.com/%E0%B8%81%E0%B8%B3%E0%B9%80%E0%B8%99-%E0%B8%94%E0%B8%8A%E0%B8%B2%E0%B8%AA%E0%B8%B2%E0%B8%A1%E0%B8%A1-%E0%B8%B2&quot;&gt;https://www.3horsestea.com/%E0%B8%81%E0%B8%B3%E0%B9%80%E0%B8%99-%E0%B8%94%E0%B8%8A%E0%B8%B2%E0%B8%AA%E0%B8%B2%E0%B8%A1%E0%B8%A1-%E0%B8%B2&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 포장 이미지를 이용해서 chatGPT를 이용해서 찾아 본 정보이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3456&quot; data-origin-height=&quot;4608&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvf88m/btsPCk9uxye/odGl20HD4lv2WZTpyHTSZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvf88m/btsPCk9uxye/odGl20HD4lv2WZTpyHTSZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvf88m/btsPCk9uxye/odGl20HD4lv2WZTpyHTSZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbvf88m%2FbtsPCk9uxye%2FodGl20HD4lv2WZTpyHTSZ0%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;358&quot; height=&quot;477&quot; data-origin-width=&quot;3456&quot; data-origin-height=&quot;4608&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용 방법 (วิธีการชงชา)&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;준비한 찻잎에 끓는 물을 붓습니다.&lt;/li&gt;
&lt;li&gt;첫 번째 물은 버리고 두 번째 물을 사용합니다.&lt;/li&gt;
&lt;li&gt;약 1분 정도 우려내면 진한 차 맛이 납니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;원재료&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ndash; 말린 찻잎 100%&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;13-2-05847-2-0001&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바코드 번호는 &lt;span&gt;&lt;b&gt;8850804000032&lt;/b&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-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTRpg3/btsPDOhphIQ/EdGBnwJfzq1xOEZQQ4fZEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTRpg3/btsPDOhphIQ/EdGBnwJfzq1xOEZQQ4fZEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTRpg3/btsPDOhphIQ/EdGBnwJfzq1xOEZQQ4fZEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTRpg3%2FbtsPDOhphIQ%2FEdGBnwJfzq1xOEZQQ4fZEK%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;600&quot; height=&quot;800&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;800&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;600&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BZScG/btsPB7WLLiO/P6XDuKH7iT5pvP4dlqSj0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BZScG/btsPB7WLLiO/P6XDuKH7iT5pvP4dlqSj0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BZScG/btsPB7WLLiO/P6XDuKH7iT5pvP4dlqSj0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBZScG%2FbtsPB7WLLiO%2FP6XDuKH7iT5pvP4dlqSj0K%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;600&quot; height=&quot;800&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;800&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;600&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bK0Pui/btsPDnErVNK/kkL4yVtmpWyHpxWywkxGpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bK0Pui/btsPDnErVNK/kkL4yVtmpWyHpxWywkxGpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bK0Pui/btsPDnErVNK/kkL4yVtmpWyHpxWywkxGpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbK0Pui%2FbtsPDnErVNK%2FkkL4yVtmpWyHpxWywkxGpK%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;600&quot; height=&quot;800&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;800&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_7120.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cT1Kqu/btsPBJaI8TU/U55iziY6NCWBt7S370SvI0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cT1Kqu/btsPBJaI8TU/U55iziY6NCWBt7S370SvI0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cT1Kqu/btsPBJaI8TU/U55iziY6NCWBt7S370SvI0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcT1Kqu%2FbtsPBJaI8TU%2FU55iziY6NCWBt7S370SvI0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;800&quot; data-filename=&quot;IMG_7120.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&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;600&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bw5YRs/btsPDp928bQ/sLDYrmQOtJEzLXGFHJiYkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bw5YRs/btsPDp928bQ/sLDYrmQOtJEzLXGFHJiYkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bw5YRs/btsPDp928bQ/sLDYrmQOtJEzLXGFHJiYkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbw5YRs%2FbtsPDp928bQ%2FsLDYrmQOtJEzLXGFHJiYkK%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;600&quot; height=&quot;800&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;800&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;이 제품은 **Three Horses Tea Co., Ltd.**에서 제조한 **&amp;ldquo;삼마차(Three Horses Tea)&amp;rdquo;**이며, 태국과 중국 전통이 결합된 유명한 브랜드입니다. 아래에 각 면의 정보를 요약해 드릴게요:&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅ 제품 기본 정보&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;제품명&lt;/b&gt;&lt;/span&gt;: ใบชาเบอร์ 1 ตราสามม้า&lt;/li&gt;
&lt;li&gt;(차잎 No.1 삼마 브랜드)&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;회사명&lt;/b&gt;&lt;/span&gt;: THREE HORSES TEA CO., LTD.&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;원산지&lt;/b&gt;&lt;/span&gt;: 태국&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;내용량&lt;/b&gt;&lt;/span&gt;: 40g&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅ 포장면별 설명&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;앞면 (마지막 사진)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;한자&lt;/b&gt;&lt;/span&gt;: 壹號萬里香&lt;/li&gt;
&lt;li&gt;&amp;rarr; &amp;ldquo;일호 만리향&amp;rdquo;으로 해석되며, &amp;ldquo;No.1 품질, 멀리 퍼지는 향기&amp;rdquo;라는 의미.&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;태국어&lt;/b&gt;&lt;/span&gt;: &amp;ldquo;차 잎 No.1 삼마 브랜드&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;옆면 (세 번째 사진)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;ldquo;차 잎 No.1은 중국차의 깊은 향과 부드러운 맛이 특징입니다&amp;rdquo;라는 내용&lt;/li&gt;
&lt;li style=&quot;color: #0e0e0e;&quot;&gt;ใบเบอร์ 1 ชากลิ่นหอมและของ ชาเป็นใบที่ให้กลิ่นชุ่มคอ ชาจีน&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;상단 (두 번째 사진)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상표 로고: 말 3마리가 원 안에 그려져 있음 &amp;rarr; &amp;ldquo;Three Horses&amp;rdquo;&lt;/li&gt;
&lt;li&gt;영어 회사명 표기: THREE HORSES TEA CO., LTD.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;뒷면 (첫 번째 사진)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;우려내는 방법&lt;/b&gt;&lt;span&gt;:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;끓는 물에 찻잎을 넣고, 첫 번째 물은 버리고 두 번째 물을 사용&lt;/li&gt;
&lt;li&gt;1분간 우려낸 후 마심&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;성분&lt;/b&gt;&lt;/span&gt;: 100% 찻잎&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;중국어 포장면 (네 번째 사진)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;큰 글씨: 三馬茶 (삼마차)&lt;/li&gt;
&lt;li&gt;회사 주소 등 전통적인 중국 스타일의 정보 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅ 요약 정리&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;제품 이름&lt;/b&gt;&lt;/span&gt;: 삼마차 (Three Horses Tea)&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/span&gt;: 중국식 향과 맛을 살린 고급 찻잎 (No.1 등급), 태국에서 생산&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;용도&lt;/b&gt;&lt;/span&gt;: 일반적인 우려 마시는 차로, 중국차 특유의 향이 강함&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;사용법&lt;/b&gt;&lt;/span&gt;: 두 번째 우려낸 물부터 마시는 것이 추천됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;태국 &lt;span&gt;&lt;b&gt;&amp;ldquo;삼마차(Three Horses Tea)&amp;rdquo;&lt;/b&gt;&lt;/span&gt; 브랜드에 대한 추가 정보를 아래에 정리해 드립니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  브랜드와 역사&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;창립 배경&lt;/b&gt;&lt;/span&gt;: 초기에는 중국과 대만산 찻잎을 수입해 직접 블렌딩하여 판매하는 소규모 사업이었으나, &lt;span&gt;&lt;b&gt;2506년(1963년) 태국 루므피니 공원 국제 박람회&lt;/b&gt;&lt;/span&gt;에서 &amp;lsquo;차 구매 시 찻잔 증정&amp;rsquo; 이벤트를 통해 대중의 관심을 획득하며 본격적으로 성장하게 됩니다&lt;span&gt;&amp;nbsp; &lt;/span&gt; .&lt;/li&gt;
&lt;li&gt;이후 &amp;ldquo;ใบชาสามม้า จำกัด(삼마차회사)&amp;rdquo;로 정식 회사명을 변경하고 &lt;span&gt;&lt;b&gt;MK, Bar B Q Plaza&lt;/b&gt;&lt;/span&gt; 등의 유명 체인점에도 납품하면서 브랜드를 확장했습니다&lt;span&gt;&amp;nbsp; &lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;매년 매출은 수억 원대 수준이며, &lt;span&gt;&lt;b&gt;베스트셀러는 No.1과 No.3 제품&lt;/b&gt;&lt;/span&gt;입니다&lt;span&gt;&amp;nbsp; &lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;제품 종류 및 특징&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;▶️ No. 1 (ใบชาเบอร์ 1)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;색이 연하고 투명하며, 깔끔한 맛&lt;/b&gt;&lt;/span&gt;이 특징으로 고급 레스토랑이나 호텔에서 사용됩니다&lt;span&gt;&amp;nbsp; &lt;/span&gt; .&lt;/li&gt;
&lt;li&gt;품질 등급이 높고 &lt;span&gt;&lt;b&gt;쓴맛이 덜하며 향이 부드럽고 목을 촉촉하게&lt;/b&gt;&lt;/span&gt; 해준다고 평가됩니다&lt;span&gt;&amp;nbsp; &lt;/span&gt; .&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;▶️ No. 3 (ใบชาเบอร์ 3)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;좀 더 &lt;span&gt;&lt;b&gt;강하게 불린 차로 색이 짙고 농도 높음&lt;/b&gt;&lt;/span&gt;, 우리나라의 우롱이나 홍차처럼 진한 풍미가 납니다.&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;가격은 저렴&lt;/b&gt;&lt;/span&gt;, 맛이 강해 길거리 음식점이나 태국식 체인에서 많이 사용됩니다&lt;span&gt;&amp;nbsp; &lt;/span&gt; .&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;맛과 브루잉 팁&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Reddit 사용자 리뷰에 따르면, No.3는 &lt;span&gt;&lt;b&gt;헤이즐넛과 말린 자두향&lt;/b&gt;&lt;/span&gt;이 느껴지는 고소하고 은은한 과일 향이 있으며, &lt;span&gt;&lt;b&gt;입 안에서 달콤함&lt;/b&gt;&lt;/span&gt;도 남는다고 합니다&lt;span&gt;&amp;nbsp; &lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;전문가와 리뷰 영상에서는 No.1도 &lt;span&gt;&lt;b&gt;2~3분 정도 충분히 우려내면&lt;/b&gt;&lt;/span&gt; 풍부한 향과 깊은 맛을 즐길 수 있다고 합니다&lt;span&gt;&amp;nbsp; &lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;브루잉 방법 (권장)&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;첫 번째 물은 바로 버리고&lt;/b&gt;&lt;/span&gt;, 두 번째 끓는 물을 사용해 &lt;span&gt;&lt;b&gt;1분 정도 우려낸 후&lt;/b&gt;&lt;/span&gt; 마시는 방식이 일반적입니다&lt;span&gt;&amp;nbsp; &lt;/span&gt; .&lt;/li&gt;
&lt;li&gt;이는 찻잎의 불순물을 제거하고 깨끗하면서도 진한 향미를 살리기 위한 방법입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;현재 라인업과 고급화 전략&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 No.1 및 No.3 제품 외에, 현재는 &lt;span&gt;&lt;b&gt;Flower‑scented oolong&lt;/b&gt;&lt;/span&gt;, &lt;span&gt;&lt;b&gt;premium delicate tea&lt;/b&gt;&lt;/span&gt; 등 다양한 고급 라인도 출시 중입니다 (100 g에 약 790~1,350 바트)&lt;span&gt;&amp;nbsp; &lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;전통 소비자층 외에도 골프장, 스파, 스페셜티 시장을 겨냥한 &lt;span&gt;&lt;b&gt;프리미엄 티 라인&lt;/b&gt;&lt;/span&gt;을 강화하고 있습니다&lt;span&gt;&amp;nbsp; &lt;/span&gt; .&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;▶️ 요약 정리&lt;/b&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;항목&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;No.1&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;No.3&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;색상 &amp;amp; 맛&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;연한 감&amp;middot;부드러운 향&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;진한 색&amp;middot;강한 향미&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;사용처&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;고급 레스토랑, 호텔&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;찐맛 좋아하는 일반 외식점&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;가격대 (80 g 기준)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;다소 고가&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;저렴 (수십 바트대)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;추천 용도&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;깔끔하고 향긋한 차&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;아이스티, 셰이크 형태&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;우림 방식&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;1분 우려, 두 번째 물 사용&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;강하게 우려도 적절&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
      <author>산떠 버하둘</author>
      <guid isPermaLink="true">https://shanta.tistory.com/23</guid>
      <comments>https://shanta.tistory.com/23#entry23comment</comments>
      <pubDate>Wed, 30 Jul 2025 00:20:08 +0900</pubDate>
    </item>
    <item>
      <title>Argo CD Core(headless mode)</title>
      <link>https://shanta.tistory.com/21</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;일반적으로 headless라 함은 모니터(GUI)가 없는 컴퓨팅 환경 또는 두뇌 역할을 하는 컨트롤 타워가 없는 상황을 이야기 합니다.&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WS9dc/btsLDlYLI1L/K5iSQMhWfjsur8tWeWCiF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WS9dc/btsLDlYLI1L/K5iSQMhWfjsur8tWeWCiF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WS9dc/btsLDlYLI1L/K5iSQMhWfjsur8tWeWCiF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWS9dc%2FbtsLDlYLI1L%2FK5iSQMhWfjsur8tWeWCiF1%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;282&quot; height=&quot;282&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;800&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;Argo CD의 아키텍처는 다음 이미지와 같이 4개의 레이어로 구분되어 있습니다. headless mode는 여기에서 Core 계층만 설치되어 작동합니다. 그래서 core 모드라고 하는 듯 합니다. 실제로 초기에 headless 라고 불리던 용어를 core로 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;대대적으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;변경하는 작업이 있었습니다. (참고 PR: &lt;a href=&quot;https://github.com/argoproj/argo-cd/pull/6819&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/argoproj/argo-cd/pull/6819&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;721&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pQqGU/btsLDK45YVs/vvB52QmENjUoyEpGvjIA10/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pQqGU/btsLDK45YVs/vvB52QmENjUoyEpGvjIA10/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pQqGU/btsLDK45YVs/vvB52QmENjUoyEpGvjIA10/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpQqGU%2FbtsLDK45YVs%2FvvB52QmENjUoyEpGvjIA10%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;502&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;721&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; Core mode는 다음 제안으로부터 시작했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;neat-enhancement-idea&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- Neat Enhancement Idea: &lt;a href=&quot;https://argo-cd.readthedocs.io/en/stable/proposals/headless-argocd/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://argo-cd.readthedocs.io/en/stable/proposals/headless-argocd/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제안서에 있는 headless라는 용어나 옵션은 후에 core로 대체되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 core 모드의 개념을 설명하는 문서입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Argo CD Core: &lt;a href=&quot;https://argo-cd.readthedocs.io/en/stable/operator-manual/core/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://argo-cd.readthedocs.io/en/stable/operator-manual/core/&lt;/a&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;Multi-Tenant 멀티 테넌트&lt;br /&gt;Argo CD 멀티 테넌트 설치는 일반적으로 많이 사용하는 방식입니다. Argo CD나 쿠버네티스 클러스터를 관리하는 플랫폼 팀 뿐 만 아니라 개발팀에서도 직접 활용할 수 있도록 Web UI를 지원하고, API를 서비스하며 자체적인 RBAC 체계를 가지고 있습니다.&lt;br /&gt;이에 반하여 Core 설치는 플랫폼 팀 만을 위한 서비스 제공을 목적으로 하며, API 서버가 설치되지 않으므로 여기에 포함된 Web UI도 서비스되지 않습니다. 보안은 쿠버네티스의 인증/인가 체계를 사용하게됩니다.&lt;br /&gt;- Multi-Tenant &amp;lt;-&amp;gt; Core&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Core 모드 설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Argo CD Core Installation:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://argo-cd.readthedocs.io/en/stable/operator-manual/installation/#core&quot;&gt;https://argo-cd.readthedocs.io/en/stable/operator-manual/installation/#core&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Core 모드에서 CLI 사용하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Core 모드로 설치된 Argo CD를 다루기 위해서는 argocd cli를 이용하게 됩니다. 이때 사용할 수 있는 옵션이 '--core' 입니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;--core 옵션&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;--core는 global 옵션입니다. 어느 명령에서든지 사용할 수 있으며, 이 경우 Argo CD API에 접속하는 것이 아니라 kubernetes API를 이용하게 됩니다. 실제로는 CLI 내부적으로 로컬에 API 서버를 띄워서 이를 이용하는 것으로 보입니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;core 로그인&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 --core 옵션을 사용하게되면 argocd cli의 기본 context가 kubernetes로 바뀌면서 앞으로의 모든 CLI 명령에 --core 옵션을 붙인 효과가 발생하게 됩니다. 이 때 실제로 kubernetes API와 상호 작용하지는 않고 단지 context 파일에 업데이트만 하는 것으로 보입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1735969223142&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl config set-context --current --namespace=argocd # change current kube context to argocd namespace
argocd login --core&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Web UI&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Core 모드에서는 API 서버와 Web UI가 제공되지 않지만 아래와 같이 CLI를 이용해서 로컬에 Web UI 서비스를 띄울 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1735972662333&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;argocd admin dashboard -n argocd&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;브라우저를 이용하여 http://localhost:8080에 접속하면 Web UI를 사용할 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드 속의 core 모드&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 코드는, cli 코드 중에 API에 접속하기위한 client를 얻는 부분(headless.NewClientOrDie)에서 core 모드 사용 여부를 염두에 두고 공통 함수를 호출하고 있습니다. 아래의 공통 함수(NewClinetOrDie)에서는 core 옵션 사용 여부에 따라 로컬 서버를 시작할 지 판단하고 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1735973301526&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;...
conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie()
defer argoio.Close(conn)
apps, err := appIf.List(ctx, &amp;amp;application.ApplicationQuery{
    Selector:     ptr.To(selector),
    AppNamespace: &amp;amp;appNamespace,
})

...

// NewClientOrDie creates a new API client from a set of config options, or fails fatally if the new client creation fails.
func NewClientOrDie(opts *apiclient.ClientOptions, c *cobra.Command) apiclient.Client {
	ctx := c.Context()

	ctxStr := initialize.RetrieveContextIfChanged(c.Flag(&quot;context&quot;))
	// If we're in core mode, start the API server on the fly and configure the client `opts` to use it.
	// If we're not in core mode, this function call will do nothing.
	err := MaybeStartLocalServer(ctx, opts, ctxStr, nil, nil, cache.RedisCompressionNone, nil)
	if err != nil {
		log.Fatal(err)
	}
	client, err := apiclient.NewClient(opts)
	if err != nil {
		log.Fatal(err)
	}
	return client
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;요약&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Argo CD에서 core와 headless는 동일한 의미이며 core가 정착된 용어로 보입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Core 모드에서는 API 서버가 설치되지 않습니다. 그러므로 API 서버에 포함된 Web UI도 서비스하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CLI에서 --core 옵션을 붙이면 현재의 kubectl context를 사용하여 kubernetes API에 요청을 보냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CLI의 --core 옵션은 Argo CD 서비스의 core 설치 여부와는 상관 없이 작동합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CLI의 login 명령에서 --core 옵션 사용은 기본 옵션으로 --core 플래그를 켠 정도의 효과만 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인증/인가는 전적으로 kubernetes의 RBAC 체계를 따릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;생각&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Argo CD Core 모드는 반대되는 개념인 멀티 테넌트 모드 대비 간소화된 설치로 클러스터의 리소스를 절약할 수 있다는 장점이 있지만 그보다는 인증/인가를 전적으로 쿠버네티스에 의존함으로써 클러스터를 관리하는 입장에서 훨씬 간결한 관리가 가능해진다는 장점이 클 것 같습니다.&lt;/p&gt;</description>
      <category>argo</category>
      <category>argocd</category>
      <category>argoproj</category>
      <category>CD</category>
      <category>core</category>
      <category>headless</category>
      <author>산떠 버하둘</author>
      <guid isPermaLink="true">https://shanta.tistory.com/21</guid>
      <comments>https://shanta.tistory.com/21#entry21comment</comments>
      <pubDate>Sat, 4 Jan 2025 16:22:32 +0900</pubDate>
    </item>
    <item>
      <title>Fixing the shutdown issue - Harman Kardon Aura Studio 2</title>
      <link>https://shanta.tistory.com/19</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Just wrapping the board with tape and cooking foil.&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;29B50112-A00A-4953-B7C7-CA927BCC2D34_1_105_c.jpeg&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l7IdO/btsydVYHWu4/BKeVOiD7pBPVBqeRBJ7S5k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l7IdO/btsydVYHWu4/BKeVOiD7pBPVBqeRBJ7S5k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l7IdO/btsydVYHWu4/BKeVOiD7pBPVBqeRBJ7S5k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl7IdO%2FbtsydVYHWu4%2FBKeVOiD7pBPVBqeRBJ7S5k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;768&quot; height=&quot;1024&quot; data-filename=&quot;29B50112-A00A-4953-B7C7-CA927BCC2D34_1_105_c.jpeg&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>하만카돈 #오라 #스튜디오 #2 #harman #kardon #aura #studio #fix #repair #수리 #shutdown #bluetooth</category>
      <author>산떠 버하둘</author>
      <guid isPermaLink="true">https://shanta.tistory.com/19</guid>
      <comments>https://shanta.tistory.com/19#entry19comment</comments>
      <pubDate>Thu, 12 Oct 2023 08:46:00 +0900</pubDate>
    </item>
    <item>
      <title>리눅스 쉘에서 사용하는 백틱(`)에 대한 고찰</title>
      <link>https://shanta.tistory.com/18</link>
      <description>&lt;div&gt;
&lt;div id=&quot;content&quot; data-inline-comments-target=&quot;true&quot; data-testid=&quot;page-content-only&quot;&gt;
&lt;div&gt;
&lt;div id=&quot;main-content&quot; data-testid=&quot;pageContentRendererTestId&quot; data-test-appearance=&quot;full-page&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h2 id=&quot;백틱(backtick)의-정의&quot; data-renderer-start-pos=&quot;1&quot; data-ke-size=&quot;size26&quot;&gt;백틱(backtick)의 정의&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-renderer-start-pos=&quot;19&quot; data-ke-size=&quot;size16&quot;&gt;IEEE Open Group의 정의에 의하면, 리눅스 쉘에서 백틱은 $()과 함께 &lt;b&gt;명령어 대체&lt;/b&gt;(command substitution)로 분류되는 표현식입니다. 백틱 또는 $() 괄호 안에 기술하는 명령어를 하위 쉘이 실행하고 그 출력 결과를 문자열로 대체하여 줍니다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;171&quot; data-ke-size=&quot;size16&quot;&gt;참고: &lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;a href=&quot;https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_03&quot; data-testid=&quot;inline-card-resolved-view&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Shell Command Language&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1669703987195&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[user1@ip-x-x-x-x ~]$ echo &quot;I am `whoami`&quot;
I am user1
[user1@ip-x-x-x-x ~]$ echo &quot;I am $(whoami)&quot;
I am user1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;권장-사항&quot; data-renderer-start-pos=&quot;301&quot; data-ke-size=&quot;size26&quot;&gt;권장 사항&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-renderer-start-pos=&quot;308&quot; data-ke-size=&quot;size16&quot;&gt;백틱은 오래된 표현법으로 중첩되는 괄호나 이스케이프 문자 관련하여 혼란이 있을 수 있으므로 &lt;b&gt;달러괄호&lt;/b&gt;-$() 표현이 권장됩니다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;참고1: &lt;span&gt;&lt;span&gt;&lt;a href=&quot;https://www.redhat.com/sysadmin/backtick-operator-vs-parens&quot; data-testid=&quot;inline-card-resolved-view&quot;&gt;&lt;span&gt;&lt;span&gt;Bash scripting: Moving from backtick operator to $ parentheses&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;389&quot; data-ke-size=&quot;size16&quot;&gt;참고2: &lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;a href=&quot;https://unix.stackexchange.com/questions/5778/whats-the-difference-between-stuff-and-stuff&quot; data-testid=&quot;inline-card-resolved-view&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;What's the difference between $(stuff) and `stuff`?&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;주의할-점&quot; data-renderer-start-pos=&quot;398&quot; data-ke-size=&quot;size26&quot;&gt;주의할 점&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-renderer-start-pos=&quot;405&quot; data-ke-size=&quot;size16&quot;&gt;명령어 대체는 현재 환경 기준으로 하위 쉘을 통해 수행되므로 만약 둘러싸고 있는 명령이 원격이나 다른 환경에서 실행된다면 서로 다른 환경에서 실행될 수 있다는 점을 유의해야 합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-testid=&quot;view-page-labels-container&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1669704069389&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[user1@ip-x-x-x-x ~]$ sudo -u root echo &quot;I am `whoami`&quot;
I am user1
[user1@ip-x-x-x-x ~]$ sudo whoami | xargs -I % echo &quot;I am %&quot;
I am root&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들면, ansible을 통하여 원격 호스트에서 쉘 명령을 수행하려고 할 때, 명령어 대체를 이용하면 대체 명령어는 ansible 호스트에서 수행되고, 그 결과와 함께 편집된 셀 명령이 원격에서 수행됩니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;pre id=&quot;code_1669705475594&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[user@ansible-server ~]$ ansible -i &amp;lt;inventory 파일&amp;gt; -m shell -a &quot;echo `hostname`&quot;
...
ansible-server
...
ansible-server
...&lt;/code&gt;&lt;/pre&gt;</description>
      <category>backtick</category>
      <category>Shell</category>
      <category>명령어 대체</category>
      <author>산떠 버하둘</author>
      <guid isPermaLink="true">https://shanta.tistory.com/18</guid>
      <comments>https://shanta.tistory.com/18#entry18comment</comments>
      <pubDate>Tue, 29 Nov 2022 15:44:20 +0900</pubDate>
    </item>
    <item>
      <title>Docker 이미지 오래된 버전 정리 스크립트</title>
      <link>https://shanta.tistory.com/17</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 서버가 하나 있는데, 빌드 과정에 docker 빌드를 수행하고 있습니다. 이 과정에서 도커 이미지가 버전별로 쌓이고 있어서 디스크 용량이 부족한 상황이였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker rmi 명령으로 이미지를 지울 수 있지만 이미지 종류도 많았고 매 번 수작업할 수도 없는 노릇입니다. 게다가 개발팀의 요구사항은 마지막 버전을 남겨두고 나머지를 삭제해 달라는 것이였습니다. 기존에 수행하던 정리작업 명령은 다음과 같았습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1643352388971&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo docker rmi \
  -f $(sudo docker images -a &amp;lt;이미지명&amp;gt; --filter &quot;before=&amp;lt;이미지명&amp;gt;:&amp;lt;최종버전&amp;gt;&quot; -q)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검색을 해 봤지만 딱히 상황에 맞는 해법을 찾을 수 없어서 쉘 스크립트를 작성하고 crontab에 등록해서 자동 수행되도록 하였습니다. 스크립트 작성도 여기 저기 검색해서 짜집기에 가깝게 작성하였는데, 더 좋은 방법이 있을지 모르겠습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;스크립트&lt;/h3&gt;
&lt;pre id=&quot;code_1643351694320&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd `dirname &quot;$0&quot;`
# 삭제 스크립트 작성
sudo docker images | \
  grep &amp;lt;이미지 필터링 패턴&amp;gt; | \
  awk '{ print $1 &quot; &quot; $2 }' | sort -V -r | awk -F' ' '!D[$1]++' | \
  awk '{ print &quot;sudo docker rmi -f $(sudo docker images -a &quot; $1 &quot; --filter \&quot;before=&quot;$1&quot;:&quot;$2&quot;\&quot; -q)&quot; }' \
  &amp;gt; clean-images.sh
# 작성된 삭제 스크립트 실행  
sh clean-images.sh
# 미사용 컨테이너 및 dangling 이미지 삭제
sudo docker container prune -f
sudo docker image prune -f&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;1. 이미지 목록에서 필터링을 통해 이름과 버전만 뽑아내고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 이걸 버전을 기준으로 정렬하여 가장 높은 버전만 추리고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 이걸 다시 docker rmi 명령으로 조합하여 스크립트 파일 clean-images.sh 을 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 이 스크립트를 실행&lt;/p&gt;</description>
      <category>Troubleshooting</category>
      <author>산떠 버하둘</author>
      <guid isPermaLink="true">https://shanta.tistory.com/17</guid>
      <comments>https://shanta.tistory.com/17#entry17comment</comments>
      <pubDate>Fri, 28 Jan 2022 15:49:18 +0900</pubDate>
    </item>
    <item>
      <title>Vault HA 구성 with Consul</title>
      <link>https://shanta.tistory.com/16</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문서는 Hashicorp 홈페이지의 &lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/ha-with-consul?in=vault/operations&quot;&gt;Vault High Availability with Consul&lt;/a&gt; 라는 문서에 주석을 더하여 번역하였습니다. 일부 오역이 있을 수 있음을 감안하여 주십시오.&lt;br /&gt;Vault는 오픈소스 버전과 유료의 Enterprise 버전이 있습니다. Vault는 오픈소스 버전 만으로도 실 업무에 사용하기에 부족함이 없을 것으로 보입니다(많이 사용해 보지는 않아서 확신은...). Vault를 프로덕트에 적용하기 위해서는 고가용성(HA) 구성이 필수적이라 할 수 있는데, &lt;s&gt;Vault 만으로는 HA 구성이 불가능하고 비밀 저장 백엔드를 Consul이나 Zookeeper 같은 서비스의 클러스터로 구성하여야 합니다&lt;/s&gt;(v1.4 부터는 raft라는 이름의 통합 저장소(Integrated Storage)를 지원하는데 이 저장소는 자체적으로 데이터 복제(replication)를 지원합니다). 이 문서는 Vault - Consul HA 구성에 대한 상세한 설명과 함께 단계적으로 따라서 해 볼 수 있는 자습서입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vault는 다중 서버 운용을 통하여 고가용성 모드에서 실행할 수 있습니다. Vault는 일반적인 컴퓨팅 요구 사항보다는 스토리지 백엔드의 IO 제한에 영향을 받습니다. Consul 같은 특정 스토리지 백엔드는 Vault가 고가용성 설정으로 실행되도록 추가적인 조정 기능을 제공하는 반면, 다른 백엔드는 보다 강력한 백업 및 복원 프로세스를 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HA 모드에서 실행할 때 Vault 서버에서는 Standby 및 Active의 두 가지 추가 상태가 있습니다. Vault 클러스터 내에서 단일 인스턴스만 Active되어 모든 요청(읽기 및 쓰기)을 처리하고 모든 Standby 노드는 요청을 Active 노드로 리디렉션합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1602&quot; data-origin-height=&quot;553&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m6AKF/btrbGz5haOj/Yn133viJLkb8fd7NXlKKF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m6AKF/btrbGz5haOj/Yn133viJLkb8fd7NXlKKF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m6AKF/btrbGz5haOj/Yn133viJLkb8fd7NXlKKF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm6AKF%2FbtrbGz5haOj%2FYn133viJLkb8fd7NXlKKF1%2Fimg.png&quot; data-origin-width=&quot;1602&quot; data-origin-height=&quot;553&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NOTE: 버전 0.11부터 Standby 노드는 read-replica 노드로써 대부분의 읽기 전용 요청을 처리할 수 있습니다. 이 Performance Standby Nodes 기능은 Vault Enterprise 기능의 일부입니다. 이는 대용량 Encryption as a Service(&lt;a href=&quot;https://www.vaultproject.io/docs/secrets/transit/index.html&quot;&gt;Transit secrets engine&lt;/a&gt;) 요청을 처리하는 데 특히 유용합니다. 자세한 내용은 &lt;a href=&quot;https://www.vaultproject.io/docs/enterprise/performance-standby/index.html&quot;&gt;Performance Standby Nodes documentation&lt;/a&gt; 및 &lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/performance-standbys&quot;&gt;Performance Standby tutorial&lt;/a&gt; 문서를 읽어 보세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;transit 엔진의 경우 실시간으로 암호화 및 복호화를 수행하기 때문에 상대적으로 CPU 자원을 많이 사용합니다. 이런 transit 요청이 많다면 active-active 클러스터를 지원하는 엔터프라이즈 기능이 필요할 수도 있겠습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에서는 기본적인 Vault 고가용성(HA) 클러스터를 구축하는 방법을 배웁니다. 이것은 드롭인 프로덕션 예제로 사용할 수 있는 완전하거나 규범적인 튜토리얼은 아니지만 자신의 프로덕션 설정을 위한 기본 사항을 충분하게 다루고 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;드롭인(drop-in) 프로덕트: 시장에 바로 진입하여 경쟁할 수 있는 상태의 제품&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;준비&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 중급 Vault 작업 튜토리얼은 귀하가 Vault 및 Consul에 대한 사전 지식을 가지고 있다고 가정합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;시나리오 소개&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리의 목표는 다음과 같이 Vault HA를 구성하는 것입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2 Vault Servers: 1 active, 1 standby&lt;/li&gt;
&lt;li&gt;3 Consul Servers 클러스터&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/reference-architecture&quot;&gt;Vault Reference Architecture&lt;/a&gt; 문서에서 권장하는 클러스터 아키텍처를 설명합니다. Vault HA 클러스터를 프로비저닝하기 위한 Terraform 모듈이 &lt;a href=&quot;https://github.com/hashicorp/vault-guides/tree/master/operations/provision-vault/best-practices/terraform-aws&quot;&gt;vault-guides&lt;/a&gt; 레포지토리에 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 자습서는, 더 나은 이해를 위해 Vault HA 클러스터를 만드는 수동 단계를 안내하는 것이 목적입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참조 다이어그램&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 다이어그램은 참조용 심플 아키텍처의 세부 정보를 보여 줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;662&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dtMS9C/btrbJIUHLyX/ydduaKxuhBPEVbI3vZX36k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dtMS9C/btrbJIUHLyX/ydduaKxuhBPEVbI3vZX36k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dtMS9C/btrbJIUHLyX/ydduaKxuhBPEVbI3vZX36k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdtMS9C%2FbtrbJIUHLyX%2FydduaKxuhBPEVbI3vZX36k%2Fimg.png&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;662&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자습서에서는 다음 절차를 수행할 것입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.notion.so/Vault-High-Availability-with-Consul-31b7d5f609154c57a162f12f5e3a636e&quot;&gt;Step 1: Setup a Consul server cluster&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.notion.so/Vault-High-Availability-with-Consul-31b7d5f609154c57a162f12f5e3a636e&quot;&gt;Step 2: Start and Verify the Consul cluster State&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.notion.so/Vault-High-Availability-with-Consul-31b7d5f609154c57a162f12f5e3a636e&quot;&gt;Step 3: Setup Consul client agents on Vault nodes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.notion.so/Vault-High-Availability-with-Consul-31b7d5f609154c57a162f12f5e3a636e&quot;&gt;Step 4: Configure the Vault servers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.notion.so/Vault-High-Availability-with-Consul-31b7d5f609154c57a162f12f5e3a636e&quot;&gt;Step 5: Start Vault and verify its state&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 자습서의 목적을 위해 Vault 및 Consul의 오픈소스 버전을 사용합니다. 그러나 설정은 엔터프라이즈 버전과 동일합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Step 1: Setup a Consul server cluster&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 자습서의 Consul 서버는 IP 주소로만 정의되지만 레이블(label)로도 참조됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;consul_s1: 10.1.42.101&lt;/li&gt;
&lt;li&gt;consul_s2: 10.1.42.102&lt;/li&gt;
&lt;li&gt;consul_s3: 10.1.42.103&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NOTE: 이 자습서에서는 Consul 바이너리가 /usr/local/bin/consul에 있다고 가정하지만, 다른 경우 경로 참조를 적절하게 조정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 염두에 두고, 기본적인 Consul 서버 구성 시작점은 다음과 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628504628276&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;server&quot;: true,
  &quot;node_name&quot;: &quot;$NODE_NAME&quot;,
  &quot;datacenter&quot;: &quot;dc1&quot;,
  &quot;data_dir&quot;: &quot;$CONSUL_DATA_PATH&quot;,
  &quot;bind_addr&quot;: &quot;0.0.0.0&quot;,
  &quot;client_addr&quot;: &quot;0.0.0.0&quot;,
  &quot;advertise_addr&quot;: &quot;$ADVERTISE_ADDR&quot;,
  &quot;bootstrap_expect&quot;: 3,
  &quot;retry_join&quot;: [&quot;$JOIN1&quot;, &quot;$JOIN2&quot;, &quot;$JOIN3&quot;],
  &quot;ui&quot;: true,
  &quot;log_level&quot;: &quot;DEBUG&quot;,
  &quot;enable_syslog&quot;: true,
  &quot;acl_enforce_version_8&quot;: false
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일부 값에는 변수 placeholer가 포함되어 있고 나머지에는 적절한 기본 값이 있습니다. 예제를 기반으로 고유한 Consul 서버 설정에서 다음 값을 바꿔야 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$NODE_NAME: 노드를 지칭하는 고유한 레이블; 여기에서는 consul_s1, consul_s2, consul_s3입니다.&lt;/li&gt;
&lt;li&gt;$CONSUL_DATA_PATH: Consul 데이터 디렉토리의 절대 경로. 이 디렉토리는 Consul 프로세스 사용자가 쓰기 가능해야 합니다.&lt;/li&gt;
&lt;li&gt;$ADVERTISE_ADDR: 해당 Consul 서버가 클러스터의 다른 서버에 알리는 것으로 선호하는 주소로 설정하되 0.0.0.0으로 설정하면 안 됩니다. 이 자습서에서는 각 Consul 서버의 주소 또는 각각 10,1.42.101, 10.1.42.102, 10.1.42.103으로 설정해야 합니다.&lt;/li&gt;
&lt;li&gt;$JOIN1, $JOIN2, $JOIN3: 이 예제에서는 클러스터를 형성하기 위해 서버 에이전트를 조인하는 retry_join 방법을 사용합니다. 따라서 이 자습서의 값은 각각 10,1.42.101, 10.1.42.102, 10.1.42.103입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 사용자 인터페이스가 활성화되어 있고(&quot;ui&quot;: true), Consul 서버는 디버깅 수준으로 시스템 로그를 남깁니다(&quot;log_level&quot;: &quot;DEBUG&quot;). 이 자습서의 목적을 위해 acl_enforce_version_8은 ACL에 대해 걱정할 필요가 없도록 false로 설정됩니다. 그러나 프로덕션 환경에서는 ACL을 활성화하고 자세한 내용은 &lt;a href=&quot;https://learn.hashicorp.com/tutorials/consul/access-control-setup-production&quot;&gt;Consul ACL Guide&lt;/a&gt;를 따르십시오.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;NOTE: Consul 에이전트 설정 파일에 대한 제세한 내용은 &lt;a href=&quot;https://www.consul.io/docs/agent/options.html#configuration-files&quot;&gt;Consul 문서&lt;/a&gt;를 참조하십시오.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 Consul 서버의 설정 파일을 생성하고 /usr/local/etc/consul/&amp;lt;node_name&amp;gt;.json으로 저장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 consul_s1.json의 예입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628504591416&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;server&quot;: true,
  &quot;node_name&quot;: &quot;consul_s1&quot;,
  &quot;datacenter&quot;: &quot;dc1&quot;,
  &quot;data_dir&quot;: &quot;/var/consul/data&quot;,
  &quot;bind_addr&quot;: &quot;0.0.0.0&quot;,
  &quot;client_addr&quot;: &quot;0.0.0.0&quot;,
  &quot;advertise_addr&quot;: &quot;10.1.42.101&quot;,
  &quot;bootstrap_expect&quot;: 3,
  &quot;retry_join&quot;: [&quot;10.1.42.101&quot;, &quot;10.1.42.102&quot;, &quot;10.1.42.103&quot;],
  &quot;ui&quot;: true,
  &quot;log_level&quot;: &quot;DEBUG&quot;,
  &quot;enable_syslog&quot;: true,
  &quot;acl_enforce_version_8&quot;: false
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 consul_s2.json의 예입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628504573098&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;server&quot;: true,
  &quot;node_name&quot;: &quot;consul_s2&quot;,
  &quot;datacenter&quot;: &quot;dc1&quot;,
  &quot;data_dir&quot;: &quot;/var/consul/data&quot;,
  &quot;bind_addr&quot;: &quot;0.0.0.0&quot;,
  &quot;client_addr&quot;: &quot;0.0.0.0&quot;,
  &quot;advertise_addr&quot;: &quot;10.1.42.102&quot;,
  &quot;bootstrap_expect&quot;: 3,
  &quot;retry_join&quot;: [&quot;10.1.42.101&quot;, &quot;10.1.42.102&quot;, &quot;10.1.42.103&quot;],
  &quot;ui&quot;: true,
  &quot;log_level&quot;: &quot;DEBUG&quot;,
  &quot;enable_syslog&quot;: true,
  &quot;acl_enforce_version_8&quot;: false
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 consul_s3.json의 예입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628504539211&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;server&quot;: true,
  &quot;node_name&quot;: &quot;consul_s3&quot;,
  &quot;datacenter&quot;: &quot;dc1&quot;,
  &quot;data_dir&quot;: &quot;/var/consul/data&quot;,
  &quot;bind_addr&quot;: &quot;0.0.0.0&quot;,
  &quot;client_addr&quot;: &quot;0.0.0.0&quot;,
  &quot;advertise_addr&quot;: &quot;10.1.42.103&quot;,
  &quot;bootstrap_expect&quot;: 3,
  &quot;retry_join&quot;: [&quot;10.1.42.101&quot;, &quot;10.1.42.102&quot;, &quot;10.1.42.103&quot;],
  &quot;ui&quot;: true,
  &quot;log_level&quot;: &quot;DEBUG&quot;,
  &quot;enable_syslog&quot;: true,
  &quot;acl_enforce_version_8&quot;: false
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 인스턴스가 서버 모드에서 실행될 것임을 나타내기 위해 server 파라미터가 true로 설정되었음을 주목하십시오.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Consul systemd 단위 파일&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Consul 바이너리와 적절한 기본 구성이 준비되었으면 이제 각 서버 인스턴스에서 Consul을 시작하기만 하면 됩니다. systemd가 대부분의 최신 Linux 배포판에서 널리 사용되는 점을 고려하여 다음과 같이 systemd 단위 파일(/etc/systemd/system/consul.service)을 구성하였습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628504487230&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;### BEGIN INIT INFO
# Provides:          consul
# Required-Start:    $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Consul agent
# Description:       Consul service discovery framework
### END INIT INFO

[Unit]
Description=Consul server agent
Requires=network-online.target
After=network-online.target

[Service]
User=consul
Group=consul
PIDFile=/var/run/consul/consul.pid
PermissionsStartOnly=true
ExecStartPre=-/bin/mkdir -p /var/run/consul
ExecStartPre=/bin/chown -R consul:consul /var/run/consul
ExecStart=/usr/local/bin/consul agent \
    -config-file=/usr/local/etc/consul/consul_s1.json \
    -pid-file=/var/run/consul/consul.pid
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
KillSignal=SIGTERM
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 값들은 스타일이나 파일시스템 계층 표준 준수 수준에 따라 변경이 필요할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;-config-file&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-pid-file&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 서버에서 단위 파일을 정의하고 저장하면, systemctl daemon-reload를 수행한 다음 Consul 서비스를 시작할 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Step 2: Start and verify the Consul cluster state&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;data_dir로 지정된 경로에 대한 소유권과 권한이 올바른지 확인한 후, 각 시스템에서 Consul 서비스를 시작하고 상태를 확인하십시오.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;systemd를 사용하여 Consul 에이전트를 시작합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628504768890&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ sudo systemctl start consul&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Consul 에이전트의 상태를 체크합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628504803539&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ sudo systemctl status consul

consul.service - Consul server agent
   Loaded: loaded (/etc/systemd/system/consul.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2019-05-23 21:48:18 UTC; 11s ago
 Main PID: 2068 (consul)
    Tasks: 13
   Memory: 13.6M
      CPU: 0m 52.784s
   CGroup: /system.slice/consul.service
           └─2068 /usr/local/bin/consul agent -config-file=/usr/local/etc/consul/server_agent.json -pid-file=/var/run/consul/consul.pid&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;모든 Consul 서버를 시작한 후 Consul 클러스터 상태를 체크합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628504974408&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ consul members

Node       Address           Status  Type    Build  Protocol  DC    Segment
consul_s1  10.1.42.101:8301  alive   server  1.0.6  2         dc1   &amp;lt;all&amp;gt;
consul_s2  10.1.42.102:8301  alive   server  1.0.6  2         dc1   &amp;lt;all&amp;gt;
consul_s3  10.1.42.103:8301  alive   server  1.0.6  2         dc1   &amp;lt;all&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클러스터의 상태가 양호해 보이고 3개의 서버가 모두 표시됩니다. 계속하기 전에 리더가 있는지 확인하십시오.&lt;/p&gt;
&lt;pre id=&quot;code_1628505014161&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ consul operator raft list-peers

Node                   ID                                    Address           State     Voter  RaftProtocol
consul_s2              536b721f-645d-544a-c10d-85c2ca24e4e4  10.1.42.102:8300  follower  true   3
consul_s1              e10ba554-a4f9-6a8c-f662-81c8bb2a04f5  10.1.42.101:8300  follower  true   3
consul_s3              56370ec8-da25-e7dc-dfc6-bf5f27978a7a  10.1.42.103:8300  leader    true   3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 출력은 이 예제에서 consul_s3가 현재 클러스터의 리더인 것을 보여줍니다. 이제 Vault 서버 설정 단계로 이동할 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Step 3: Setup Consul client agents on Vault nodes&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vault 서버에서는 각 노드에 Consul 및 Vault 바이너리가 모두 필요합니다. Consul은 클라이언트 에이전트로 구성되고 Vault는 서버로 구성됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;327&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTpZp8/btrbvbrqDwz/CSxCE3OOu8gt69LsJ3RJyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTpZp8/btrbvbrqDwz/CSxCE3OOu8gt69LsJ3RJyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTpZp8/btrbvbrqDwz/CSxCE3OOu8gt69LsJ3RJyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTpZp8%2FbtrbvbrqDwz%2FCSxCE3OOu8gt69LsJ3RJyk%2Fimg.png&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;327&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Consul 클라이언트 에이전트 구성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Consul은 고가용성 스토리지 백엔드를 제공하는 데 사용되므로, Vault 서버의 Consul 에이전트를 Consul 서버 클러스터와 통신하여 헬스체크 등록, 서비스 디스커버리, 클러스터 HA 패일오버(failover) 조정(클러스터 리더십) 하도록 구성해야 합니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Note that&amp;nbsp;&lt;a href=&quot;https://www.vaultproject.io/docs/configuration/storage/consul.html#address&quot;&gt;it is not recommended to connect the Vault servers directly to the Consul servers&lt;/a&gt;.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Consul 클라이언트 에이전트는 Consul 서버 클러서트에 대한 네트워크 통신을 위해 Vault 서버와 동일한 주소를 사용하지만 Vault가 루프백 인터페이스를 통해 연결할 수 있도록 루프백 인터페이스에만&amp;nbsp;client_address&amp;nbsp;를 바인딩합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 Consul 클라이언트 에이전트의 구성 예입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628505151087&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;server&quot;: false,
  &quot;datacenter&quot;: &quot;dc1&quot;,
  &quot;node_name&quot;: &quot;$NODE_NAME&quot;,
  &quot;data_dir&quot;: &quot;$CONSUL_DATA_PATH&quot;,
  &quot;bind_addr&quot;: &quot;$BIND_ADDR&quot;,
  &quot;client_addr&quot;: &quot;127.0.0.1&quot;,
  &quot;retry_join&quot;: [&quot;$JOIN1&quot;, &quot;$JOIN2&quot;, &quot;$JOIN3&quot;],
  &quot;log_level&quot;: &quot;DEBUG&quot;,
  &quot;enable_syslog&quot;: true,
  &quot;acl_enforce_version_8&quot;: false
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.notion.so/Vault-High-Availability-with-Consul-31b7d5f609154c57a162f12f5e3a636e&quot;&gt;Step1&lt;/a&gt;에서 수행한 작업과 유사하게 고유한 Consul 클라이언트 에이전트 구성에서 다음 값을 적절하게 바꿉니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$NODE_NAME: 노드에 대한 고유한 레이블, 여기에서는 각각 consul_c1, consul_c2가 될 것입니다.&lt;/li&gt;
&lt;li&gt;$CONSUL_DATA_PATH: Consul 데이터 디렉토리의 절대 경로, Consul 프로세스가 쓰기 가능해야 합니다.&lt;/li&gt;
&lt;li&gt;$BIND_ADDR: 이것은 Consul 서버가 클러스터의 다른 서버에 알리는 것을 선호하는 주소로 설정되어야 하며 0.0.0.0으로 설정되어서는 안 됩니다. 이 자습서의 경우 구성 파일의 각 인스턴스에 있는 Vault 서버의 IP 주소 또는 각각 10.1.42.201 및 10.1.42.202로 설정해야 합니다.&lt;/li&gt;
&lt;li&gt;$JOIN1, $JOIN2, $JOIN3: 이 예제에서는 클러스터를 형성하기 위해 서버 에이전트를 조인하는 retry_join 방법을 사용합니다. 따라서 이 자습서의 값은 각각 10,1.42.101, 10.1.42.102, 10.1.42.103입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 Consul 에이전트의 설정 파일을 생성하고 /usr/local/etc/consul/&amp;lt;node_name&amp;gt;.json으로 저장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 consul_c1.json의 예입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628505218353&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;server&quot;: false,
  &quot;datacenter&quot;: &quot;dc1&quot;,
  &quot;node_name&quot;: &quot;consul_c1&quot;,
  &quot;data_dir&quot;: &quot;/var/consul/data&quot;,
  &quot;bind_addr&quot;: &quot;10.1.42.201&quot;,
  &quot;client_addr&quot;: &quot;127.0.0.1&quot;,
  &quot;retry_join&quot;: [&quot;10.1.42.101&quot;, &quot;10.1.42.102&quot;, &quot;10.1.42.103&quot;],
  &quot;log_level&quot;: &quot;DEBUG&quot;,
  &quot;enable_syslog&quot;: true,
  &quot;acl_enforce_version_8&quot;: false
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1628505229855&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;server&quot;: false,
  &quot;datacenter&quot;: &quot;dc1&quot;,
  &quot;node_name&quot;: &quot;consul_c2&quot;,
  &quot;data_dir&quot;: &quot;/var/consul/data&quot;,
  &quot;bind_addr&quot;: &quot;10.1.42.202&quot;,
  &quot;client_addr&quot;: &quot;127.0.0.1&quot;,
  &quot;retry_join&quot;: [&quot;10.1.42.101&quot;, &quot;10.1.42.102&quot;, &quot;10.1.42.103&quot;],
  &quot;log_level&quot;: &quot;DEBUG&quot;,
  &quot;enable_syslog&quot;: true,
  &quot;acl_enforce_version_8&quot;: false
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 인스턴스가 클라이언트 모드에서 실행될 것임을 나타내기 위해 server 매개변수가 false로 설정되어 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Consul systemd 단위 파일&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Consul 바이너리와 적절한 기본 구성이 준비되었으면 이제 각 서버 인스턴스에서 Consul을 시작하기만 하면 됩니다. 다음과 같이 systemd 단위 파일을 구성하였습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628505266880&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;### BEGIN INIT INFO
# Provides:          consul
# Required-Start:    $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Consul agent
# Description:       Consul service discovery framework
### END INIT INFO

[Unit]
Description=Consul client agent
Requires=network-online.target
After=network-online.target

[Service]
User=consul
Group=consul
PIDFile=/var/run/consul/consul.pid
PermissionsStartOnly=true
ExecStartPre=-/bin/mkdir -p /var/run/consul
ExecStartPre=/bin/chown -R consul:consul /var/run/consul
ExecStart=/usr/local/bin/consul agent \
    -config-file=/usr/local/etc/consul/consul_c1.json \
    -pid-file=/var/run/consul/consul.pid
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
KillSignal=SIGTERM
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요에 따라 다음 값을 변경하십시오.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;config-file&lt;/li&gt;
&lt;li&gt;pid-file&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 Vault 서버에서 단위 파일을 정의하고 저장하면(예, /etc/systemd/system/consul.service), systemctl daemon-reload를 수행한 다음 Consul 서비스를 시작할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Consul을 시작하고 해당 클러스터 상태를 확인하여 설정에서 data_dir 값으로 지정한 경로의 소유권과 권한이 올바른지 확인한 다음, 각 시스템에서 Consul 서비스를 시작하고 상태를 확인합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628505337214&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ sudo systemctl start consul
$ sudo systemctl status consul

consul.service - Consul client agent
   Loaded: loaded (/etc/systemd/system/consul.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2019-05-23 21:48:18 UTC; 11s ago
 Main PID: 23758 (consul)
    Tasks: 11
   Memory: 9.8M
      CPU: 571ms
   CGroup: /system.slice/consul.service
           └─23758 /usr/local/bin/consul agent -config-file=/usr/local/etc/consul/client_agent.json -pid-file=/var/run/consul/consul.pid&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 Consul 클라이언트 에이전트를 시작하고 나서 Consul 클러스터의 상태를 체크합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628505383057&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ consul members

Node        Address           Status  Type    Build  Protocol  DC    Segment
consul_s1   10.1.42.101:8301  alive   server  1.0.6  2         dc1   &amp;lt;all&amp;gt;
consul_s2   10.1.42.102:8301  alive   server  1.0.6  2         dc1   &amp;lt;all&amp;gt;
consul_s3   10.1.42.103:8301  alive   server  1.0.6  2         dc1   &amp;lt;all&amp;gt;
consul_c1   10.1.42.201:8301  alive   client  1.0.6  2         arus  &amp;lt;default&amp;gt;
consul_c2   10.1.42.202:8301  alive   client  1.0.6  2         arus  &amp;lt;default&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;NOTE: Consul 클러스터 아키텍처에 대해 더 배우고자 한다면 &lt;a href=&quot;https://learn.hashicorp.com/tutorials/consul/reference-architecture&quot; data-token-index=&quot;1&quot; data-reactroot=&quot;&quot;&gt;Consul Reference Architecture&lt;/a&gt; 자습서를 참고하십시오. 또한 Consul 클러스터 배포에 대해 자세한 내용은 &lt;a href=&quot;https://learn.hashicorp.com/tutorials/consul/deployment-guide&quot; data-token-index=&quot;3&quot; data-reactroot=&quot;&quot;&gt;Deployment Guide&lt;/a&gt;를 참고하십시오.&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Step 4: Configure the Vault servers&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 Vault 서버를 위한 3개의 서버와 2개의 클라이언트 에이전트로 구성된 Consul 클러스터가 있으므로 Vault HA 설정을 부트스트랩할 수 있도록 Vault에 대한 구성과 시작 스크립트를 함께 가져와 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 튜토리얼의 Vault 서버는 IP 주소로만 정의되지만 레이블로도 참조됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;vault_s1: 10.1.42.201&lt;/li&gt;
&lt;li&gt;vault_s2: 10.1.42.202&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구성 파일에서 다음을 설정합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;tcp 리스너&lt;/li&gt;
&lt;li&gt;consul 스토리지 백엔드&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/configuration/index.html#high-availability-parameters&quot;&gt;High Availability parameters&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 섹션에서는 Vault 바이너리가 /usr/local/bin/vault에 있다고 가정합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Vault 구성&lt;/h3&gt;
&lt;pre id=&quot;code_1628505512066&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;listener &quot;tcp&quot; {
  address          = &quot;127.0.0.1:8200&quot;
  cluster_address  = &quot;127.0.0.1:8201&quot;
  tls_disable      = &quot;true&quot;
}

storage &quot;consul&quot; {
  address = &quot;127.0.0.1:8500&quot;
  path    = &quot;vault/&quot;
}

api_addr =  &quot;$API_ADDR&quot;
cluster_addr = &quot;$CLUSTER_ADDR&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;이 자습서에서는 리스너 절에서 TLS를 비활성화하지만 프로덕션 환경에서 클라이언트와 Vault 서버 간의 안전한 통신을 위해서는 항상 &lt;a href=&quot;https://www.vaultproject.io/docs/configuration/listener/tcp#tls_cert_file&quot;&gt;TLS와 함께 사용&lt;/a&gt;하여야 합니다. 이를 위해서는 각 Vault 호스트마다 인증서 파일과 키 파일이 필요합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tcp 리스너에서 다음의 파라미터를 설정합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;address (string: &quot;127.0.0.1:8200&quot;): 수신을 위해 바인딩할 주소를 지정합니다.&lt;/li&gt;
&lt;li&gt;cluster_address (string: &quot;127.0.0.1:8201&quot;): 클러스터 서버 간 요청에 대해 바인딩할 주소를 지정합니다. 이는 기본적으로 address 포트 값보다 1 높은 수치입니다. 일반적으로 설정할 필요는 없지만 Vault 서버가 서로 격리되어 TCP 로드발란서 또는 다른 체계를 경유(hop)하여 통신해야하는 경우 필요할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구성을 사용하면 모든 인터페이스에서 수신 대기할 수 있습니다(예, 루프백 주소에 대한 Vault 명령이 성공함).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 Vault의 HA 파라미터(api_addr 및 cluster_addr)를 명시적으로 설정하고 있습니다. Consul을 Vault의 스토리지 백엔드로 사용할 때, 경우에 따라 Consul이 자동으로 active Vault 노드의 주소를 찾고 전파하려고 시도하므로 이 두 파라미터를 구성할 필요가 없습니다. 그러나 어떤 클러스터 구성에서는 명시적으로 설정할 필요가 있습니다(예, 로드발란서(LB)를 통한 Vault 접근).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순화를 위하여, 이 시나리오에서는 로드발란서를 통해서 접속하는 대신에 Vault 노드에 직접 접속하는 것으로 하겠습니다. 클라이언트 접근 패턴과 그 의미에 대한 자세한 내용은 &lt;a href=&quot;https://www.vaultproject.io/docs/concepts/ha.html#client-redirection&quot;&gt;Client Redirection&lt;/a&gt; 문서를 검토하십시오.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일부 값들은 변수 placeholder가 포함되어 있고 나머지에는 적절한 기본값이 있습니다. 다음의 값들은 예제에 기반하여 각자의 Vault 서버 구성에 맞는 값으로 변경하십시오.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$API_ADDR: 클라이언트 리디렉션을 위해 다른 Vault 서버에게 통지할 주소(full URL). 환경 변수 VAULT_API_ADDR을 통해 제공될 수도 있습니다. 일반적으로 이것은 리스너 주소 값을 가리키는 전체 URL로 설정해야 합니다. 이 시나리오에서는 각각 http://10.1.42.201:8200 와 http://10.1.42.202:8200이 되어야 합니다.&lt;/li&gt;
&lt;li&gt;$CLUSTER_ADDR: 요청 전달을 위해 클러스터의 다른 Vault 서버에 광고할 주소를 지정합니다. 이는 환경 변수 VAULT_CLUSTER_ADDR을 통해 제공될 수도 있습니다. 이것은 api_addr과 같은 전체 URL입니다. 이 시나리오에서는 각각 https://10.1.42.201:8201 및 https://10.1.42.202:8201이 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;여기에 있는 scheme(https)는 무시됩니다. 모든 클러스터 구성원은 항상 개인키/인증서 쌍과 함께 TLS를 사용합니다.&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;vault_s1.hcl 예제&lt;/h3&gt;
&lt;pre id=&quot;code_1628505585589&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;listener &quot;tcp&quot; {
  address          = &quot;0.0.0.0:8200&quot;
  cluster_address  = &quot;10.1.42.201:8201&quot;
  tls_disable      = &quot;true&quot;
}

storage &quot;consul&quot; {
  address = &quot;127.0.0.1:8500&quot;
  path    = &quot;vault/&quot;
}

api_addr = &quot;http://10.1.42.201:8200&quot;
cluster_addr = &quot;https://10.1.42.201:8201&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;vault_s2.hcl 예제&lt;/h3&gt;
&lt;pre id=&quot;code_1628505624704&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;listener &quot;tcp&quot; {
  address          = &quot;0.0.0.0:8200&quot;
  cluster_address  = &quot;10.1.42.202:8201&quot;
  tls_disable      = &quot;true&quot;
}

storage &quot;consul&quot; {
  address = &quot;127.0.0.1:8500&quot;
  path    = &quot;vault/&quot;
}

api_addr = &quot;http://10.1.42.202:8200&quot;
cluster_addr = &quot;https://10.1.42.202:8201&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Vault 서버 systemd 단위 파일&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vault 바이너리와 함께 적절하게 Consul 로컬 클라이언트 에이전트로 구성한 기본 설정이 있습니다. 이제 각 서버 인스턴스에서 Vault를 시작하기만 하면 됩니다. 다음은 systemd 단위 파일의 예입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628505639154&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;### BEGIN INIT INFO
# Provides:          vault
# Required-Start:    $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Vault server
# Description:       Vault secret management tool
### END INIT INFO

[Unit]
Description=Vault secret management tool
Requires=network-online.target
After=network-online.target

[Service]
User=vault
Group=vault
PIDFile=/var/run/vault/vault.pid
ExecStart=/usr/local/bin/vault server -config=/etc/vault/vault_server.hcl -log-level=debug
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
KillSignal=SIGTERM
Restart=on-failure
RestartSec=42s
LimitMEMLOCK=infinity

[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 값들은 스타일이나 파일시스템 계층 표준 준수 수준에 따라 변경이 필요할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;-config-file&lt;/li&gt;
&lt;li&gt;-pid-file&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 서버에서 단위 파일을 /etc/systemd/system/vault.service 같은 파일로 정의하고 저장하면, systemctl daemon-reload를 수행한 다음 Vault 서비스를 시작할 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Step 5: Start Vault and verify its State&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 서버에서 Vault 서비스를 시작하십시오.&lt;/p&gt;
&lt;pre id=&quot;code_1628505737777&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ sudo systemctl start vault
$ sudo systemctl status vault

vault.service - Vault secret management tool
   Loaded: loaded (/etc/systemd/system/vault.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2019-05-23 21:48:18 UTC; 11s ago
 Main PID: 2080 (vault)
    Tasks: 12
   Memory: 71.7M
      CPU: 50s
   CGroup: /system.slice/vault.service
           └─2080 /usr/local/bin/vault server -config=/home/ubuntu/vault_nano/config/vault_server.hcl -log-level=debug&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 Vault 서버를 &lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/getting-started-deploy#initializing-the-vault&quot;&gt;초기화&lt;/a&gt;하고 &lt;a href=&quot;https://www.vaultproject.io/docs/concepts/seal&quot;&gt;봉인해제&lt;/a&gt;할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vault 초기화&lt;/p&gt;
&lt;pre id=&quot;code_1628505835507&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vault operator init&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 Consul에서 저장소를 준비하고 active Vault 서버를 결정합니다. 기본적으로 초기화 프로세스에서는 인메모리 마스터키가 생성되고 Shamir의 비밀 공유 알고리즘을 적용하여 해당 마스터키를 분해합니다. 마스터키를 분해하기 위해서 설정에 있는 키공유(key shares) 값 만큼 봉인해제 키가 생성되어 사용됩니다. 봉인해제, 즉 마스터키를 재조립하기 위해서는 마찬가지로 설정에 있는 쿼럼 형성 수 만큼의 봉인해제 키가 필요합니다. 기본적으로 5개의 키가 공유되고 봉인해제를 위한 쿼럼 형성에는 3개의 공유키가 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클러스터 내 각 Vault 서버는 이러한 봉인해제 키를 사용할 수 있으며 각 Vault 서버는 사용하기 전에 봉인을 해제해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 기본 초기화의 출력 예입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628505857188&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Unseal Key 1: mK3KawqyUfzaxF+cvH7PjvUQENhWSawvydi9aZpcJZpO
Unseal Key 2: Ptzj1SuPwY/kMl2soujwnelBiMP6oizAMDkEN9O/5EKd
Unseal Key 3: 4BTEyTEU+ffDQMKZzTIuZcbZfH0jKEk8nN04RDiTI4z9
Unseal Key 4: zi8m4wlzya6PKV8fFdl//OtIPrmascpBnfcKAlwdx3MM
Unseal Key 5: 264hCHpfTC4N/dURRjht9RyFsW0tUq647q3A022Z+qyC

Initial Root Token: s.NiJ2kO6H49ckdNBsMiXyo7uR

Vault initialized with 5 key shares and a key threshold of 3. Please securely
distribute the key shares printed above. When the Vault is re-sealed,
restarted, or stopped, you must supply at least 3 of these keys to unseal it
before it can start servicing requests.

Vault does not store the generated master key. Without at least 3 key to
reconstruct the master key, Vault will remain permanently sealed!

It is possible to generate new unseal keys, provided you have a quorum of
existing unseal keys shares. See &quot;vault operator rekey&quot; for more information.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력에는 나중에 Vault에 인증할 수 있는 초기 루트 토큰도 포함됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vault를 성공적으로 초기화했으므로 먼저 vault_s1 서버의 봉인을 해제하십시오.&lt;/p&gt;
&lt;pre id=&quot;code_1628505883195&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vault operator unseal &amp;lt;unseal_key_1&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임계 값에 도달할 때까지 다른 봉인해제 키를 입력하십시오.&lt;/p&gt;
&lt;pre id=&quot;code_1628505901677&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vault operator unseal &amp;lt;unseal_key_2&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임계 값 만큼 봉인해제 키를 입력하면 Vault 서버는 봉인해제되어 사용할 수 있는 상태가 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628505943991&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vault operator unseal &amp;lt;unseal_key_3&amp;gt;

Key                    Value
---                    -----
Seal Type              shamir
Initialized            true
Sealed                 false
Total Shares           5
Threshold              3
Version                1.4.0-rc1
Cluster Name           vault-cluster-5f9488de
Cluster ID             4175d4b0-58d4-f60d-1488-9860f2d53e9b
HA Enabled             true
HA Cluster             n/a
HA Mode                standby
Active Node Address    &amp;lt;none&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 Vault를 초기화할 때 생성 및 출력된 봉인해제 키를 사용하여 두 번째 Vault 서버(vault_s2)를 봉인해제하십시오.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Standby Vault 서버에서 Vault 상태를 체크하십시오.&lt;/p&gt;
&lt;pre id=&quot;code_1628505965939&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vault status

Key                    Value
---                    -----
Seal Type              shamir
Initialized            true
Sealed                 false
Total Shares           5
Threshold              3
Version                1.4.0-rc1
Cluster Name           vault-cluster-5f9488de
Cluster ID             4175d4b0-58d4-f60d-1488-9860f2d53e9b
HA Enabled             true
HA Cluster             https://10.1.42.201:8201
HA Mode                standby
Active Node Address:   http://10.1.42.201:8200&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 시점에서 Vault 서버는 HA 모드에서 작동하며 active 또는 standby Vault 인스턴스에서 비밀을 쓸 수 있어야 하며 요청 전달 테스트로 성공했는지 확인할 수 있습니다. 또한 active 인스턴스를 종료(sudo systemctl stop vault)하여 시스템 오류를 시뮬레이션하고 standby 인스턴스가 리더십을 차지하는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Help and Reference&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/concepts/ha.html&quot;&gt;High Availability Mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/configuration/storage/consul.html&quot;&gt;Consul Storage Backend&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/configuration/index.html#high-availability-parameters&quot;&gt;High Availability Parameters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.consul.io/docs/agent/options.html&quot;&gt;Consul Agent Configuration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;NOTE: &lt;a href=&quot;https://github.com/hashicorp/vault-guides/tree/master/operations/provision-vault/best-practices/terraform-aws&quot;&gt;Provision a Best Practices Vault Cluster in AWS&lt;/a&gt; 에서는 AWS에서 Vault HA 클러스터를 프로비저닝하기 위한 Terraform 자산을 제공합니다. 최소 3개의 가용 영역(AZs)이 있는 AWS 리전을 선택해야 합니다.&lt;/blockquote&gt;</description>
      <category>Vault</category>
      <category>cluster</category>
      <category>CONSUL</category>
      <category>HA</category>
      <category>high availability</category>
      <category>Vault</category>
      <category>고가용성</category>
      <category>클러스터</category>
      <author>산떠 버하둘</author>
      <guid isPermaLink="true">https://shanta.tistory.com/16</guid>
      <comments>https://shanta.tistory.com/16#entry16comment</comments>
      <pubDate>Mon, 9 Aug 2021 18:46:55 +0900</pubDate>
    </item>
    <item>
      <title>Vault KV Secrets Engine</title>
      <link>https://shanta.tistory.com/15</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Vault는 어플리케이션 내의 데이터베이스 접속 비밀번호나 API 접근 토근 같은 민감한 정보를 저장할 수 있도록 Key-Value 저장소를 지원합니다. 이 kv 저장소는 두 가지 모드를 지원하는데 v1과 v2가 그것입니다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;128&quot; data-ke-size=&quot;size16&quot;&gt;각 버전은 스토리지 생성시 목적에 맞게 취사 선택이 가능합니다.&lt;/p&gt;
&lt;h3 id=&quot;KV-Version-1&quot; data-renderer-start-pos=&quot;165&quot; data-ke-size=&quot;size23&quot;&gt;KV Version 1&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;버전 관리 없음&lt;/li&gt;
&lt;li&gt;버전 메타 정보가 없기 때문에 저장 공간 절약&lt;/li&gt;
&lt;li&gt;스토리지 호출이 적고 잠금이 없기 때문에 성능에 이득&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/secrets/kv/kv-v1&quot; data-renderer-mark=&quot;true&quot;&gt;KV Secrets Engine - Version 1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;KV-Version-2&quot; data-renderer-start-pos=&quot;288&quot; data-ke-size=&quot;size23&quot;&gt;KV Version 2&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;버전 관리 있음&lt;/li&gt;
&lt;li&gt;기본 10개 버전까지 관리되고 설정 가능&lt;/li&gt;
&lt;li&gt;삭제해도 저장소에서 제거되지 않고 삭제된 것으로 표시, 완전 제거를 위해서는 destory 명령 사용&lt;/li&gt;
&lt;li&gt;ACL 정책 설정시 아래처럼 data, metadata 같은 prefix를 사용하여야 합니다&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1626883763600&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Read-only permit for /kv/sample
path &quot;kv/data/sample/*&quot; {
  capabilities = [ &quot;read&quot; ]
}
path &quot;kv/metadata/sample/*&quot; {
  capabilities = [ &quot;list&quot; ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/secrets/kv/kv-v2&quot; data-renderer-mark=&quot;true&quot;&gt;KV Secrets Engine - Version 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;참고&quot; data-renderer-start-pos=&quot;643&quot; data-ke-size=&quot;size23&quot;&gt;참고&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span data-inline-card=&quot;true&quot; data-card-url=&quot;https://www.vaultproject.io/docs/secrets/kv&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/secrets/kv&quot; data-testid=&quot;inline-card-resolved-view&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;KV - Secrets Engines | Vault by HashiCorp&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Vault</category>
      <category>KV</category>
      <category>Secrets</category>
      <category>Vault</category>
      <author>산떠 버하둘</author>
      <guid isPermaLink="true">https://shanta.tistory.com/15</guid>
      <comments>https://shanta.tistory.com/15#entry15comment</comments>
      <pubDate>Thu, 22 Jul 2021 01:11:34 +0900</pubDate>
    </item>
    <item>
      <title>Vault Seal/Unseal</title>
      <link>https://shanta.tistory.com/14</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Vault 서버는 sealed(봉인) 상태로 시작 됩니다. 이 상태에서 저장된 정보는 어떤 경우에도 평문으로 볼 수 없습니다. Unsealing(개봉) 전에는 거의 모든 작업이 불가능합니다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;109&quot; data-ke-size=&quot;size16&quot;&gt;Vault 데이터를 암호화하여 저장합니다. 암호화 키로 데이터를 암호화하고 이 암호화키는 키링에 보관하여 데이터와 함께 저장합니다. 이 키링은 마스터 키로 알려진 다른 암호화 키로 암호화합니다. 따라서 Vault는 데이터를 복호화하기 위하여 먼저 암호화 키를 마스터 키를 이용하여 복호화하여야 합니다. Unsealing(복호화)는 이 마스터 키에 접근하는 프로세스입니다. 마스터 키도 다른 모든 데이터와 함께 저장되지만 또 다른 메커니즘인 봉인해제 키(unseal key)에 의해 암호화됩니다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;387&quot; data-ke-size=&quot;size16&quot;&gt;요약하면, 데이터는 키링의 암호화 키로, 암호화 키는 마스터 키로, 마스터 키는 봉인해제 키로 암호화됩니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-renderer-start-pos=&quot;450&quot; data-ke-size=&quot;size16&quot;&gt;봉인해제 키 &amp;rarr; 마스터 키 &amp;rarr; 암호화 키 &amp;rarr; 데이터&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;Shamir&amp;rsquo;s-Secret-Sharing-샤미르의-비밀-공유&quot; data-renderer-start-pos=&quot;490&quot; data-ke-size=&quot;size23&quot;&gt;Shamir&amp;rsquo;s Secret Sharing 샤미르의 비밀 공유&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-renderer-start-pos=&quot;526&quot; data-ke-size=&quot;size16&quot;&gt;봉인해제 키는 &lt;a href=&quot;https://ehdvudee.tistory.com/27&quot; data-renderer-mark=&quot;true&quot;&gt;샤미르의 비밀 공유&lt;/a&gt; 알고리즘을 사용하여 여러 조각으로 분할되어 생성됩니다(RSA에 'S'의 그 Shamir 맞다). 각 봉인해제 키는 분리된 공간에 저장할 것을 권장하며 봉인해제 시에 각 키를 입력 받아 임계치 이상의 키가 입력이 되면 봉인해제되는 방식입니다. Vault에서는 기본 값으로 5개의 키가 생성이 되고, 3개의 키가 입력되면 봉인해제됩니다.&lt;/p&gt;
&lt;h3 id=&quot;Unsealing-봉인해제&quot; data-renderer-start-pos=&quot;733&quot; data-ke-size=&quot;size23&quot;&gt;Unsealing 봉인해제&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-renderer-start-pos=&quot;749&quot; data-ke-size=&quot;size16&quot;&gt;봉인해제는 다음의 과정 중 하나를 통하여 수행합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;터미널에서 vault operator unseal 명령을 입력 후 봉인해제 키를 차례로 입력&lt;/li&gt;
&lt;li&gt;Unseal API 호출&lt;/li&gt;
&lt;li&gt;WebUI에서 키를 차례로 입력&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-renderer-start-pos=&quot;875&quot; data-ke-size=&quot;size16&quot;&gt;봉인해제 상태에서 다시 봉인 상태가 되는 경우는 다음 중 하나입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Seal API 호출&lt;/li&gt;
&lt;li&gt;Vault 서버 재시작&lt;/li&gt;
&lt;li&gt;Vault 저장소에서 복구할 수 없는 오류가 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;Sealing-봉인&quot; data-renderer-start-pos=&quot;979&quot; data-ke-size=&quot;size23&quot;&gt;Sealing 봉인&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-renderer-start-pos=&quot;991&quot; data-ke-size=&quot;size16&quot;&gt;봉인 API를 호출하면 메모리에 있는 마스터 키가 폐기되고 이를 복원하기 위해서는 봉인해제 과정이 필요합니다. 봉인에는 루트 권한이 있는 단일 작업자만 필요합니다. 이렇게 하면 침입이 감지되었을 때 Vault 데이터를 빠르게 잠가 피해를 최소화할 수 있습니다.&lt;/p&gt;
&lt;h3 id=&quot;Auto-Unseal-자동-봉인해제&quot; data-renderer-start-pos=&quot;1138&quot; data-ke-size=&quot;size23&quot;&gt;Auto Unseal 자동 봉인해제&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-renderer-start-pos=&quot;1159&quot; data-ke-size=&quot;size16&quot;&gt;Auto Unseal은 봉인해제 키를 안전하게 보관하는 작업의 복잡성을 줄이기 데 도움이 되도록 개발되었습니다. 이 기능은 봉인해제 키를 안전하게 보관해야하는 사용자의 책임을 신뢰할 수 있는 장치나 서비스에게 위임합니다. Vault 기동시 봉인 기능을 구현하고 있는 장치나 서비스에 접속하여 마스터 키 해독을 요청합니다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;1340&quot; data-ke-size=&quot;size16&quot;&gt;Vault에서는 사용자 쿼럼이 수행해야하는 작업 중, 봉인해제 외에 루트 키 생성 같은 작업이 있습니다. Shamir 봉인을 사용할 때 이러한 작업을 승인하려면 봉인해제 키를 제공해야합니다. Auto unseal을 사용하는 경우에는 대신에 recovery key(복구 키)가 필요합니다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;1503&quot; data-ke-size=&quot;size16&quot;&gt;Shamir 봉인을 사용한 초기화 프로세스에서 봉인해제 키가 생성되는 것처럼 자동 봉인해제로 초기화하면 복구 키가 생성됩니다. 복구 키는 마스터 키를 해독할 수 없으므로 AutoUnseal 메커니즘이 작동하지 않는 경우 Vault를 봉인해제하기에 충분하지 않습니다. 이것은 순전히 권한 인증 메커니즘입니다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;1676&quot; data-ke-size=&quot;size16&quot;&gt;API를 통하여 Vault 노드를 봉인하는 것은 여전히 가능합니다. 이 경우 Vault는 재기동하거나 봉인해제 API가 사용될 때까지 봉인된 상태로 유지됩니다. 이 때 봉인해제를 위해서는 봉인해제 키 대신 복구 키가 필요합니다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;1805&quot; data-ke-size=&quot;size16&quot;&gt;AutoUnseal을 지원하는 프로바이더는 HSM(Hardware Security Module) 이나 클라우드 서비스의 KMS 등이 있습니다. Vault의 transit 기능을 이용할 수도 있습니다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;1918&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;1920&quot; data-ke-size=&quot;size16&quot;&gt;참고: &lt;span data-inline-card=&quot;true&quot; data-card-url=&quot;https://www.vaultproject.io/docs/concepts/seal&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-testid=&quot;inline-card-icon-and-title-image&quot; data-origin-width=&quot;192&quot; data-origin-height=&quot;192&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgCbqN/btq96ElZ6bg/YkhqfabDOHYyF8CWeb6eJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgCbqN/btq96ElZ6bg/YkhqfabDOHYyF8CWeb6eJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgCbqN/btq96ElZ6bg/YkhqfabDOHYyF8CWeb6eJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgCbqN%2Fbtq96ElZ6bg%2FYkhqfabDOHYyF8CWeb6eJK%2Fimg.png&quot; data-testid=&quot;inline-card-icon-and-title-image&quot; data-origin-width=&quot;192&quot; data-origin-height=&quot;192&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;1920&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span data-inline-card=&quot;true&quot; data-card-url=&quot;https://www.vaultproject.io/docs/concepts/seal&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/concepts/seal&quot; data-testid=&quot;inline-card-resolved-view&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Seal/Unseal | Vault by HashiCorp&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Vault</category>
      <category>HSM</category>
      <category>key</category>
      <category>KMS</category>
      <category>Seal</category>
      <category>Shamir</category>
      <category>Unseal</category>
      <category>Vault</category>
      <category>봉인</category>
      <category>봉인해제</category>
      <category>샤미르</category>
      <author>산떠 버하둘</author>
      <guid isPermaLink="true">https://shanta.tistory.com/14</guid>
      <comments>https://shanta.tistory.com/14#entry14comment</comments>
      <pubDate>Tue, 20 Jul 2021 11:42:39 +0900</pubDate>
    </item>
    <item>
      <title>Vault의 AppRole을 사용하는 권장 패턴</title>
      <link>https://shanta.tistory.com/13</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;이 글은 Hashicorp사의 Vault에 관련된 문서중 &quot;&lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/pattern-approle?in=vault/recommended-patterns#ci-worker-passes-a-vault-token-to-the-runner&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Recommended Pattern for Vault AppRole&amp;nbsp;Use&quot;를&lt;/a&gt; 번역하며 약간의 의역을 더한 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 소스 내에 존재하는 민감 정보를 소스에서 분리하여 Vault에 안전하게 보관하고 이를 CI 단계에서 안전하게 다시 주입하는 구체적인 과정을 설명하고 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;목표&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.hashicorp.com/products/vault/&quot;&gt;하시코프 볼트&lt;/a&gt;는 아이덴티티 기반의 비밀, 암호화 관리 시스템입니다. 안전하고 감사 가능하며 제한된 접근을 제공하기 위해 인증(authentication) 및 권한 부여(authorization) 방법으로 제어되는 암호화 서비스를 제공합니다. UI, CLI 또는 HTTP API를 사용하여 토큰, 암호, 인증서, 비밀 보호를 위한 암호화 키 및 민감 정보에 대한 접근을 보호, 저장 및 엄격하게 제어하는 데 사용됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;볼트 사용의 핵심은 인증 및 권한 부여입니다. 볼트가 이를 클라이언트에 제공하는 방법을 이해하는 것이 볼트를 구성하고 관리하는 방법을 이해하기 위한 열쇠입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;볼트는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/concepts/auth/&quot;&gt;인증 방법(auth method)&lt;/a&gt;을 사용하여 클라이언트에 인증을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;볼트는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/concepts/policies/&quot;&gt;정책(policy)&lt;/a&gt;을 사용하여 클라이언트에 권한 제어를 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;볼트는 몇 가지 내부 또는 외부 인증 방법을 제공합니다. 외부 방법을 AWS, LDAP, GitHub 등과 같은 신뢰할 수 있는 서드파티 인증자(trusted third-party authenticators)이라고 합니다. 어떤 상황에서는 신뢰할 수 있는 서드파티 인증자를 사용할 수 없으므로 볼트에서는 AppRole이라는 대체 수단을 갖습니다. 신뢰할 수 있는 서드파티 인증자가 있다면 그것을 사용하는 것이 AppRole을 사용하는 것보다는 바람직합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 가이드에서는 AppRole의 상위 수준 개념을 자세히 설명하고 상위 수준 개념에서 탐색한 권장 패턴에 따라 두 가지 세부 용도를 간략하게 설명합니다. 이 가이드는 또한 이 기능의 안전하지 않은 사용을 방지하는 데 도움이 되는 안티 패턴에 대해 자세히 설명합니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;AppRole에 익숙하지 않은 경우&amp;nbsp;&lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/approle&quot;&gt;AppRole Pull 인증&lt;/a&gt;&amp;nbsp;자습서에서 단계별 지침을 참조하십시오. 또한 더 많은 예를 보려면&amp;nbsp;&lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/approle-trusted-entities&quot;&gt;AppRole With Terraform &amp;amp; Chef&lt;/a&gt;를 참조하십시오.&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;볼트 모범 사례&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 가이드는 볼트의 두 가지 기본 원칙, 즉 아이덴티티의 폭발 반경과 인증 기간을 모두 제한하는 데 크게 의존합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;아이덴티티 폭발 반경(Blast-radius of an identity)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;볼트는 아이덴티티 기반 비밀 관리 솔루션으로, 비밀에 대한 접근은 클라이언트의 알려지고 확인된 아이덴티티를 기반으로 합니다. 이 아이덴티티는 볼트에서 식별 가능해야 하고 해당 사용자가 사용하는 비밀에만 접근 가능해야 합니다. 볼트와 비밀의 최종 사용자 사이에 제 3자가 끼여서는 안 되며(never be proxied) 클라이언트는 최종 사용자가 아닌 비밀에 접근할 수 없어야 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;인증 기간&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;볼트에서 엔터티의 아이덴티티를 확인하면, 볼트는 해당 엔터티에 토큰을 제공합니다. 클라이언트는 인증을 증명하기 위하여 볼트와의 모든 후속 상호 작용에 이 토큰을 사용하므로 이 토큰은 안전하게 처리되고 제한된 수명을 가져야 합니다. 토큰은 접근 권한을 부여한 비밀에 대한 접근이 필요한 동안에만 유효해야 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;전제 조건&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;고가용성 Vault 클러스터에 필요한 리소스를 프로비저닝하기 위해 Vault용&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/reference-architecture&quot;&gt;참조 아키텍처&lt;/a&gt;를 따랐습니다.&lt;/li&gt;
&lt;li&gt;Vault용&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/deployment-guide&quot;&gt;배포 안내서&lt;/a&gt;에 따라 각 Vault 서버에 Vault를 설치 및 구성했습니다.&lt;/li&gt;
&lt;li&gt;Vault 클러스터의 보안을 개선하기 위해 Vault용&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/production-hardening&quot;&gt;프로덕션 강화 가이드&lt;/a&gt;를 따랐습니다.&lt;/li&gt;
&lt;li&gt;금고가 봉인되지 않았습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/commands/operator/unseal.html&quot;&gt;개봉&lt;/a&gt;에 대한 문서를 참조하십시오.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에서는 Vault 버전 0.8에 도입된 응답 래핑 토큰을 참조합니다. 따라서 다음 권장 사항을 Vault v0.8 이상에 적용한다고 가정합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;용어 사전&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인증 - 본인 확인 절차입니다. 종종 AuthN으로 축약됩니다.&lt;/li&gt;
&lt;li&gt;권한 부여 - 엔터티가 어떤 수준에서 액세스할 수 있는지 확인하는 프로세스입니다. 종종 AuthZ로 축약됩니다.&lt;/li&gt;
&lt;li&gt;RoleID - Vault에 인증할 역할에 대한 준 비밀 식별자입니다. 이것을 인증 쌍의 '사용자 이름' 부분으로 생각하십시오.&lt;/li&gt;
&lt;li&gt;SecretID - Vault에 인증할 역할의 비밀 식별자입니다. 이것을 인증 쌍의 '비밀번호' 부분으로 생각하십시오.&lt;/li&gt;
&lt;li&gt;AppRole 역할 - 인증을 위한 권한 부여 및 사용 매개변수를 포함하는 Vault에 구성된 역할입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;볼트 AppRole 개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AppRole 인증 방법은 볼트에서 시스템 인증을 위해 제공합니다. AppRole은 유연하게 설계되었기 때문에 구성 방법이 다양합니다. 보안 책임은 다른 볼트 인증 방법의 경우와 같이 신뢰할 수 있는 서드파티가 아니라 구성자에게 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AppRole은 신뢰할 수 있는 서드파티 인증자가 아니라 신뢰할 수 있는 브로커 방식입니다. 차이점은 인증에서 신뢰의 책임은 클라이언트와 볼트 간의 인증을 중개하는 안전하게 관리되는 브로커 시스템에 있다는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 보안의 핵심 원칙은 볼트와의 인증 중계 중에 RoleID와 SecretID가 비밀을 소비해야하는 최종 사용자 시스템에만 항상 함께 있다는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AppRole 인증에는 세 명의 플레이어가 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;볼트 - 볼트 서비스&lt;/li&gt;
&lt;li&gt;브로커 - 인증을 중개하는 신뢰할 수 있고 안전한 시스템&lt;/li&gt;
&lt;li&gt;비밀 소비자 - 비밀의 최종 소비자&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;래핑된 secretID가 있는 CI 파이프라인의 AppRole&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 시나리오에서는, CI에서 비밀로 분류되어 볼트에 저장된 데이터가 필요한 작업을 실행할 필요가 있습니다. CI에서 마스터 노드와 작업자(worker) 노드가 있습니다(예, Jenkins). 작업자 노드는 수명이 짧은 즉석 생성된 컨테이너에서 수행됩니다. 여기에서의 프로세스는 다음과 같아야 합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CI 작업자는 볼트에 인증합니다&lt;/li&gt;
&lt;li&gt;볼트는 인증 토큰을 반환합니다&lt;/li&gt;
&lt;li&gt;작업자는 토큰을 사용하여 생성할 작업의 역할(role)을 위한 래핑(wrapped)된 secretID를 볼트에 요청합니다&lt;/li&gt;
&lt;li&gt;볼트는 래핑된 secretID를 반환합니다&lt;/li&gt;
&lt;li&gt;작업자는 작업 실행자(runner)를 생성하고 래핑된 secretID를 작업에 변수로 전달합니다&lt;/li&gt;
&lt;li&gt;실행자 컨테이너가 볼트에 secretID의 래핑 해제를 요청합니다&lt;/li&gt;
&lt;li&gt;볼트는 SecretID를 반환합니다&lt;/li&gt;
&lt;li&gt;실행자는 RoleID 및 SecretID를 사용하여 볼트에 인증합니다.&lt;/li&gt;
&lt;li&gt;볼트는 요청 받은 비밀을 읽을 수 있는 권한이 포함된 정책의 토큰을 반환합니다&lt;/li&gt;
&lt;li&gt;실행자는 토큰을 사용하여 볼트에서 비밀을 가져옵니다&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;793&quot; data-origin-height=&quot;537&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/81wLw/btq9RfHKb75/Vmp3GccmUGuLebGKCTJtz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/81wLw/btq9RfHKb75/Vmp3GccmUGuLebGKCTJtz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/81wLw/btq9RfHKb75/Vmp3GccmUGuLebGKCTJtz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F81wLw%2Fbtq9RfHKb75%2FVmp3GccmUGuLebGKCTJtz0%2Fimg.png&quot; data-origin-width=&quot;793&quot; data-origin-height=&quot;537&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 해당 프로세스의 더 복잡한 단계에 대한 자세한 설명입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;CI 작업자가 볼트에 인증합니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CI 작업자는 생성할 작업의 AppRole에 대해 래핑된 SecretID를 요청하려면 볼트에 인증해야 합니다. 작업자가 플랫폼 인증 방법을 사용할 수 있다면 작업자는 이를 사용해야 합니다. 그렇지 않다면 유일한 옵션은 다른 방법으로 작업자를 볼트에 미리 인증하는 것입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;볼트는 토큰을 반환합니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업자의 볼트 토큰은 범위가 제한되어야 하며 래핑된 SecretID 만 얻을 수 있어야 합니다. 이 때문에 작업자는 수명이 긴 볼트 토큰으로 미리 시드 하거나 하드 코딩된 RoleID 및 SecretID를 사용할 수 있습니다. 이는 경미한 위험만 제공하기 때문입니다.&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_1626883269344&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;path &quot;auth/approle/role/+/secret*&quot; {
  capabilities = [ &quot;create&quot;, &quot;read&quot;, &quot;update&quot; ]
  min_wrapping_ttl = &quot;100s&quot;
  max_wrapping_ttl = &quot;300s&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;작업자는 래핑된 SecretID를 요청하기 위하여 토큰을 사용합니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CI 작업자는 이제 래핑된 SecretID를 검색할 수 있어야 합니다. 이 명령은 다음과 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1626883300135&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vault write -wrap-ttl=120s -f auth/approle/role/my-role/secret-id&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업자는 생성중인 작업의 **역할(role)**만 알고 있으면 됩니다. 위의 예에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;my-role이 그것이지만 이것이 RoleID는 아닙니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;작업자는 작업 실행자를 생성하고 래핑된 SecretID를 전달합니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 래핑된 토큰을 환경 변수로 전달하여 달성할 수 있습니다. 다음은 Jenkins에서 이 작업을 수행하는 방법의 예입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1626883372433&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;environment {
   WRAPPED_SID = &quot;&quot;&quot;$s{sh(
                    returnStdout: true,
                    Script: &amp;lsquo;curl --header &quot;X-Vault-Token: $VAULT_TOKEN&quot;
       --header &quot;X-Vault-Namespace: ${PROJ_NAME}_namespace&quot;
       --header &quot;X-Vault-Wrap-Ttl: 300s&quot;
         $VAULT_ADDR/v1/auth/approle/role/$JOB_NAME/secret-id&amp;rsquo;
         | jq '.data.secret_id'
                 )}&quot;&quot;&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실행자는 RoleID와 SecretID를 사용하여 볼트에 인증합니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행자는 볼트에 인증하고 정확히 필요한 비밀만 읽을 수 있는 정책을 수신합니다. 정책의 예는 다음과 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1626883392567&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;path &quot;kv/my-role_secrets/*&quot; {
  capabilities = [ &quot;read&quot; ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;구현 세부사항&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가 보안 조치로 다음 사항을 염두에 두고 App에 필요한 역할을 생성하십시오.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;[secret_id_bound_cidrs&amp;nbsp;(array: [])](&lt;a href=&quot;https://www.vaultproject.io/api-docs/auth/approle#secret_id_bound_cidrs&quot;&gt;https://www.vaultproject.io/api-docs/auth/approle#secret_id_bound_cidrs&lt;/a&gt;)&amp;nbsp;- 쉽표로 구분된 문자열 또는 CIDR 블록 목록. 설정된 경우 로그인 작업을 수행할 수 있는 IP 주소 블록을 지정합니다.&lt;/li&gt;
&lt;li&gt;[secret_id_num_uses&amp;nbsp;(integer: 0)](&lt;a href=&quot;https://www.vaultproject.io/api-docs/auth/approle#secret_id_num_uses&quot;&gt;https://www.vaultproject.io/api-docs/auth/approle#secret_id_num_uses&lt;/a&gt;)&amp;nbsp;- 이 AppRole에서 토큰을 가져오기 위해 특정 SecretID를 사용할 수 있는 횟수입니다. 횟수만큼 다 사용하면 SecretID는 만료됩니다. 값이 0이면 무제한 사용이 허용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;권장 사항&lt;/b&gt;: 최상의 보안을 위해&lt;span&gt;&amp;nbsp;&lt;/span&gt;secret_id_num_uses를&lt;span&gt;&amp;nbsp;&lt;/span&gt;1로 설정하십시오. 또한 접속할 장치의 소스 IP 범위를 제한하기 위해&lt;span&gt;&amp;nbsp;&lt;/span&gt;secret_id_bound_cidrs를 변경하는 것을 고려하십시오.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;안티 패턴&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;볼트의 AppRole 인증 방법을 사용할 때 이러한 안티 패턴을 피하는 것이 좋습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;CI 작업자가 비밀을 검색합니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CI 작업자는 볼트에 인증하고 작업에 대한 비밀을 직접 검색하여 이를 실행자에게 전달할 수 있지만 이는 위에 나열된 모범 사례 중 첫 번째를 위반한 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CI 작업자는 많은 다른 유형의 작업을 실행해야 할 수 있으며 그 중 상당수는 비밀이 필요합니다. 이 방법을 사용하는 경우 작업자는 비밀의 소비자가 아니면서도 많은 비밀을 검색할 수 있는 권한(정책)을 가지고 있어야 합니다. 또한 하나의 비밀이 노출된다면, 노출된 비밀과 아이덴티티를 연결 지어서 해당 아이덴티티에 대한 유리 깨기 절차(&lt;a href=&quot;https://hipaa.yale.edu/security/break-glass-procedure-granting-emergency-access-critical-ephi-systems#:~:text=Break%20glass%20(which%20draws%20its,to%20gain%20access%20when%20necessary.)&quot;&gt;break-glass procedure&lt;/a&gt;)를 시작할 수 없을 것입니다. 그래서 모든 비밀을 노출된 것으로 간주해야 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;CI 작업자가 실행자에게 볼트 토큰을 전달합니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업자는 권한을 받아서 볼트에서 RoleID와 SecretID를 검색하고 둘 다 사용하도록 실행자에게 전달할 수도 있습니다. 이렇게 하면 작업자가 모든 비밀을 검색할 수 있는 볼트 권한이 부여되지 않지만 RoleID와 SecretID를 모두 가지고 있으므로 그런 권한이 있는 것과 마찬가지입니다. 이는 모범 사례에 위배됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;CI 작업자가 실행자에게 볼트 토큰을 전달합니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업자에게 비밀을 검색할 권한이 있는 하위 토큰을 생성할 수 있는 권한이 부여될 수 있습니다. 이 토큰을 실행자에게 전달하면 실행자는 이 토큰 만으로 비밀을 검색할 수 있습니다. 작업자에게 비밀에 직접적으로 접근할 수 있는 권한이 부여되지는 않았지만 작업자는 이 비밀에 접근할 수 있는 토큰을 알고 있기 때문에 권한이 이미 있는 것과 같습니다. 따라서 모범 사례에 위배됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;보안 고려 사항&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신뢰할 수 있는 브로커 상황에서, 브로커(이 경우 Jenkins 작업자)에 대한 보안을 유지해야 하고 브로커는 위험한 시스템으로 취급되어야 합니다. 이는 사용자가 최소한의 권한을 가져야 하고 접근 행위에 대해 면밀히 모니터링하고 감사해야 함을 의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 볼트 감사 로그는 타임스탬프 이벤트를 제공하므로 다음 두 이벤트에 대한 알림으로 전체 프로세스를 모니터링합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AppRole에 대해 래핑된 SecretID가 요청되고 실행 중인 Jenkins 작업이 없는 경우&lt;/li&gt;
&lt;li&gt;Jenkins 슬레이브가 토큰의 래핑을 풀려고 시도하였지만 토큰이 이미 사용되었기 때문에 볼트가 거부하는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 경우 모두 신뢰할 수 있는 브로커 워크플로가 손상되었을 가능성이 있으며 이벤트를 조사해야 함을 나타냅니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;볼트 AppRole 참조&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Vault auth methods
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/auth/index.html&quot;&gt;CLI Enable/Disable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/api/auth/approle/index.html&quot;&gt;API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Vault AppRole authentication
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/approle&quot;&gt;Pull authentication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/auth/approle.html&quot;&gt;Auth method&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Vault cubbyhole response wrapping
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/concepts/response-wrapping.html&quot;&gt;Response wrapping concept&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/cubbyhole-response-wrapping&quot;&gt;Learn tutorials&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Vault policies
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/concepts/policies.html&quot;&gt;Policy overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/policies&quot;&gt;ACL policies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/sentinel&quot;&gt;Sentinel policies&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Vault tokens
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/commands/token/create.html&quot;&gt;Create Vault tokens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/concepts/tokens.html&quot;&gt;Token types&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/concepts/policies.html#capabilities&quot;&gt;Vault policy capabilities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/concepts/tokens.html#token-time-to-live-periodic-tokens-and-explicit-max-ttls&quot;&gt;Vault token periods and TTLs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Vault</category>
      <category>approle</category>
      <category>auth method</category>
      <category>Best Practice</category>
      <category>hashicorp</category>
      <category>KMS</category>
      <category>secret</category>
      <category>secretid</category>
      <category>Vault</category>
      <category>권장</category>
      <category>볼트</category>
      <author>산떠 버하둘</author>
      <guid isPermaLink="true">https://shanta.tistory.com/13</guid>
      <comments>https://shanta.tistory.com/13#entry13comment</comments>
      <pubDate>Sun, 18 Jul 2021 17:29:04 +0900</pubDate>
    </item>
    <item>
      <title>별명생성기 - 1. 기획</title>
      <link>https://shanta.tistory.com/12</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;긴 퇴근길에 재미있는 아이디어가 떠올랐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;독창적이고 엉뚱한 별명을 자동으로 만들어주는 서비스를 만들면 재미있겠다는 생각이였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터넷의 각 종 사이트에 가입할 때 별명을 물어보는 경우가 있는데 보통은 자주 사용하는 별명을 하나 쯤은 가지고 있어서 그걸 입력하지만 중복을 허용하지 않는 경우는 자기 별명을 사용하지 못하는 경우가 많다. 이럴 때 흔히 생각할 수 없는, 엉뚱하지만 말은 되는 그런 별명이 있었으면 좋겠다는 생각을 했었는데 방대한 단어 수를 가지고 있는 국어 사전을 기반으로 단어를 조합하면 어떨까하는 아이디어이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;말이되는...&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단어의 품사를 기반으로 규칙을 정해서 조합하면 그럭저럭 의미는 엉뚱하지만 말은 되지 않을까 생각했다. 예를 들면 형용사 + 명사 조합은 어느 정도 말이 될 것 같았다. 그런데 이건 영어 맨투맨 기초편 1권만 반복적으로 들춰봤던 이의 짧은 생각이였고, 국어에서는 명사(체언)을 수식하는 것은 관형사라고 한다. 국어 공부부터 다시 해야겠다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;사전 데이터&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대한민국 정부의 오픈API가 일반화된 요즘 사전 데이터도 어디엔가 존재할 것으로 예상했다. 아니다 다를까 검색을 시작한지 얼마 안되 쓸만한 데이터를 찾았다. 무려 90만이 넘는 단어이다. 품사로 구분해서 단어를 조합하다보면 경우의 수가 확 줄겠지만 두 단어 조합만으로도 해시 알고리즘에 준하는 식별력을 보일 수도 있을 것 같다. 아래 페이지의 링크에서 엑셀 파일을 다운로드 받을 수 있다. 단어|품사|사전종류의 세 컬럼만 가지고 있는 아주 단순한 구조의 사전이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kbig.kr/portal/kbig/datacube/niadict.page&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;kbig.kr/portal/kbig/datacube/niadict.page&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;품사구분&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사전에 있는 품사 정보는 &quot;ncn&quot; 같은 생소한 영문 약어로 되어 있는데, 검색해보니 &quot;KAIST 품사 태그셋&quot;이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://semanticweb.kaist.ac.kr/research/kcp/tag_set.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;s&gt;semanticweb.kaist.ac.kr/research/kcp/tag_set.html&lt;/s&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 서버가 더 이상 운영되지 않은 것으로 보여 다음의 참고 문서 링크를 첨부한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hamanlp.org/docs/morphemes/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://hamanlp.org/docs/morphemes/&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;유사 프로젝트&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사람의 생각은 또 비슷해서 나와 비슷한 생각을 한 사람이 여럿 있었나보다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 악질이름생성기: &lt;a href=&quot;https://name.ho9.me&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;name.ho9.me&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;&lt;span&gt;한국어 별명/닉네임 생성기: &lt;/span&gt;&lt;a href=&quot;https://nickname.hwanmoo.kr&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;nickname.hwanmoo.kr&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Nickname 생성기: &lt;a href=&quot;https://velog.io/@wimes/Nickname-생성기-p6k2342cfn&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;velog.io/@wimes/Nickname-생성기-p6k2342cfn&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 랜덤 녜횡 제조기: &lt;a href=&quot;https://beepman.github.io/nyehuing/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;beepman.github.io/nyehuing/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼에도 불구하고 이 프로젝트를 계속 진행해도 의미 있을 것 같았다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;자료구조&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 중요한 사전 데이터를 어떻게 다룰지 생각해보았다. 단어 조합법이 확정되지 않은 상황에서 데이터를 메모리에 로딩해서 이런 저런 시도를 다양하게 해 보아야 할 것 같다. SQLite 같은 로컬 데이터 베이스를 활용하는 방법도 있겠지만 번거로울 것 같다. 적절한 자료구조를 고민해봐야겠다. 특히 품사별로 랜덤하게 선택 가능해야한다는 요구사항에 주목해야할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Toy Project</category>
      <author>산떠 버하둘</author>
      <guid isPermaLink="true">https://shanta.tistory.com/12</guid>
      <comments>https://shanta.tistory.com/12#entry12comment</comments>
      <pubDate>Fri, 26 Mar 2021 00:26:44 +0900</pubDate>
    </item>
  </channel>
</rss>