<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>클라우드 아카이브</title>
    <link>https://kimdy.tistory.com/</link>
    <description>VM/Container 가상화 외에 네트워크/보안 및 다양한 오픈소스에 관심이 많습니다.</description>
    <language>ko</language>
    <pubDate>Thu, 13 Aug 2026 19:50:13 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Cloud Engineer</managingEditor>
    <item>
      <title>[생성 패턴] Builder Pattern (빌더 패턴)이란?</title>
      <link>https://kimdy.tistory.com/53</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;목표&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 생성 패턴이 무엇인지에 대해 간략하게 설명한 뒤에 빌더 패턴에 대해 알아보겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;생성 패턴이란?&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;디자인 패턴에 대해 기초를 닦을 수 있는 대표적인 사이트인 리팩토링 그루(&lt;a href=&quot;https://refactoring.guru/ko/design-patterns/classification&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;)에서는 생성 패턴을 아래와 같이 설명하고 있습니다.&lt;br /&gt;&lt;b&gt;생성 패턴&lt;/b&gt;들은 기존 코드의 재활용과 유연성을 증가시키는 객체 생성 메커니즘들을 제공합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 객체 생성 시  객체지향 개발 원칙인 SOLID를 최대한 준수할 수 있음과 동시에 다른 프로젝트 혹은 코드에서 Reusability(재활용성)를 높일 수 있도록 도와주는 디자인 패턴입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Builder Pattern (빌더 패턴)&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;빌더 패턴은 객체를 단계 별로 생성할 수 있도록 해주는 생성 패턴입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 말만 봤을 때는 빌더 패턴이 도대체 무엇인지 이해가 안될 수 있습니다. 이해를 돕기 위해 하나의 문제를 가정해보겠습니다. 자동차를 만드는 공장에서는 아반떼, 쏘나타, 그랜저 등 다양한 차종을 양산하고 있습니다. 이 경우 자동차라는 단일 객체가 아닌 각 차종이 객체가 될 수 있는데요. 프레임, 엔진, 의자 종류이 다를 뿐인데 각 차종 별로 객체를 따로 생성 및 관리해주어야 합니다. 또한 사용자가 선택한 옵션에 따라 관리해주어야 하기 때문에 자동차를 중심으로 &lt;u&gt;자식 클래스들의 계층구조가 점점 복잡&lt;/u&gt;해질 뿐만 아니라 &lt;u&gt;객체 생성 코드가 못생겨질 수 있다&lt;/u&gt;는 문제점이 있습니다. 심지어 그랜저에만 가지고 있는 옵션이 있을 경우 개발자가 객체 생성 시점에서 해당 코드를 보고 햇갈릴 수도 있죠.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;위 문제를 해결하기 위해 빌더 패턴을 사용할 수 있으며 해당 패턴은 자동차 클래스에서 &lt;u&gt;&lt;b&gt;객체 생성 코드를 추출하여&amp;nbsp;builder​라는 별도의 객체들로 관리할 수 있도록&lt;/b&gt;&lt;/u&gt; 제안합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;builder에서 buildFrame(프레임 생성), buildEngine(엔진 부착), buildSeats(의자 부착) 등을  구현하고,  특정 차종에 대한 객체 생성 시 Builder 객체를 활용하면 되는 것입니다. 특히 모든 단계를 호출하는 것이 아닌 해당 자동차 차종을 제작하는데 필요한 단계들만 호출하면 됩니다. 혹자는 일부 자동차 차종에서 의자를 부착할 때 안마 기능이 부가적으로 들어가있는 등의 별도 구현이 필요할 수 있는데요. 이 경우 특수 Case를 전담하는 별도의 Builder 클래스를 구현하고 해당 Builder를 통해 특수 기능을 부여해주면 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디자인 패턴 중 생성 패턴인 Builder Pattern(빌더 패턴)에 대해 알아보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 포스팅에서는 실제 오픈 소스에서 해당 Builder Pattern을 어떻게 적용하여 구현했는지에 대해 작성하겠습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #444444; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/디자인패턴</category>
      <author>Cloud Engineer</author>
      <guid isPermaLink="true">https://kimdy.tistory.com/53</guid>
      <comments>https://kimdy.tistory.com/53#entry53comment</comments>
      <pubDate>Sun, 6 Oct 2024 15:54:05 +0900</pubDate>
    </item>
    <item>
      <title>Jfrog Artifactory란?</title>
      <link>https://kimdy.tistory.com/52</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;0. 개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엔터프라이즈 환경에서 클라우드 시스템을 운영하다보면 VM에 설치될 패키지 관리 혹은 컨테이너 이미지 버전 관리가 중앙에서 관리되지 않는 경우가 있습니다. 따라서 A라는 사용자가 VM/Container 이미지를 생성하여 사내 표준으로 구성하더라도 이를 관리하는 실무자가 퇴사하게 될 경우 관리에 문제가 발생하게됩니다. 각 OS 및 컨테이너를 구성하는 패키지 및 라이브러리 버전을 중앙에서 관리하도록 도와주는 솔루션이 바로 Jfrog Artifactory입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Jfrog Artifactory란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jfrog Arficatory는 이스라엘 출신의 클라우드 소프트웨어 기업인 Jfrog라는 회사에서 개발한 범용 artifact Repository로, 리눅스/유닉스를 비롯하여 도커/쿠버네티스에서 사용하는 &lt;u&gt;&lt;b&gt;패키지/라이브러리/바이너리 파일 버전 등을 중앙에서 관리&lt;/b&gt;&lt;/u&gt;하도록 도와주는 DevOps 솔루션입니다. 다시 말해, Centos/RHEL의 패키지 의존성 및 버전을 관리해주는 YUM 뿐만 아니라 컨테이너 이미지를 관리하는 Private Registry 역할을 수행합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 굳이 Jfrog Arifactory를 사용해야되나..??&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에도 Jfrog Artifactory와 동일한 기능을 지원하는 다양한 솔루션이 존재합니다. 대표적으로 Nexus가 있는데요. 굳이 Jfrog Artifactory를 사용해야되는 이유는 &lt;u&gt;&lt;b&gt;클라우드 네이티브 환경을 지원&lt;/b&gt;&lt;/u&gt;하기 때문입니다. 즉 API 및 다양한 클라우드 스토리지 백엔드 솔루션을 지원합니다.&amp;nbsp;또한 포춘지에서 선정한 100대 기업 중 75% 이상이 Jfrog의 서비스를 사용하는 등 공신력이 높은 기업에서 개발한 솔루션이라고 할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-1. 하이브리드 클라우드 환경에 적합&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baIYzV/btrNwECrGZs/nISyfT3XHjxIO4u91mbKe0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baIYzV/btrNwECrGZs/nISyfT3XHjxIO4u91mbKe0/img.jpg&quot; data-alt=&quot;지원 환경 비교, 출처 : https://jfrog.com/blog/artifactory-vs-nexus-integration-matrix/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baIYzV/btrNwECrGZs/nISyfT3XHjxIO4u91mbKe0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaIYzV%2FbtrNwECrGZs%2FnISyfT3XHjxIO4u91mbKe0%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;755&quot; height=&quot;307&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;지원 환경 비교, 출처 : https://jfrog.com/blog/artifactory-vs-nexus-integration-matrix/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 사진에서 볼 수 있듯이, Nexus는 On-Premise 환경에서만 지원을 해주는 반면에 Artifactory는 On-premise 뿐만 아니라 다양한 클라우드 환경에서 지원을 해주고 있습니다. 기업의 IT 인프라 환경이 On-Premise을 클라우드 네이티브로 전환하고 이를 퍼블릭 클라우드 혹은 다른 클라우드 환경을 결합하여 사용하는 추세로 진화하면서 대부분의 기업에서 Artfactory를 적극 도입을 검토하고 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-2. REST API 제공&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;210&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGvqV0/btrNwEJeu2f/FjO6LK6kkxqMYQELS3jr4k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGvqV0/btrNwEJeu2f/FjO6LK6kkxqMYQELS3jr4k/img.jpg&quot; data-alt=&quot;API 제공 여부 비교, 출처 : https://jfrog.com/blog/artifactory-vs-nexus-integration-matrix/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGvqV0/btrNwEJeu2f/FjO6LK6kkxqMYQELS3jr4k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGvqV0%2FbtrNwEJeu2f%2FFjO6LK6kkxqMYQELS3jr4k%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;818&quot; height=&quot;210&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;210&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;API 제공 여부 비교, 출처 : https://jfrog.com/blog/artifactory-vs-nexus-integration-matrix/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기업이 클라우드 네이티브 환경을 구축하기 위해서 선행되어야 하는게 기업의 모든 솔루션은 REST API를 통해 접근이 가능해야된다는 점입니다. Nexus는 클라우드 환경을 지원하지 않기 때문에 REST API를 제공하는데 의무사항이 없는 반면에 Artifactory는 다양한 클라우드 환경을 지원하므로 REST API를 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1137&quot; data-origin-height=&quot;328&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xgUlO/btrNCf2r7q6/xPmfqOrdmwNIPiktXDC44K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xgUlO/btrNCf2r7q6/xPmfqOrdmwNIPiktXDC44K/img.png&quot; data-alt=&quot;스토리지 백엔드 비교, 출처 : https://jfrog.com/blog/artifactory-vs-nexus-integration-matrix/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xgUlO/btrNCf2r7q6/xPmfqOrdmwNIPiktXDC44K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxgUlO%2FbtrNCf2r7q6%2FxPmfqOrdmwNIPiktXDC44K%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;1137&quot; height=&quot;328&quot; data-origin-width=&quot;1137&quot; data-origin-height=&quot;328&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스토리지 백엔드 비교, 출처 : https://jfrog.com/blog/artifactory-vs-nexus-integration-matrix/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔루션에서 어떤 스토리지 백엔드를 지원하는지 또한 클라우드 네이티브 및 DevOps를 가속화하는데 중요한 요소 중 하나입니다. &lt;span&gt;Artifactory에서는 다양한 퍼블릭 클라우드 및 샤딩을 지원합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;3. 마무리&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jfrog Artifactory가 무엇이며, 사용해야 되는 이유에 대해 알아봤습니다. 다음 포스팅에서는 Jfrog Artifactory의 구성요소 및 디렉터리 구성 그리고 설치 요구사항에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[출처]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- https://byline.network/2020/10/26-109/&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp; &lt;span style=&quot;color: #777777;&quot;&gt;&lt;a href=&quot;https://jfrog.com/blog/artifactory-vs-nexus-integration-matrix/&quot;&gt;https://jfrog.com/blog/artifactory-vs-nexus-integration-matrix/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Cloud Native Solution/[Jfrog] Arifactory</category>
      <category>artifactory</category>
      <category>Cloud</category>
      <category>Container</category>
      <category>devops</category>
      <category>docker</category>
      <category>JFrog</category>
      <category>kubernetes</category>
      <category>packages</category>
      <category>Repository</category>
      <category>REST API</category>
      <author>Cloud Engineer</author>
      <guid isPermaLink="true">https://kimdy.tistory.com/52</guid>
      <comments>https://kimdy.tistory.com/52#entry52comment</comments>
      <pubDate>Sun, 2 Oct 2022 10:46:40 +0900</pubDate>
    </item>
    <item>
      <title>[vault] Namespace 개념과 특징 및 실습</title>
      <link>https://kimdy.tistory.com/50</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;0. 개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 회사에서 Vault를 운영하며 조직 구조 변경 혹은 입사자/퇴사자 관리 등을 효과적으로 하기 위해서 &lt;b&gt;각 조직 별 및 서비스 별로 Vault를 별도 구성 및 관리하는 니즈&lt;/b&gt;가 발생하게됩니다.(이른바 멀티 테넌트 방식) Vault에서는 이러한 니즈를 충족시키고자 Namespace라는 기능을 개발했으며, 본 컴포넌트를 활용하여 급변하는 비즈니스 환경에 맞춰 시스템 구성을 다변화하도록 지원해줍니다. 본 포스팅에서는 Namespace에 대한 개념 및 특징과 이를 직접 구현해보겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Namespace란&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&quot;Vaults within a Vault&quot;&lt;br /&gt;단일 Vault 서버에 여러 개의 논리적인 그룹으로 나누어 서비스를 제공할 수 있도록 해주는 기능&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Vault 서버를 여러 개의 논리적인 환경으로 구성하여 운영 (&lt;b&gt;멀티 테넌트 방식&lt;/b&gt;)&lt;/li&gt;
&lt;li&gt;Kubernetes의 namespace와 동일한 메커니즘&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Namespace 특징 : Login Path, Auth Method 및 Data 등을 별도 관리&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Namespace로 별도 구성 가능한 컴포넌트는 하기와 같음
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Policies&lt;/li&gt;
&lt;li&gt;Auth Methods&lt;/li&gt;
&lt;li&gt;Secrets Engines&lt;/li&gt;
&lt;li&gt;Tokens&lt;/li&gt;
&lt;li&gt;Identity entities and groups&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 실습&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;DevOps팀&lt;/b&gt;에 &lt;b&gt;쿠버네티스 클러스터 관리 파트&lt;/b&gt;와 &lt;b&gt;배포 파트&lt;/b&gt;가 나누어졌다고 가정&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-1. 구성도&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;798&quot; data-origin-height=&quot;486&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvKbSu/btrLNvAwWmU/nJZPLsz0GrpzsaInYAs0dK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvKbSu/btrLNvAwWmU/nJZPLsz0GrpzsaInYAs0dK/img.png&quot; data-alt=&quot;Vault Raft HA Cluster 내 Namespace 구성도&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvKbSu/btrLNvAwWmU/nJZPLsz0GrpzsaInYAs0dK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvKbSu%2FbtrLNvAwWmU%2FnJZPLsz0GrpzsaInYAs0dK%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;540&quot; height=&quot;329&quot; data-origin-width=&quot;798&quot; data-origin-height=&quot;486&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Vault Raft HA Cluster 내 Namespace 구성도&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. 실습&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-2-1. 위 환경에 맞춰 Vault Namespace를 구성&lt;/h4&gt;
&lt;pre id=&quot;code_1662880918985&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# DevOps팀 구성
$ vault namespace create devops
 
# 파트 구성
$ vault namespace create -namespace=devops k8s-cluster
$ vault namespace create -namespace=devops deployment&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-2-2. 각 namespace에 적용할 policy 작성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 데브옵스(devops) 팀 policy 작성&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가정 : Vault 관리자는 DevOps에 소속되어 Chlid Namespace인 &lt;b&gt;k8s-cluster 및 deployment 관련 전체 권한&lt;/b&gt;을 보유&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1662881702212&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vault_policy_devops.hcl
path &quot;devops/k8s-cluster/*&quot; {
        capabilities = [&quot;create&quot;, &quot;read&quot;, &quot;update&quot;, &quot;delete&quot;, &quot;list&quot;, &quot;sudo&quot;]
}

path &quot;devops/deployment/*&quot; {
        capabilities = [&quot;create&quot;, &quot;read&quot;, &quot;update&quot;, &quot;delete&quot;, &quot;list&quot;, &quot;sudo&quot;]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 쿠버네티스 클러스터 관리(k8s-cluster) 파트 policy 작성&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가정 : 클러스터 관리자가 오픈스택 혹은 k8s 노드 접속&amp;nbsp;&lt;b&gt;secrets 관련 전체 권한&lt;/b&gt;을 보유&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1662881337697&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vault_policy_k8s-cluster.hcl

# Manage SSH OTP Access to k8s nodes
path &quot;ssh-otp-k8s/*&quot; {
	capabilities = [&quot;read&quot;, &quot;list&quot;, &quot;update&quot;]
}

# Manage signed RSA Access to openstack nodes
path &quot;ssh-signed-rsa-openstack/*&quot; {
	capabilities = [&quot;read&quot;, &quot;list&quot;, &quot;update&quot;]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 배포 관리(deployment) 파트 policy 작성&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가정 : 배포 관리자는 오픈스택 혹은 k8s 노드 접속 &lt;b&gt;secrets 읽기 권한&lt;/b&gt;만 보유&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1662881359688&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vault_policy_deployment.hcl

# Manage SSH OTP Access to k8s nodes
path &quot;ssh-otp-k8s/*&quot; {
	capabilities = [&quot;read&quot;, &quot;list&quot;]
}

# Manage signed RSA Access to openstack nodes
path &quot;ssh-signed-rsa-openstack/*&quot; {
	capabilities = [&quot;read&quot;, &quot;list&quot;]
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-2-3. 각 Namespace에 policy 적용&lt;/h4&gt;
&lt;pre id=&quot;code_1662881852058&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vault policy write -namespace=devops devops_policy vault_policy_devops.hcl
$ vault policy write -namespace=devops/k8s-cluster k8s-cluster_policy vault_policy_k8s-cluster.hcl
$ vault policy write -namespace=devops/deployment deployment_policy vault_policy_deployment.hcl&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vault의 기능인 Namespace의 개념과 특징 및 실습을 진행했습니다. 엔터프라이즈 환경에서 조직/IT 서비스 별로 Vault Namespace를 나누어 구성함으로써 운영의 효율성을 높일 수 있습니다.&amp;nbsp;다음 포스팅에서는 Vault의 Audit Device 기능을 다뤄보겠습니다.&lt;/p&gt;</description>
      <category>Cloud Native Solution/[Hashicorp] Vault</category>
      <category>devops</category>
      <category>hashicorp</category>
      <category>kv</category>
      <category>namespace</category>
      <category>Policy</category>
      <category>Vault</category>
      <author>Cloud Engineer</author>
      <guid isPermaLink="true">https://kimdy.tistory.com/50</guid>
      <comments>https://kimdy.tistory.com/50#entry50comment</comments>
      <pubDate>Sun, 11 Sep 2022 17:38:15 +0900</pubDate>
    </item>
    <item>
      <title>[Hashicorp][HA] Vault Raft 클러스터 구성</title>
      <link>https://kimdy.tistory.com/49</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;0. 개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 Vault를 학습할 때는 standalone VM 노드에서 Vault를 구축하여 테스트해볼 수 있겠지만, 기업에서 PoC 및 프로덕션 환경에서는 클러스터링을 통해 Vault 무중단 시스템을 구축해야됩니다. Hashicorp에서는 Vault가 Community와 Enterprise인지에 따라 &lt;b&gt;차별화된 클러스터링 기능&lt;/b&gt;을 제공하는데요. 본 포스팅에서는 Community를 기준으로 &lt;b&gt;Vault Raft Cluster를 구성&lt;/b&gt;하는 내용을 다뤄보겠습니다. Raft Cluster는 &lt;b&gt;Raft 합의 알고리즘&lt;/b&gt;을 따르기 때문에 3개 VM 노드를 생성하여 클러스터를 구성하겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 시스템 구성도&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;OS : CentOS 7.x&lt;/li&gt;
&lt;li&gt;Vault : Community Version&lt;/li&gt;
&lt;li&gt;HA Type : Raft Cluster (= Integrated Storage)&lt;/li&gt;
&lt;li&gt;특이사항
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인터넷 가능 (폐쇄망 X)&lt;/li&gt;
&lt;li&gt;SElinux Disbale&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1946&quot; data-origin-height=&quot;534&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Bx7u6/btrKF0916Cc/7YjDA3j2jzgGK8hUlAlLe0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Bx7u6/btrKF0916Cc/7YjDA3j2jzgGK8hUlAlLe0/img.png&quot; data-alt=&quot;Vault version 별 HA 클러스터 구성도&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Bx7u6/btrKF0916Cc/7YjDA3j2jzgGK8hUlAlLe0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBx7u6%2FbtrKF0916Cc%2F7YjDA3j2jzgGK8hUlAlLe0%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;1946&quot; height=&quot;534&quot; data-origin-width=&quot;1946&quot; data-origin-height=&quot;534&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Vault version 별 HA 클러스터 구성도&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 실습&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 실습에서는 Yum Repository 구성부터 Vault 설치 및 Configuration 구성을 완료하고 결과값을 확인해보겠습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-1. Yum Repository 및 Vault 설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 Hashicorp에서 공식적으로 제공하는 Package Repository를 추가한 뒤, Vault를 설치해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1661402025064&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 1. Yum Repository 구성에 필요한 패키지 설치
$ sudo yum install -y yum-utils

# 2. Hashicorp에서 제공하는 Repository 추가
$ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo

# 3. Vault 설치
$ sudo yum -y install vault&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-2. Vault Configuration 구성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vault 및 Raft 클러스터 구성 정보를 입력해줍니다. 만약 해당 경로에 파일이 없다면 생성해줍니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;8200 포트 : Client로부터 받은 요청을 Redirect할 때 Advertise할 IP 주소를 지정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;8201 포트 : 노드 간 Raft 클러스터 운영에 필요한 정보를 공유&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Vault 구성과 관련된 레퍼런스를 확인하고 싶으신 분은 &lt;a href=&quot;https://www.vaultproject.io/docs/configuration&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를, Raft는 &lt;a href=&quot;https://www.vaultproject.io/docs/configuration/storage/raft&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 클릭하여 확인하시면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-2-1. Active Node&lt;/h4&gt;
&lt;pre id=&quot;code_1661403223368&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ sudo vi /etc/vault.d/vault.hcl

cluster_addr    = &quot;http://1.1.1.1:8201&quot;
api_addr                        = &quot;http://1.1.1.1:8200&quot;
disable_mlock = true //raft 기반 구성 시, out of memory 방지하기 위해 설정
ui            = true

// Listner 설정 (외부 포트 Open)
listener &quot;tcp&quot; {
        address = &quot;0.0.0.0:8200&quot;
        cluster_address = &quot;0.0.0.0:8201&quot;
        tls_disable = true	// 실습이므로, TLS Disable. Production에서는 False로 변경
}

// Raft Storage 설정 (Integrated Storage)
storage &quot;raft&quot; {
        path = &quot;/opt/vault/data&quot;
	    node_id = &quot;{{ Active Node 고유 이름 }}&quot;

// Node 개수만큼 retry_join 절 작성
        retry_join {
                leader_api_addr   = &quot;http://1.1.1.1:8200&quot;
        }
        retry_join {
                leader_api_addr   = &quot;http://1.1.1.2:8200&quot;
        }
        retry_join {
                leader_api_addr   = &quot;http://1.1.1.3:8200&quot;
        }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-2-2. Standby Node&lt;/h4&gt;
&lt;pre id=&quot;code_1661475553829&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cluster_addr    = &quot;http://{{ 본인 Node IP 주소 }}:8201&quot;
api_addr                        = &quot;http://{{ 본인 Node IP 주소 }}:8200&quot;
disable_mlock = true //raft 기반 구성 시, out of memory 방지하기 위해 설정
ui            = true

// Listner 설정
listener &quot;tcp&quot; {
        address = &quot;0.0.0.0:8200&quot;
        cluster_address = &quot;0.0.0.0:8201&quot;
        tls_disable = true			// 실습이므로, TLS Disable. Production에서는 False로 변경
}

// Raft Storage 설정
storage &quot;raft&quot; {
	path = &quot;/opt/vault/data&quot;
	node_id = &quot;{{ Stnadby 노드 고유 이름 }}&quot;

// Node 개수만큼 retry_join 절 작성
        retry_join {
                leader_api_addr   = &quot;http://1.1.1.1:8200&quot;
        }
        retry_join {
                leader_api_addr   = &quot;http://1.1.1.2:8200&quot;
        }
        retry_join {
                leader_api_addr   = &quot;http://1.1.1.3:8200&quot;
        }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-3. Service 등록 및 시작&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vault를 Systemd로 등록하여 재부팅 시 자동으로 구동되도록 설정한 뒤 데몬을 시작해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1661476399852&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ sudo systemctl enable vault.service
$ sudo systemctl start vault.service
$ sudo systemctl status vault.service&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-3. Vault 주소 환경변수 등록&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vault CLI를 활용하기 위해 Vault IP 주소를 환경 변수로 등록한 뒤, Vault 상태를 확인합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1661476510709&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ export VAULT_ADDR=&quot;http://{{각 Node IP 주소}}:8200&quot;

# vault 상태 확인
$ vault status&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-4. Vault 초기화 및 Unseal&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vault가 Seal 상태로 존재한다면 Barrier로 인해 외부 접근이 불가합니다. Vault 노드를 Unseal 상태로 구성하여 외부에서 접근할 수 있도록 해줍니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-4-1. Active Node&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vault 클러스터 Initialize 및 Seal 상태를 Unseal로 변경해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1661476748261&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vault operator init -key-shares=1 -key-threshold=1

# 생성된 Unseal Key 입력
$ vault operator unseal&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-4-2. Standby Node&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Standby 노드에서 아직 Active Node 및 Cluster에 대한 정보를 모르고 있기 때문에 해당 클러스터에 Join해준 뒤, Unseal로 구성해줍니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1661476758962&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vault operator raft join &quot;http://{{ Active Node IP 주소}}:8200&quot;

# Active Node에서 생성한 Unseal Key 입력
$ vault operator unseal&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-5. Vault Login 및 Raft Join 확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Active Node에서 Vault Root 계정으로 로그인하여 Vault 및 Raft Cluster 정보를 확인합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1661477014008&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Active Node를 초기화할 때 확인한 Root Token Value 입력
$ vault login token={{ token value }}

# Raft 구성 확인
$ vault operator raft list-peers&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vault Raft Cluster 구성 방법에 대해 알아봤습니다. 만약 회사에서 SDDC를 구성한다면 Vault Raft Cluster를 DR로 구성하여 클러스터를 HA 구성하는 방식이 존재합니다. 향후에는 클러스터 HA 구성 방식에 대해 다뤄보겠습니다.&lt;/p&gt;</description>
      <category>Cloud Native Solution/[Hashicorp] Vault</category>
      <author>Cloud Engineer</author>
      <guid isPermaLink="true">https://kimdy.tistory.com/49</guid>
      <comments>https://kimdy.tistory.com/49#entry49comment</comments>
      <pubDate>Sat, 27 Aug 2022 14:44:20 +0900</pubDate>
    </item>
    <item>
      <title>[Vault] Vault 개념/구성/작동원리</title>
      <link>https://kimdy.tistory.com/48</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;0. 개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자와 시스템 운영자가 업무를 수행할 때 SSH Signed RSA 접속, DB 계정 정보 등에 활용되는 비밀 정보를 빈번하게 사용하게 됩니다. 다양한 기업에서는 엑셀 파일 암호화, 자체 자산관리시스템을 활용한 정보 관리 등을 통해 해당 비밀 정보를 효과적으로 관리하기 위해 노력해왔습니다. 하지만 관리 대상 IT 자산이 선형적으로 증가함과 동시에 자산관리시스템 관리에 따른 부담 증가로 이어지는 문제가 발생했는데요. Hashicorp에서는 이러한 문제점을 해결하기 위해 비밀 정보를 중앙에서 효율적으로 관리하도록 도와주는 Vault라는 솔루션을 개발하게 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Vault란?&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;440&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDwZo0/btrKb71kAIy/R2EwjTnMxxK8mZAEtTgWp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDwZo0/btrKb71kAIy/R2EwjTnMxxK8mZAEtTgWp0/img.png&quot; data-alt=&quot;Hashicorp Vault CI&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDwZo0/btrKb71kAIy/R2EwjTnMxxK8mZAEtTgWp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDwZo0%2FbtrKb71kAIy%2FR2EwjTnMxxK8mZAEtTgWp0%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;440&quot; height=&quot;439&quot; data-origin-width=&quot;440&quot; data-origin-height=&quot;439&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Hashicorp Vault CI&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Hashicorp Vault를 한 문장으로 정의하면 민감한 데이터와 비밀 정보(Secrets)를 중앙에서 효과적으로 보호 및 관리해주는 솔루션입니다. Vault는 &lt;b&gt;REST API를 기반&lt;/b&gt;으로 작동하며, UI 또는 CLI를 통해 각종 기능을 다룰 수 있습니다. 또한 Vault는 OIDC 솔루션과 연동할 수 있도록 하여 인증된 사용자에게 &lt;span&gt;&lt;b&gt;RBAC 혹은 ABAC을 기반&lt;/b&gt;으로&lt;span&gt; &lt;/span&gt;&lt;/span&gt;권한을 부여 및 관리할 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Vault 구성&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1506&quot; data-origin-height=&quot;841&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rsDGv/btrKqQE39q5/cDnj1X9kTnroNXp9AUkVIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rsDGv/btrKqQE39q5/cDnj1X9kTnroNXp9AUkVIK/img.png&quot; data-alt=&quot;Vault 아키텍쳐 (출처 : Hashicorp Vault Architecture)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rsDGv/btrKqQE39q5/cDnj1X9kTnroNXp9AUkVIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrsDGv%2FbtrKqQE39q5%2FcDnj1X9kTnroNXp9AUkVIK%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;1506&quot; height=&quot;841&quot; data-origin-width=&quot;1506&quot; data-origin-height=&quot;841&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Vault 아키텍쳐 (출처 : Hashicorp Vault Architecture)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-1. 구성 요소&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-1-1. Storage Backend&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vault에 의해 암호화된 데이터를 저장할 스토리지를 의미합니다. 22개 이상의 스토리지를 지원하고 있으며 각 스토리지마다 지원해주는 가용성 및 보안성 등이 다르니 구성 전 환경에 맞는 솔루션을 찾아야합니다. 일반적으로 환경에 따라 아래와 같이 구성합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개발 환경 : FileSystem 또는 In-memory&lt;/li&gt;
&lt;li&gt;운영 환경 : Consul 또는 Integrated Storage (Raft)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관련 내용은 하기와 같이 Hashicorp 공식 홈페이지에서 안내하고 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bw3bLq/btrKoUaQjeM/rp5bEc3PQb68BDTDTNh1bk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bw3bLq/btrKoUaQjeM/rp5bEc3PQb68BDTDTNh1bk/img.png&quot; data-alt=&quot;Consul vs Integrated Storage&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bw3bLq/btrKoUaQjeM/rp5bEc3PQb68BDTDTNh1bk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbw3bLq%2FbtrKoUaQjeM%2Frp5bEc3PQb68BDTDTNh1bk%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;993&quot; height=&quot;436&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;436&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Consul vs Integrated Storage&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-1-2. Barrier&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사전상 의미 그대로 장벽 즉, 외부에서 Vault에 함부로 접근할 수 없도록 막아주는 벽이라고 생각하면 됩니다. IT 인프라에서 Bastion과 비슷한 역할을 수행하며, 외부에서 Vault 컴포넌트 혹은 Storage Backend에 저장된 데이터에 접근할 때 Barrier를 반드시 통과해야 됩니다. Vault Barrier에서는 일반적으로 Unseal된 Vault 컴포넌트 혹은 복호화된 Secret 데이터만 접근할 수 있도록 합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-1-3. Auth Method&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vault 사용자가 서버에 인증하는 방식을 정의합니다. 일반적으로 Keycloak 등과 같은 SSO (Single Sign On) 솔루션과 연계하여 사용자 인증을 수행합니다. Vault에서 제공하는 사용자 인증 솔루션은 아래와 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;999&quot; data-origin-height=&quot;263&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCwv4E/btrKo2T1PiQ/M4WAUJc3rBK5pv4CAPQkx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCwv4E/btrKo2T1PiQ/M4WAUJc3rBK5pv4CAPQkx0/img.png&quot; data-alt=&quot;Vault에서 지원하는 Auth Method 솔루션&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCwv4E/btrKo2T1PiQ/M4WAUJc3rBK5pv4CAPQkx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCwv4E%2FbtrKo2T1PiQ%2FM4WAUJc3rBK5pv4CAPQkx0%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;999&quot; height=&quot;263&quot; data-origin-width=&quot;999&quot; data-origin-height=&quot;263&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Vault에서 지원하는 Auth Method 솔루션&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Auth Method와 논외로, Vault에서는 인증된 사용자에 대해 AWS IAM의 RBAC 혹은 ABAC 기반으로 권한 부여를 할 수 있도록 Policy 및 Group 기반 Authorization 관리 기능을 제공합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-1-4. Secret Engine&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 안전하게 저장/생성 및 암호화/복호화할 수 있도록 해주는 컴포넌트입니다. 본 기능을 활용하여 OS, DBMS 등에 존재하는 Secret 정보를 암호화/복호화할 수 있습니다. Secret Engine은 REST API 혹은 CLI를 기반으로 활성화(enabled) 및 속성을 핸들링할 수 있습니다. Secret Engine을 통해 사용자는 SSH, DBMS 등과 연계하여 Secret 정보를 관리할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;322&quot; data-origin-height=&quot;330&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXh6sy/btrKqFKzjXY/0L49uVeC5kJpFXQZABWxGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXh6sy/btrKqFKzjXY/0L49uVeC5kJpFXQZABWxGK/img.png&quot; data-alt=&quot;Secret Engine을 통해 관리할 수 있는 Secret Data&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXh6sy/btrKqFKzjXY/0L49uVeC5kJpFXQZABWxGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXh6sy%2FbtrKqFKzjXY%2F0L49uVeC5kJpFXQZABWxGK%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;322&quot; height=&quot;330&quot; data-origin-width=&quot;322&quot; data-origin-height=&quot;330&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Secret Engine을 통해 관리할 수 있는 Secret Data&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이외에도 Vault 공식 홈페이지(&lt;a href=&quot;https://www.vaultproject.io/docs/secrets&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;)를 통해 지원되는 솔루션을 확인할 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 포스팅에서는 Vault를 사용하기 위해 알아야할 가장 기초적인 내용을 다뤘습니다. (위 기능 외에도 Audit Devices, Vault Agent 등 Vault에서 제공하는 다양한 컴포넌트가 존재합니다.) 어떤 오픈소스를 학습하던지 해당 도구를 사용하는 목적과 작동원리 및 구성요소를 먼저 학습하는게 중요한 것 같습니다. 따라서 본 포스팅에서는 해당 내용을 다뤘으며, 다음 포스팅에서는 좀더 심화된 개념 또는 실습과 관련된 포스팅을 다뤄보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[출처]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://www.vaultproject.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.vaultproject.io/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://www.joinc.co.kr/w/man/12/vault&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.joinc.co.kr/w/man/12/vault&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/getting-started-install?in=vault/getting-started&quot;&gt;https://learn.hashicorp.com/tutorials/vault/getting-started-install?in=vault/getting-started&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://www.vaultproject.io/docs/configuration/storage&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.vaultproject.io/docs/configuration/storage&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://learn.hashicorp.com/tutorials/vault/storage-migration-checklist&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://learn.hashicorp.com/tutorials/vault/storage-migration-checklist&lt;/a&gt;&lt;/p&gt;</description>
      <category>Cloud Native Solution/[Hashicorp] Vault</category>
      <category>auth methods</category>
      <category>backend storage</category>
      <category>Barrier</category>
      <category>hashicorp</category>
      <category>key/value</category>
      <category>REST API</category>
      <category>Secret</category>
      <category>secret engines</category>
      <category>Vault</category>
      <category>vault agent</category>
      <author>Cloud Engineer</author>
      <guid isPermaLink="true">https://kimdy.tistory.com/48</guid>
      <comments>https://kimdy.tistory.com/48#entry48comment</comments>
      <pubDate>Tue, 23 Aug 2022 21:30:12 +0900</pubDate>
    </item>
    <item>
      <title>[Vault][Secret Engine] SSH - OTP 구성 방식</title>
      <link>https://kimdy.tistory.com/47</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;00. 개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자는 Vault를 활용하여 Backend Storage에 데이터를 저장, 생성 및 암호화하기 위해 Secret Engine을 사용합니다. Vault에서는 SSH 관련 기능으로 OTP 방식과 동적 키 방식 2가지를 제공하고 있습니다. 본 포스팅에서는 SSH OTP 방식에 대해 알아보겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;01. OTP 방식&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 서버를 접속할 때마다 Vault에게 일회성 비밀번호(One Time Password)를 요청하고 응답받은 패스워드를 입력하여 접속하는 방식입니다. 이 때, 시스템 관리자는 접속 대상 서버에 vault-ssh-helper라는 유틸리티를 설치해야 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;02. vault-ssh-helper를 활용한 인증 프로세스&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자와 접속 서버 그리고 Vault와의 인증 방식은 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;299&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HK7Wn/btrJ70nz5Dx/vkyio4hUfYAWMyIRzpl7A1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HK7Wn/btrJ70nz5Dx/vkyio4hUfYAWMyIRzpl7A1/img.png&quot; data-alt=&quot;사용자가 vault-ssh-helper를 통해 OTP 인증을 받는 프로세스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HK7Wn/btrJ70nz5Dx/vkyio4hUfYAWMyIRzpl7A1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHK7Wn%2FbtrJ70nz5Dx%2Fvkyio4hUfYAWMyIRzpl7A1%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;700&quot; height=&quot;299&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;299&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사용자가 vault-ssh-helper를 통해 OTP 인증을 받는 프로세스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;① 사용자는 Vault에게 SSH OTP 패스워드를 요청합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;② Vault는 사용자에게 OTP 패스워드를 발급해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;③ 사용자는 Vault로부터 발급받은 OTP 패스워드를 통해 원격 서버에 접속합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;④ 원격 서버는 본 서버에 설치된 vault-ssh-helper를 통해 Vault 서버로부터 OTP 패스워드 유효성 검사를 수행합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;03. OTP 인증 구성 실습&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 Vault 서버와 접속할 원격 서버에서 어떤 구성을 수행해야 되는지에 대한 실습을 진행하겠습니다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;03-1. Secret Engine 마운트 (Vault 서버)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 Vault 서버에서 Secret Engine - SSH 방식을 마운팅합니다. Path는 고유 이름(ssh-path)로 지정해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1660872589828&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vault secrets enable -path=ssh-otp ssh&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;03-2. Role 생성 (Vault 서버)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성한 Secret Engine에 적용할 Role을 생성해줍니다. 본 Role을 토대로 접속 가능한 사용자 IP 및 계정 등이 구성됩니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1660873050971&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vault write ssh/roles/test_ssh_otp_role \
	key_type=otp \
	default_user=testuser \
	allowed_users=testuser \
	cidr_list=0.0.0.0/0&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;key_type : 어떤 방식으로 사용자 인증을 수행할지를 지정 (otp, dynamic, ca)&lt;/li&gt;
&lt;li&gt;default_user : 인증을 성공한 사용자가 기본적으로 접속할 유저를 지정&lt;/li&gt;
&lt;li&gt;allowed_users : 인증을 성공한 사용자가 접속할 수 있는 리눅스 유저를 지정 (본 포스팅에서는 testuser만 접속 가능하도록 지정)&lt;/li&gt;
&lt;li&gt;cidr_list : 해당 role 적용이 가능한 IP 대역&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 옵션에 대해 자세히 학습하고 싶으신 분들은 &lt;a href=&quot;https://www.vaultproject.io/api-docs/secret/ssh&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 클릭하여 확인하시면 됩니다. Vault에서는 공식 문서로 원론적인 내용을 다루는 부분과 API 명세를 다루는 부분을 나누어 제공하고 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;03-3. vault-ssh-helper 설치 (접속 대상 서버)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;접속 대상 서버에서 vault-ssh-helper를 설치해줍니다. wget 명령어를 통해 URL을 통한 설치를 진행하겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1660873940161&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 1. vault-ssh-helper 설치
$ wget https://releases.hashicorp.com/vault-ssh-helper/0.2.1/vault-ssh-helper_0.2.1_linux_amd64.zip
$ unzip vault-ssh-helper_0.2.1_linux_amd64.zip

# 2. 파일 이동
$ mv vault-ssh-helper /usr/local/bin/vault-ssh-helper&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ &lt;span style=&quot;background-color: #fcfcfc; color: #666666;&quot;&gt;/usr/local/bin : &lt;/span&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666;&quot;&gt;수&lt;/span&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666;&quot;&gt;동으로 설치한 컴파일 시스템 패키지를 넣는 공간&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #000000;&quot;&gt;03-4. vault-ssh-helper 구성 (접속 대상 서버)&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #000000;&quot;&gt;vault-ssh-helper에서 바라보는 vault 서버와 사용자 인증에 적용할 SSH 마운트 포인트 및 Role 등을 구성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1660874200951&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 1. vault-ssh-helper에서 사용할 디렉토리 생성
$ mkdir /etc/vault-ssh-helper.d

# 2. 구성 파일 생성
$ vi /etc/vault-ssh-helper.d/config.hcl
vault_addr = &quot;http://{{vault 서버 주소}}:8200&quot;
ssh_mount_point = &quot;ssh-otp&quot;
tls_skip_verify=true
allowed_cidr_list=&quot;0.0.0.0/0&quot;
allowed_roles=&quot;test_ssh_otp_role&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;vault_addr : vault 서버 주소를 지정 (IP 또는 도메인네임)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ssh_mount_point : 사용자가 인증 수행 시 vault-ssh-helper에서 연동할 SSH Secret Engine 마운팅포인트&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;tls_skip_verify : 사용자가 인증 수행 시 TLS를 통한 신뢰성 검증을 skip할지에 대한 여부 지정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;allow_cidr_list : 허용할 CIDR&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;allowed_roles : 사용자가 인증 수행 시 vault-ssh-helper에서 연동할 Role (SSH Secret Engine에 구성된 Role)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;03-5. vault-ssh-helper 구성 검증 수행&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;03-4에서 작성한 config 파일을 통해 vault-ssh-helper와 vault 서버 간 정상적으로 작동되는지 확인합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1660874499608&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vault-ssh-helper -verify-only -config=/etc/vault-ssh-helper.d/config.hcl -dev
2022/08/19 02:00:55 ==&amp;gt; WARNING: Dev mode is enabled!
2022/08/19 02:00:55 [INFO] using SSH mount point: ssh-otp
2022/08/19 02:00:55 [INFO] using namespace:
2022/08/19 02:00:55 [INFO] vault-ssh-helper verification successful!&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;03-6. PAM 인증 구성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vault-ssh-helper가 PAM에서 인증 역할의 일부를 수행하기 때문에 /etc/pam.d/sshd 파일 내용이 다음과 될 수 있도록 해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[주의] SELinux를 비활성화해주거나 별도의 예외처리를 해주셔야 로그 파일이 정상적으로 append됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1660874655539&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vi /etc/pam.d/sshd
#%PAM-1.0
auth    requisite pam_exec.so quiet expose_authtok log=/var/log/vaultssh.log /usr/local/bin/vault-ssh-helper -config=/etc/vault-ssh-helper.d/config.hcl -dev
auth    optional pam_unix.so not_set_pass use_first_pass nodelay
auth       required     pam_sepermit.so
# auth       substack     password-auth
auth       include      postlogin
# Used with polkit to reauthorize users in remote sessions
-auth      optional     pam_reauthorize.so prepare
account    required     pam_nologin.so
account    include      password-auth
# password   include      password-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open env_params
session    required     pam_namespace.so
session    optional     pam_keyinit.so force revoke
session    include      password-auth
session    include      postlogin
# Used with polkit to reauthorize users in remote sessions
-session   optional     pam_reauthorize.so prepare&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;03-7. SSH 데몬 구성 변경&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vault-ssh-helper 정상 작동을 할 수 있도록 /etc/ssh/sshd_config 파일에서 구성을 변경해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1660874818266&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vi /etc/ssh/sshd_config
ChallengeResponseAuthentication yes
UsePAM yes
PasswordAuthentication no&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;03-8. SSH 접속 테스트&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vault 서버에서 credential 생성 후 해당 IP로 접속해본 결과 정상 접속이 됨을 확인할 수 있습니다!&lt;/p&gt;
&lt;pre id=&quot;code_1660876574181&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vault write ssh-otp/creds/test_ssh_otp_role ip={{접속 대상 서버 IP 주소}}
Key                Value
---                -----
lease_id           ssh-otp/creds/test_ssh_otp_role/rEuhGXE2xwrhfdbHFiVwxAwHH
lease_duration     768h
lease_renewable    false
ip                 {{접속 대상 서버 IP 주소}}
key                4910ff5d-4616-f857-b741-b14e57ac6997
key_type           otp
port               22
username           testuser
$ ssh testuser@{{접속 대상 서버 IP 주소}}
Password: {{key 입력}}
Last login: Fri Aug 19 02:32:40 2022 from x.x.x.x
$ exit&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;04. 마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSH Secret Engine에는 2가지 인증 방식(OTP 인증, Signed RSA 인증)이 존재합니다. 본 포스팅에서는 OTP 인증 방식을 다뤘으며 실제로 Vault에서는 해당 방식을 권장하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[출처]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://faun.pub/generating-ssh-one-time-passwords-with-vault-7aa7fab0032&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://faun.pub/generating-ssh-one-time-passwords-with-vault-7aa7fab0032&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://www.vaultproject.io/docs&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.vaultproject.io/docs&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://www.vaultproject.io/api-docs&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.vaultproject.io/api-docs&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Cloud Native Solution/[Hashicorp] Vault</category>
      <category>hashicorp</category>
      <category>otp</category>
      <category>Secret Engine</category>
      <category>SSH OTP</category>
      <category>Vault</category>
      <category>복호화</category>
      <category>암호화</category>
      <author>Cloud Engineer</author>
      <guid isPermaLink="true">https://kimdy.tistory.com/47</guid>
      <comments>https://kimdy.tistory.com/47#entry47comment</comments>
      <pubDate>Fri, 19 Aug 2022 18:19:20 +0900</pubDate>
    </item>
    <item>
      <title>[인프라 테스트] pytest-testinfra를 이용한 인프라 테스트 코드 작성</title>
      <link>https://kimdy.tistory.com/45</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;00. 개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앤서블을 사용하여 인프라 변경 작업을 수행할 때 해당 변경사항에 대한 테스트 코드를 작성하여 검증하는 방식을 도입하면 좋겠다는 생각을 하게 되었습니다. 또한 CI 도구와 결합하여 앤서블 코드 린트/단위/통합 테스트를 통해 다양한 시나리오를 검증함으로써 코드의 신뢰성을 높일 수 있을 것입니다. 본 포스팅에서는 파이썬에서 제공하는 테스트 프레임워크인 pytest에서 플러그인으로 제공하는 testinfra에 대해 알아보겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;01. pytest란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 포스팅은 testinfra를 학습하는게 목적이므로, pytest에 대한 개념만 간단하게 확인하고 본론으로 들어가겠습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;파이썬에서 내장되어 제공되는 테스트 프레임워크로 단위 테스트부터 인수 테스트까지 All-In-One으로 제공&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;02. pytest-testinfra란?&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span&gt;pytest-testinfra는 pytest 플러그인이며, IT 인프라의 실제 상태를 테스트하는데 사용&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주로 구성 관리 도구인 Salt, Ansible, Puppet 등을 적용 후 상태를 테스트하는데 사용됩니다. 본 도구 설계자는 testinfra를 동일 인프라 테스트 도구인 Serverspec과 동일한 기능을 제공하는데 초점을 맞추어 개발했습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;03. pytest-testinfra 설치 방식&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pytest의 플러그인 형태로 제공되므로 본 플러그인을 직접 설치해야됩니다. pytest의 경우 파이썬 내장 라이브러리이기 때문에 기본적으로 설치되어 있겠지만 본 실습에서는 미설치 상태라고 가정하겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1656660654115&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# pytest 설치
$ pip install pytest

# testinfra 설치
$ pip install testinfra

# pytest와 testinfra 플러그인이 정상적으로 설치되었는지 확인
$ pip list | grep pytest 
pytest                        7.1.2
pytest-testinfra              6.7.0&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;04. pytest-testinfra 적용 대상&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예제를 통해 pytest-testinfra를 사용하는 방법은 이해되었습니다. 하지만, 적용 대상 서버를 지정하는건 어떻게 해야할지 모른 상태입니다. testinfra는 중앙 서버(예를 들면 앤서블 코어 서버)에서 다양한 환경(BM/VM/Container 등)에서 구동 중인 호스트에 접속하여 테스트할 수 있는 연결 방식을 제공하고 있습니다. 이 중 local, paramiko 연결 방식에 대해 알아보겠습니다. 다른 연결 방식에 대한 내용은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;오른쪽 링크를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://testinfra.readthedocs.io/en/latest/backends.html&quot;&gt;클릭&lt;/a&gt;하여 확인하시면 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;04-01. Local 연결 방식&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;localhost에 연결하여 testinfra에 명시된 인프라 상태를 테스트하는 방식입니다. 본 방식은 다음과 같은 CLI 명령어를 통해 테스트할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1656662167256&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ py.test --sudo testcode.py&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;04-02. Paramiko 연결 방식&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSHv2 프로토콜을 통해 테스트 대상 서버에 SSH 연결하여&lt;span&gt;&amp;nbsp;&lt;/span&gt;testinfra에 명시된 인프라 상태를 테스트하는 방식입니다. 본 방식은 다음과 같은 CLI 명령어를 통해 테스트할 수 있습니다. testinfra 플러그인에서는 password 인증 방식을 지원하지 않기 때문에 ssh-agent를 통한 연결 방식을 추천하고 있습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1656662167256&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ py.test --ssh-config=/path/to/ssh_config --hosts=1.1.1.1&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;05. pytest-testinfra 문법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 testinfra는 직관적으로 구성되어 있기 때문에 관련 예제를 통해 바로 문법을 학습해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1656660891608&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def test_passwd_file(File):         #
    passwd = File(&quot;/etc/passwd&quot;)    #
    assert passwd.contains(&quot;root&quot;)  #          &amp;rdquo;root&amp;ldquo;
    assert passwd.user == &quot;root&quot;    #   owner   root
    assert passwd.group == &quot;root&quot;   #         root
    assert passwd.mode == 0644      #       


def test_nginx_is_installed(Package):
    nginx = Package(&quot;nginx&quot;)
    assert nginx.is_installed       # nginx    
    assert nginx.version.startswith(&quot;1.10&quot;) #   nginx  


def test_nginx_running_and_enabled(Service):
    nginx = Service(&quot;nginx&quot;)
    assert nginx.is_running         #   nginx     
    assert nginx.is_enabled         # nginx&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일에서 볼 수 있듯이 파이썬을 개발해본 경험이 있다면 매우 직관적으로 이해할 수 있습니다. 다만 함수 형태로 예제가 제공되기 때문에 어떻게 사용하면 될지는 이해가 쉽지만, 실무에 어떻게 적용할지 감을 익히기엔 어려움이 있습니다. 따라서 파이썬 class를 통해 테스트 코드를 실제 어떻게 작성하면 될지 알아보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1656661128274&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import unittest
import testinfra


class Test(unittest.TestCase):

    # Before Environment Configuration
    def setUp(self):
    	# local 방식 : localhost (127.0.0.1)에서 테스트를 수행하며 sudo 권한으로 진행
        self.host = testinfra.get_host(&quot;local://&quot;, sudo=True)

	# Paramiko 방식 : wheel 그룹에 속한 tech 계정으로 1.1.1.1 서버에 22번 포트로 SSHv2 접속
        self.host = testinfra.get_host(&quot;paramiko://wheel:tech@1.1.1.1:22&quot;)

    # After Test process
    def tearDown(self) -&amp;gt; None:
        return super().tearDown()


    # tech 계정과 wheel 그룹이 존재하는지 확인
    def test_exist_account_group(self):
        viewer_user = self.host.user(&quot;tech&quot;)
        wheel = self.host.group(&quot;wheel&quot;)
        
        self.assertTrue(wheel.exists)
        self.assertTrue(viewer_user.exists)


    # ntpd 서비스 상태 확인
    def test_systemd_services(host):
        assert host.package('ntpd').is_installed == True
        ntp = host.service('ntp')
        assert ntp.is_running == True
        assert ntp.is_enabled == True


if __name__ == &quot;__main__&quot;:
    unittest.main()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 실제 개념 검증을 위해 사용되었던 코드이며 위와 같이 테스트 코드를 작성하시면 됩니다. 위 모듈 이외 다른 모듈을 사용하고자 할 경우 오른쪽 링크를 &lt;a href=&quot;https://testinfra.readthedocs.io/en/latest/modules.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;클릭&lt;/a&gt;하여 확인하시면 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;06. 실행 결과&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드를 travis ci를 통해 테스트할 경우 아래와 같은 결과값을 확인할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1656662426310&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ python --version
Python 3.6.7

$ pip --version
pip 21.3.1 from /home/travis/virtualenv/python3.6.7/lib/python3.6/site-packages/pip (python 3.6)
install.1
88.58s

$ pip install ansible
install.2
0.94s

$ pip install pytest-testinfra
install.3
0.58s

$ ansible --version
0.67s

$ ansible-playbook ansible/test/test_playbook.yml --syntax-check

[DEPRECATION WARNING]: Ansible will require Python 3.8 or newer on the 
controller starting with Ansible 2.12. Current version: 3.6.7 (default, Jun 12 
2019, 02:05:21) [GCC 5.4.0 20160609]. This feature will be removed from 

...

PLAY RECAP *********************************************************************
localhost                  : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
The command &quot;ansible-playbook ansible/test/test_playbook.yml&quot; exited with 0.
0.54s

$ py.test ansible/test/test_ubuntu.py

============================= test session starts ==============================
platform linux -- Python 3.6.7, pytest-7.0.1, pluggy-0.12.0
rootdir: /home/travis/build/dev-kimdoyoung/IaC_provisioning_openstack_aws
plugins: testinfra-6.8.0
collected 1 item                                                               
ansible/test/test_ubuntu.py .                                            [100%]
============================== 1 passed in 0.13s ===============================
The command &quot;py.test ansible/test/test_ubuntu.py&quot; exited with 0.
Done. Your build exited with 0.&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;07. 마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬에서 내장으로 제공하는 테스트 프레임워크인 pytest 에서 인프라 테스트 목적의 플러그인 testinfra에 대해 알아봤습니다. 본 플러그인과 CI 도구를 연계하여 TDD 기반의 앤서블 구성 자동화 등을 수행할 수 있습니다.&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://velog.io/@sangyeon217/pytest&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@sangyeon217/pytest&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://testinfra.readthedocs.io/en/latest/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://testinfra.readthedocs.io/en/latest/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps/테스트</category>
      <author>Cloud Engineer</author>
      <guid isPermaLink="true">https://kimdy.tistory.com/45</guid>
      <comments>https://kimdy.tistory.com/45#entry45comment</comments>
      <pubDate>Fri, 1 Jul 2022 17:05:50 +0900</pubDate>
    </item>
    <item>
      <title>[프로세스] VIRT, RES, SHR과 Memory Commit</title>
      <link>https://kimdy.tistory.com/44</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;0. 들어가기 전&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linux에서 top 명령어를 입력하면 특정 Interval 간격마다 화면을 갱신하면서 보여줍니다. 출력값에서 OS의 구동 시간(uptime), 접속 유저, Load Average, 메모리 사용량, 전체 프로세스 현황 등 시스템 운영에 필요한 다양한 정보를 확인할 수 있습니다. 특정 프로세스에 대한 정보를 확인하고자 할 때, VIRT, RES, SHR 그리고 S라는 용어가 등장하는데 해당 용어가 어떤 것을 의미하는지 알아보는 포스팅을 작성하겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. VIRT, RES, SHR 개념&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;490&quot; data-origin-height=&quot;457&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dPtVNm/btrC76h4jVY/nWLPzK0DZDHeKT9tPE10Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dPtVNm/btrC76h4jVY/nWLPzK0DZDHeKT9tPE10Kk/img.png&quot; data-alt=&quot;VIRT, RES, SHR 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dPtVNm/btrC76h4jVY/nWLPzK0DZDHeKT9tPE10Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdPtVNm%2FbtrC76h4jVY%2FnWLPzK0DZDHeKT9tPE10Kk%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;351&quot; height=&quot;327&quot; data-origin-width=&quot;490&quot; data-origin-height=&quot;457&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;VIRT, RES, SHR 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VIRT, RES, SHR 용어의 개념을 먼저 정의하겠습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;VIRT : 프로세스가 리눅스 커널로부터 할당받은 &lt;b&gt;최대 가상 메모리(Virtual Memory)&lt;/b&gt; 전체 크기&lt;/li&gt;
&lt;li&gt;RES : 프로세스가 실제로 &lt;b&gt;최대 물리 메모리(Physical Memory)&lt;/b&gt;에서 사용하고 있는 전체 크기&lt;/li&gt;
&lt;li&gt;SHR : 다른 프로세스와 공유하는 &lt;b&gt;최대 공유 메모리(Shared Memory)&lt;/b&gt;의 전체 크기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 특정 프로세스가 커널로부터 RES, VIRT, SHR를 할당받고 실제 물리 영역의 메모리에서 사용하는 공간은 RES를 통해 확인할 수 있습니다. 따라서 &lt;u&gt;top 명령어를 통해 메모리 점유율이 높은 프로세스를 찾고싶을 경우 RES값이 높은 프로세스&lt;/u&gt;를 찾으면 됩니다. 위에서 각 용어 별로 &lt;b&gt;최대 메모리&lt;/b&gt;라고 표현한 이유는 프로세스가 최대로 사용 가능한 메모리 크기를 의미하기 때문입니다. 즉, 커널로부터 사용을 예약받은 메모리 크기입니다. 해당 개념은 디스크의 thin provisioning과 유사한 느낌을 가지고 있습니다. 이를 그림으로 표현하면 아래와 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;466&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AymOk/btrC6e9fVmE/9BAKeT2uuUnb9mCQmUSpU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AymOk/btrC6e9fVmE/9BAKeT2uuUnb9mCQmUSpU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AymOk/btrC6e9fVmE/9BAKeT2uuUnb9mCQmUSpU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAymOk%2FbtrC6e9fVmE%2F9BAKeT2uuUnb9mCQmUSpU1%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;460&quot; height=&quot;313&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;466&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림을 해석하면 프로세스는 커널로부터 물리 디스크 2GB까지 사용 가능하도록 할당받았으며, 가상 메모리는 2GB까지 사용할 수 있도록 할당받았습니다. 따라서 프로세스는 자신이 2GB까지 사용이 가능한 것 처럼 인식하는 반면, 커널은 해당 프로세스가 현재 점유 중인 메모리 크기는 2GB 미만이며 최대 2GB까지 사용이 가능한 것으로 인지합니다. 이처럼 물리 메모리와 가상 메모리가 고정 크기로 할당받지 않는 상태로 메모리 사용이 가능한 이유는 커널에서 Memory Commit이라는 동작 방식을 기반으로 메모리를 할당/관리하기 때문입니다. 이는 커널 파라미터 중 vm.overcommit_memory라는 파라미터를 통해 구동방식을 설정할 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Memory Commit 작동 원리&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1136&quot; data-origin-height=&quot;707&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dOHLVY/btrC89dZeds/25MfUFUBdmMhiCltJSwyCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dOHLVY/btrC89dZeds/25MfUFUBdmMhiCltJSwyCK/img.png&quot; data-alt=&quot;Memory Commit 작동 방식&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dOHLVY/btrC89dZeds/25MfUFUBdmMhiCltJSwyCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdOHLVY%2FbtrC89dZeds%2F25MfUFUBdmMhiCltJSwyCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1136&quot; height=&quot;707&quot; data-origin-width=&quot;1136&quot; data-origin-height=&quot;707&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Memory Commit 작동 방식&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Memory Commit은 위와 같은 방식으로 작동하며 파라미터값은 아래와 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;vm.overcommit_memory=0 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;default로 설정되는 값이며, page cache/swap 영역/slab reclaimable 값을 합해서 최대값을 선정하는 방식&lt;/li&gt;
&lt;li&gt;&lt;span&gt;vm.overcommit_memory=1 :&lt;span&gt; Memory WWrite 요청 즉시 Commit을 진행하는 방식&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;vm.overcommit_memory=2 :&lt;span&gt; 또다른 커널 파라미터인 vm.overcommit_ratio 값과 swap 영역 크기를 바탕으로 계산하는 방식&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한정된 자원의 사용량을 높이기 위해 서버는 CPU에서 하이퍼스레딩 기술, 메모리에서 Memory Commit 기술, 디스크에서 thin 프로비저닝 등 다양한 고성능 컴퓨팅 기술을 적용합니다. 이 중 메모리 부분에서 알아야 할 부분인 VIRT, RES, SHR과 Memory Commit에 대한 포스팅을 마무리하겠습니다.&lt;/p&gt;</description>
      <category>OS 및 스토리지/Linux</category>
      <category>HPC</category>
      <category>memory</category>
      <category>Memory commit</category>
      <category>Res</category>
      <category>SHR</category>
      <category>VIRT</category>
      <category>고성능</category>
      <category>리눅스</category>
      <category>메모리</category>
      <category>커널 파라미터</category>
      <author>Cloud Engineer</author>
      <guid isPermaLink="true">https://kimdy.tistory.com/44</guid>
      <comments>https://kimdy.tistory.com/44#entry44comment</comments>
      <pubDate>Wed, 25 May 2022 21:39:09 +0900</pubDate>
    </item>
    <item>
      <title>[리눅스] 시스템 구성 정보 확인</title>
      <link>https://kimdy.tistory.com/43</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;0. 배경&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 서버를 구축/운영할 때 bash/python와 같은 Shell 혹은 앤서블과 같은 IaC 도구를 사용하여 패치 등을 자동화하기 위해 다양한 시스템 정보 확인 관련 명령어 사용하여 정보를 수집하는 경우가 생깁니다. 물론 앤서블을 사용할 때는 gather_facts 정보를 통해 파악이 가능하지만, 본 기능은 성능 저하 이슈가 발생할 수 있으며 성능을 극한으로 끌어올릴 때 uname을 통해 커널 정보를 수집해야될 수도 있습니다. 따라서 시스템 정보 확인 명령어는 DevOps 및 SE 업무를 수행하는데 반드시 알고 있어야됩니다. 본 포스팅에서는 커널, CPU/Memory, 디스크 및 NIC 등을 확인하는 방법에 대해 알아보겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 커널 정보 확인 (uname)&lt;/h2&gt;
&lt;pre id=&quot;code_1652525733803&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 커널 전체 정보 확인
$ uname -a
Linux ip-172-31-100-100.ap-northeast-2.compute.internal 4.18.0-348.23.1.el8_5.x86_64 #1 SMP Tue Apr 12 11:20:32 EDT 2022 x86_64 x86_64 x86_64 GNU/Linux

# 커널 버전 확인
$ uname -r
4.18.0-348.23.1.el8_5.x86_64

# 프로세서 타입 확인
$ uname -p
x86_64

# 호스트이름 확인 (hostname 명령어와 동일)
$ uname -n
ip-172-31-100-100.ap-northeast-2.compute.internal&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. CPU/BIOS 정보 확인 (dmidecode)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dmidecode는 컴퓨터의 DMI (Desktop Management Interface) 테이블 정보를 사람이 읽을 수 있는 형태로 디코딩하여 보여주는 명령어입니다. 해당 명령어를 통해 CPU 및 BIOS 등에 대한 정보를 확인할 수 있습니다. dmidecode에서 자주 사용하는 타입은 system,processor, memory, bios가 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1652526356754&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# dmide
$ dmidecode -t
dmidecode: option requires an argument -- 't'
Type number or keyword expected
Valid type keywords are:
  bios
  system
  baseboard
  chassis
  processor
  memory
  cache
  connector
  slot
  
# 하드웨어에 대한 정보를 비롯하여 전반적인 시스템 관련 정보를 확인
$ dmidecode -t system
# dmidecode 3.2
Getting SMBIOS data from sysfs.
SMBIOS 2.7 present.
13 structures occupying 568 bytes.
Table at 0x7D9F0000.

Handle 0x0000, DMI type 0, 24 bytes
BIOS Information
	Vendor: Amazon EC2    # BIOS 제조사
	Version: 1.0
	Release Date: 10/16/2017
	Address: 0xF0000
	Runtime Size: 64 kB
	ROM Size: 64 kB
	Characteristics:
		PCI is supported
		EDD is supported
		ACPI is supported
		System is a virtual machine
	BIOS Revision: 1.0

Handle 0x0001, DMI type 1, 27 bytes
System Information
	Manufacturer: Amazon EC2    # 장비 제조사
	Product Name: t3.small      # 장비 타입
	Version: Not Specified
	Serial Number: ec2927db-4af7-88b1-7b5e-1c14c865f446
	UUID: ec2927db-4af7-88b1-7b5e-1c14c865f446
	Wake-up Type: Power Switch
	SKU Number: Not Specified
	Family: Not Specified

....&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1. CPU 정보 확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dmidecode -t system 명령어 입력 시 나오는 부분 중 CPU 관련 내용을 해석해보겠습니다. 본 서버의 CPU는 Intel Xeon 모델이며 단일 소켓으로 최대 3.5 GHz 속도를 낼 수 있습니다. 하기 정보에서 주의깊게 볼 수 있는 부분이 단일 소켓이 보유한 코어 개수가 1개인데 멀티 코어 기능을 수행한다는 것입니다. 즉 한 개 코어로 두 개 코어와 같은 역할을 수행하며 이게 가능한 이유는 하이퍼스레딩 기능이 enabled되어 있기 때문입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1652527024222&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Handle 0x0004, DMI type 4, 42 bytes
Processor Information
	Socket Designation: CPU 0  # Socket 확인
	Type: Central Processor
	Family: Xeon
	Manufacturer: Intel(R) Corporation
...
	Version: Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz # CPU 모델 정보
	Voltage: 1.6 V
	External Clock: 100 MHz
	Max Speed: 3500 MHz    # CPU 최대 속도
	Current Speed: 2500 MHz  # 현재 CPU 속도
...
	Core Count: 1     # 코어 개수
	Core Enabled: 1
	Thread Count: 2
	Characteristics:
		64-bit capable
		Multi-Core    # 1개 코어가 멀티 코어 역할을 수행 (하이퍼스레딩 기능 enabled)
		Hardware Thread
		Execute Protection

...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dmidecode 명령어 뿐만 아니라 lscpu 명령어를 통해 CPU 세부내용 조회가 가능합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1652527842114&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# CPU 세부내용 확인
$ lscpu
Architecture:        x86_64
CPU op-mode(s):      32-bit, 64-bit
Byte Order:          Little Endian
CPU(s):              2    # CPU 코어는 2개
On-line CPU(s) list: 0,1
Thread(s) per core:  2    # 각 코어 당 스레드는 2개
Core(s) per socket:  1    # 각 소켓은 1개 코어로 구성
Socket(s):           1    # 소켓은 1개
NUMA node(s):        1    # NUMA 노드는 1개
Vendor ID:           GenuineIntel
BIOS Vendor ID:      Intel(R) Corporation    # BIOS 제조사
CPU family:          6
Model:               85
Model name:          Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
BIOS Model name:     Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
Stepping:            7
CPU MHz:             2499.996
BogoMIPS:            4999.99
Hypervisor vendor:   KVM
Virtualization type: full
L1d cache:           32K
L1i cache:           32K
L2 cache:            1024K
L3 cache:            36608K
NUMA node0 CPU(s):   0,1
Flags:               fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single pti fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves ida arat pku ospke&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.2. Memory 정보 확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dmidecode -t system 명령어 입력 시 나오는 부분 중 Memory 관련 내용을 해석해보겠습니다. 본 서버는 Physical Memory Array 1개로 구성되어 있으며 해당 어레이에 2GB 메모리 1개가 장착되어 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1652527296311&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Handle 0x0008, DMI type 16, 23 bytes
Physical Memory Array   # Physcal Memory Array임을 확인
	Location: System Board Or Motherboard
	Use: System Memory
	Error Correction Type: Unknown
	Maximum Capacity: 2 GB    # 1개 이상의 Physical Memory를 장착하여 최대 2GB 용량까지 확장 가능
	Error Information Handle: Not Provided
	Number Of Devices: 1

Handle 0x0009, DMI type 17, 34 bytes
Memory Device    # Physical Memory임을 확인
	Array Handle: 0x0008
	Error Information Handle: Not Provided
	Total Width: 72 bits
	Data Width: 64 bits
	Size: 2 GB   # 본 메모리 용량
	Form Factor: DIMM
	Set: None
	Locator: Not Specified
	Bank Locator: Not Specified
	Type: DDR4
	Type Detail: Static Column Pseudo-static Synchronous Window DRAM
	Speed: 3200 MT/s
	Manufacturer: Not Specified
	Serial Number: Not Specified
	Asset Tag: Not Specified
	Part Number: Not Specified
	Rank: Unknown
	Configured Memory Speed: Unknown

Handle 0x000A, DMI type 19, 31 bytes
Memory Array Mapped Address
	Starting Address: 0x0000000000000000k
	Ending Address: 0x000000007FFFFFFFk
	Range Size: 2 GB
	Physical Array Handle: 0x0008
	Partition Width: 1

Handle 0x000B, DMI type 20, 35 bytes
Memory Device Mapped Address
	Starting Address: 0x0000000000000000k
	Ending Address: 0x000000007FFFFFFFk
	Range Size: 2 GB
	Physical Device Handle: 0x0009
	Memory Array Mapped Address Handle: 0x000A
	Partition Row Position: 1

Handle 0x000C, DMI type 127, 4 bytes
End Of Table&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 디스크 정보 확인&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디스크 정보를 확인할 수 있는 명령어는 lsblk, df입니다. lsblk와 df의 차이점에 대해 간략하게 설명드리면, lsblk는 디바이스 드라이버(/dev 참고)에 쿼리를 보내 물리 디스크에 대한 정보를 질의하는 반면, df는 파일시스템에 쿼리를 보내 논리 디스크에 대한 정보를 질의합니다. 본 포스팅에서는 df를 통한 디스크 정보 확인 방법을 살펴보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1652692684327&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ df -h
Filesystem		Size	Used	Avail	Use%	Mounted on
/dev/vda1		 20G	 19G	 543M	 98%	/
tmpfs			 16G	   0	  16G	  0%	/dev/shm
/dev/vda2		1.4T	371G	 986G	 28%	/data
...&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;/dev/sda, /dev/hda, /dev/vda의 차이점&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;- /dev/sda : SCSI, SATA, SAS 타입 (서버용 컴퓨터)&lt;br /&gt;- /dev/hda : IDE 타입 (개인용 컴퓨터)&lt;br /&gt;- /dev/vda : 하이퍼바이저 전용 타입 (XEN, KVM 등)&lt;br /&gt;* SCSI, IDE : 시스템이 실제 물리 디스크와 통신하기 위해 사용하는 컨트롤러 부품의 타입&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 네트워크 정보 확인&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RAID 카드 ,HBA 카드, VGA 카드, NIC 등 메인보드의 주변 장치 종류 및 정보를 확인하고 싶을 때 lspci 명령을 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[출처]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://jangpd007.tistory.com/240&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jangpd007.tistory.com/240&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://lifegoesonme.tistory.com/378&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://lifegoesonme.tistory.com/378&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>OS 및 스토리지/Linux</category>
      <category>df</category>
      <category>dmidecode</category>
      <category>linux</category>
      <category>lsblk</category>
      <category>lscpu</category>
      <category>lspci</category>
      <category>uname</category>
      <category>리눅스</category>
      <category>시스템 구성</category>
      <author>Cloud Engineer</author>
      <guid isPermaLink="true">https://kimdy.tistory.com/43</guid>
      <comments>https://kimdy.tistory.com/43#entry43comment</comments>
      <pubDate>Sat, 14 May 2022 20:33:03 +0900</pubDate>
    </item>
    <item>
      <title>[Linux] 리눅스 time, uptime을 활용한 Load Average 확인 및 활용</title>
      <link>https://kimdy.tistory.com/42</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 배경&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 시스템에서 1분, 5분, 15분 단위로 평균 부하를 파악하고 관련 정보를 활용하여 장애 발생 전 조치를 취해야됩니다. 이 때 평균 부하 즉 Load Average를 확인하기 위해 사용되는 명령어가 uptime 명령어이며, 특정 프로그램 혹은 명령어(사실 ls 등의 명령어도 일종의 프로그램입니다.)의 실행시간 등을 파악할 때 time 명령어가 사용됩니다. 본 포스팅에서는 time, uptime 명령어에 대해 각각 알아보고 해당 결과값 데이터를 통해 확인할 수 있는 내용과 활용 방안에 대해 소개하겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. time 명령어 : 특정 프로그램의 실행 시간을 확인&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;my-binary라는 프로그램을 실행시킨 직후부터 완료되기까지 실제 소요되는 시간을 확인하기 위해서는 time 명령어를 사용합니다. 리눅스 서버에서 실제 time 명령어를 통해 확인해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1647674063086&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ time ./my-binary
real 30m00.02s
user 15m35.32s
sys  20m03.29s&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 결과값을 통해 저희가 알아낼 수 있는 정보에 대해 알아보겠습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1. - 명령어 실행 시간을 다각화 : real time, user time, sys time&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;real : 특정 프로그램을 실행 후 완료되기까지 실제 소요되는 시간
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;real = 프로그램 종료 시간 - 프로그램 실행 시간&lt;/li&gt;
&lt;li&gt;gettimeofday() 시스템 콜을 사용하여 소요 시간을 리턴&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;user : &lt;u&gt;유저 영역&lt;/u&gt;에서 프로그램이 실행된 시간&lt;/li&gt;
&lt;li&gt;sys : &lt;u&gt;커널 영역&lt;/u&gt;에서 프로그램이 실행된 시간&lt;br /&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;커널 처리 명령어 예시: 메모리 동적 할당(malloc) 호출 시 실제 메모리에서 수행되는 시간, 파일 I/O (fread, fwrite) 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.2. - CPU 코어 개수를 확인할 수 있다?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나아가, real, user, sys의 정보를 활용하여 서버에서 구동 중인 CPU 코어 개수를 파악할 수도 있는데요. 일반적으로 자주 혼동하는 부분이real time = user time + sys time이라고 생각하는 것입니다. 하지만, 위의 사례에서 볼 수 있듯이 real time &amp;lt; user time + sys time이 될 수 있습니다. 이러한 현상이 발생할 수 있는 이유는 &lt;u&gt;&lt;b&gt;여러 개의 CPU 코어를 활용&lt;/b&gt;&lt;/u&gt;하여 프로그램을 실행하기 때문입니다. 즉&amp;nbsp;&lt;span style=&quot;background-color: #ffffff; color: #3a3a3a;&quot;&gt;다중 프로세서 시스템에서 프로세스 또는 쓰레드가 병렬로 실행될 수 있으므로 전체 CPU 시간보다 경과 시간이 더 짧을 수 있습니다. 따라서 위의 데이터를 통해 &lt;u&gt;&lt;b&gt;sys time + user time =&amp;lt; real time * CPU 개수&lt;/b&gt;&lt;/u&gt;라는 일반화된 공식을 만들 수 있습니다. &lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #3a3a3a;&quot;&gt;3. uptime : 서버의 전체적인 CPU 부하율을 확인&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 서버에서 uptime 명령어를 실행시키면 아래와 같은 결과를 리턴합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1647675183558&quot; class=&quot;angelscript&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ uptime
# 현재 시간 # 가동시간   # 로그인 중인 사용자 수     평균 부하율   : 1분   5분  15분
  13:39  up 6 mins,      2 users,        load averages: 3.22 5.56 2.95&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, uptime 명령어를 통해 아래와 같은 정보를 확인할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 시간 : 13시 39분&lt;/li&gt;
&lt;li&gt;시스템 부팅 후 구동 시간 : 6분&lt;/li&gt;
&lt;li&gt;시스템에 로그인 중인 사용자 수 (/var/run/utmp에서 데이터 참조) : 로그인 유저는 2명&lt;/li&gt;
&lt;li&gt;1, 5, 15분 동안의 시스템 평균 CPU 부하율 : 1분 동안 3.22, 5분 동안&amp;nbsp; 5.56, 15분 동안 2.95&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1. - CPU 코어 수에 따라 해석이 달라지는 Load Average&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버가 소유한 CPU 코어 개수에 따라 Load Average의 결과값 수치가 같더라도 서버 상태 해석이 달라질 수 있습니다. 같은 수치에 대해 서로 다른 서버가 가지고 있는 코어 개수가 다음과 같다고 가정하겠습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.1.1. - 싱글 코어 (CPU 코어 1개)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1.0 : CPU가 100% 사용 중&lt;/li&gt;
&lt;li&gt;2.0 : CPU가 100% 사용 중, 처리할 전체 프로세스의 50%는 처리 중이며, 나머지 50%는 대기 중&lt;/li&gt;
&lt;li&gt;4.0 : CPU가 100% 사용 중, 처리할 전체 프로세스의 25%는 처리 중이며, 나머지 75%는 대기 중&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.1.2. - 듀얼 코어 (CPU 코어 2개)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1.0 : CPU가 50% 사용 중&lt;/li&gt;
&lt;li&gt;2.0 : CPU가 100% 사용 중&lt;/li&gt;
&lt;li&gt;4.0 : CPU가 100% 사용 중, 처리할 전체 프로세스의 50%는 처리 중이며, 나머지 50%는 대기 중&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Load Average에서 나타내는 데이터는 부하율을 의미하기 때문입니다. CPU 사용률을 통해 다음과 같은 현상을 파악할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.2. - CPU 사용률 : 미래에 일어날 수 있는 장애를 사전에 차단할 수 있는 핵심 지표&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.2.1. - CPU 사용률이 70% 초과&lt;/h4&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;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CPU 증설&lt;/li&gt;
&lt;li&gt;CPU 점유율이 높지만 중요하지 않는 프로세스 종료 ex) notepad, Chrome 등&lt;/li&gt;
&lt;li&gt;서버 재부팅&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.2.2. - CPU 사용률이 100% 빈번하게 찍음&lt;/h4&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CPU 증설&lt;/li&gt;
&lt;li&gt;CPU 점유율이 높지만 중요하지 않는 프로세스 종료 ex) notepad, chrome 등&lt;/li&gt;
&lt;li&gt;서버 재부팅&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.3. 다양한 Load Average 확인 방법&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;/proc/loadavg 파일 (평균 부하율)&lt;/li&gt;
&lt;li&gt;uptime 명령어 (+현재시간 및 구동 시간 + w 명령어 결과)&lt;/li&gt;
&lt;li&gt;w 명령어 (+현재 로그인 중인 사용자 정보)&lt;/li&gt;
&lt;li&gt;top 명령어 (+프로세스 실행 현황 확인)&lt;/li&gt;
&lt;/ul&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;http://daplus.net/unix-%EC%8B%9C%EA%B0%84-1%EC%9D%98-%EC%B6%9C%EB%A0%A5%EC%97%90%EC%84%9C-%E2%80%8B%E2%80%8B%EC%8B%A4%EC%A0%9C-%EC%82%AC%EC%9A%A9%EC%9E%90%EB%B0%8F-sys%EB%8A%94-%EB%AC%B4%EC%97%87/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://daplus.net/unix-%EC%8B%9C%EA%B0%84-1%EC%9D%98-%EC%B6%9C%EB%A0%A5%EC%97%90%EC%84%9C-%E2%80%8B%E2%80%8B%EC%8B%A4%EC%A0%9C-%EC%82%AC%EC%9A%A9%EC%9E%90%EB%B0%8F-sys%EB%8A%94-%EB%AC%B4%EC%97%87/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>OS 및 스토리지/Linux</category>
      <category>core</category>
      <category>CPU</category>
      <category>load average</category>
      <category>TIME</category>
      <category>uptime</category>
      <category>다중 프로세스</category>
      <category>리눅스</category>
      <category>부하</category>
      <category>지표</category>
      <category>프로세스</category>
      <author>Cloud Engineer</author>
      <guid isPermaLink="true">https://kimdy.tistory.com/42</guid>
      <comments>https://kimdy.tistory.com/42#entry42comment</comments>
      <pubDate>Sat, 19 Mar 2022 16:56:35 +0900</pubDate>
    </item>
  </channel>
</rss>