<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>j_user.log</title>
        <link>https://velog.io/</link>
        <description>호기심많은 개발자</description>
        <lastBuildDate>Sun, 22 Jun 2025 08:58:22 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>j_user.log</title>
            <url>https://images.velog.io/images/j_user0719/profile/0ef32327-6561-4aa8-8f63-757dfecdb48c/없.PNG</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. j_user.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/j_user0719" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[나의 MLOps 아카데미아  #1]]></title>
            <link>https://velog.io/@j_user0719/%EB%82%98%EC%9D%98-MLOps-%EC%95%84%EC%B9%B4%EB%8D%B0%EB%AF%B8%EC%95%84-1</link>
            <guid>https://velog.io/@j_user0719/%EB%82%98%EC%9D%98-MLOps-%EC%95%84%EC%B9%B4%EB%8D%B0%EB%AF%B8%EC%95%84-1</guid>
            <pubDate>Sun, 22 Jun 2025 08:58:22 GMT</pubDate>
            <description><![CDATA[<h1 id="intro-of-intro">Intro of Intro</h1>
<p>오랜만에 글을 쓰는것 같다. 아무도 안궁금하겠지만, 근황을 말하자면.. 취준생에서 증권사 fe -&gt; 블록체인 be, fe -&gt; 통신사 be -&gt; 통신사 devops 로 아주 짧은 시간에 여러 분야를 거쳤고 다음 스텝으로 MLOps 를 공부하기 위해 해당 시리즈를 작성하려고 한다. 
나의 velog를 보면 상당한 텀이 존재하는데, 그만큼 실무 경험이 쌓인 만큼 이전과는 달리 조금 전문적인 ( 그러나 읽기 쉬운 ) 글을 쓰도록 노력해보겠다.</p>
<p>없겠지만, 근황 궁금한게 있다면 댓글로... ( TMI 방출 상시대기중.. )</p>
<h1 id="intro">Intro</h1>
<p>이번 시리즈에서 다루는 MLOps는 단순히 머신러닝 모델을 프로덕션에 배포하는 것을 넘어, 시스템 개발과 운영을 통합하고 간소화하며 최적화하는 과정으로 데이터 엔지니어, ML 엔지니어, IT 전문가 간의 협업을 포함하여 머신러닝 애플리케이션의 엔드투엔드 라이프사이클을 자동화하고 최적화하는 것을 목표로 한다. ( 다소 거창하지만 원래 Devops의 목표와 동일하다.) </p>
<h1 id="mlops란">MLOps란?</h1>
<p>MLOps는 다양한 도구와 기술을 활용하여 전체 머신러닝 파이프라인을 프로덕션화하고 자동화하는 데 도움을 준다.</p>
<pre><code>🙋 Devops와 차이점은 뭔가유?

🤖 Devops의 확장 개념으로 기존의 Devops에서 머신러닝에 대한 몇가지 Task가 추가 되었다고 생각하면 됨.

🙋 그게 뭐냐고 그니까.

🤖 밑에서 설명해줌...
</code></pre><p><img src="https://velog.velcdn.com/images/j_user0719/post/ec68e2ac-d80c-48e6-8449-f37764197a6a/image.png" alt=""></p>
<p>사진을 보면 Devops는 뭔가 간단해보이는데, MLOps는 뭔가 더 추가된걸 볼 수 있다.
차이점을 보이는 이유는 크게 두가지인데,</p>
<ol>
<li><p>적용 대상의 특수성: </p>
<ul>
<li>DevOps: 일반적인 소프트웨어 애플리케이션에 초점</li>
<li>MLOps: 머신러닝 애플리케이션의 고유한 특성에 중점. 머신러닝은 모델 구축 그 이상이며, 모델을 생산화하고 확장하는 방법을 라이프 사이클에 녹여내는게 중요하다.</li>
</ul>
</li>
<li><p>MLOps에 추가된 (or 확장된) Task</p>
<ul>
<li>데이터 관리(Data Management): 다양한 소스(데이터베이스, 스트리밍 서비스, API 등)에서 데이터를 수집하고 중앙 집중식으로 저장하는 파이프라인 구축을 포함함. 이는 전통적인 접근 방식에서 데이터 주입 및 관리의 어려움을 해결합니다.</li>
<li>버전 제어(Version Control): 코드뿐만 아니라 데이터와 모델에 대한 버전 관리를 포함함.</li>
<li>파이프라인 자동화(Automation/Pipeline): 데이터 수집, 전처리, 모델 훈련, 평가, 배포 등 순차적으로 실행되는 머신러닝 파이프라인의 자동화를 가능하게 한다.</li>
<li>실험 추적(Experiment Tracking): 하이퍼파라미터 튜닝과 같은 다양한 실험의 결과를 체계적으로 기록하고 시각화하여 최적의 모델을 선택하는 데 사용됩니다. MLflow와 같은 전용 도구가 활용됩니다.</li>
<li>재훈련(Retraining): 데이터 분포의 변화나 모델 성능 저하 시, 모델을 자동으로 재훈련하여 성능을 유지하거나 개선합니다</li>
</ul>
</li>
</ol>
<h1 id="그래서-mlops에서-뭐가-중요한데">그래서 MLOps에서 뭐가 중요한데?</h1>
<p>DevOps를 보면 아무리 아름다운 과정을 넣어도 결국은 <strong>SW가 잘 배포되었냐?</strong> 가 중요한것  처럼 당연하게도 MLOps에서 가장 중요한건 어떻게 <strong>모델을 프로덕션</strong> 하는지가 가장 중요하다.</p>
<p>즉, 모델을 실제 서비스 환경에서 안정적이고 효율적으로 운영할 수 있도록 하는 &#39;<strong>프로덕션화</strong>&#39;와 이 과정을 효율적으로 만드는 &#39;<strong>자동화</strong>&#39;가 핵심이다. 이 두 가지는 MLOps의 존재 이유이자 가장 큰 이점이라고 볼 수 있다.</p>
<pre><code>🙋 모델 프로덕션이라는게 뭔데?

🤖 단순히 모델을 만드는 것을 넘어, 대규모의 실제 사용자에게 서비스를 제공할 수 있도록 모델을 견고한 인프라와 아키텍처 위에 배포하고 확장하는 것을 의미해.

🙋 당연한거 아냐..? 

🤖 전통적인 방식에서는 모델을 개발한 후 실제 서비스에 배포하고 많은 사용자가 몰렸을 때 시스템이 제대로 작동하지 못하는 확장성 문제가 흔했어.

🙋 왜 그랬던건데..?

🤖 예를 들어, 치킨집을 한다고 가정하면 주문이 폭주했을 때 수동으로 재료를 조달하고 요리하던 방식으로는 감당할 수 없었지만, 재료 공급망을 자동화하고 더 큰 요리 기계를 도입하여 대량의 주문을 처리할 수 있게 된 것과 같아.

🙋 이해가 잘 안가는데, 그래서 어떻게 그게 해결된거냐고


🤖 MLOps는 CI/CD(지속적 통합/지속적 배포) 파이프라인과 Docker와 같은 컨테이너화 도구를 활용하여, 서비스 중단 없이 새로운 기능을 추가하고 애플리케이션을 업데이트할 수 있도록 해줘.

  확장성의 경우 클라우드가 발전하며 AWS, GCP, Azure와 같은 클라우드 플랫폼에서 EC2, S3, ECR, SageMaker, CodePipeline 등 다양한 서비스를 활용하여 인프라를 효율적으로 관리 할 수 있게 되었어.



</code></pre><p>모델 프로덕션의 경우 위와 같이 정의 및 현황을 알아 봤으니 이제 MLOps에서 어떤 부분을 자동화 해야하는지 알아보자.</p>
<h1 id="자동화">자동화</h1>
<ul>
<li><p><strong>정의 및 목표</strong>: MLOps의 핵심은 머신러닝 파이프라인의 모든 단계를 자동화하여 인간의 개입을 최소화하고 효율성과 견고성을 극대화하는 것이야. 자동화를 통해 데이터 수집부터 모델 배포, 모니터링, 재훈련에 이르는 전 과정을 끊김 없이 연결할 수 있지.</p>
</li>
<li><p><strong>파이프라인 자동화</strong>: MLOps는 데이터 수집(Data Ingestion), 데이터 검증(Data Validation), 데이터 변환(Data Transformation), 모델 훈련(Model Training), 모델 평가(Model Evaluation), 예측(Prediction) 등의 순차적인 단계를 파이프라인으로 구성하고 자동으로 실행될 수 있도록 지원해.</p>
</li>
<li><p><strong>데이터 관리 자동화</strong>: MLOps는 데이터 웨어하우스와 데이터 주입 파이프라인을 구축하여 다양한 소스(데이터베이스, 스트리밍 서비스, API 등)의 데이터를 자동으로 수집하고 중앙 집중적으로 저장할 수 있게 해줘. 이는 데이터 드리프트(Data Drift)와 같은 문제를 감지하고 자동으로 모델을 재훈련하여 성능을 유지하는 데 필수적이다.</p>
<ul>
<li><p><strong>코드 구현 자동화</strong>: MLOps는 주피터 노트북과 같은 단일 파일 방식 대신 모듈형 코딩을 권장하여, 데이터 주입, 검증, 변환, 모델 훈련 등 각 단계를 별도의 컴포넌트로 분리해. 이렇게 분리된 컴포넌트들은 유지보수, 재사용, 협업, 테스트를 용이하게 하며, DVC(Data Version Control)와 같은 도구를 통해 파이프라인 실행을 추적하고 자동화할 수 있다.</p>
</li>
<li><p><strong>버전 관리 자동화</strong>: Git 및 GitHub를 사용하여 코드베이스뿐만 아니라 데이터와 모델까지 버전 관리를 자동화하여, 변경 사항을 추적하고 필요할 때 이전 버전으로 쉽게 되돌릴 수 있게 해준다.</p>
</li>
<li><p><strong>실험 추적 자동화</strong>: MLflow와 같은 MLOps 도구는 하이퍼파라미터 튜닝과 같은 다양한 실험의 결과를 자동으로 기록하고 시각화된 사용자 인터페이스로 제공해. 이를 통해 수동으로 결과를 기록하고 비교하던 방식에서 벗어나, 가장 성능이 좋은 모델을 효율적으로 식별할 수 있다.</p>
</li>
<li><p><strong>CI/CD를 통한 배포 자동화</strong>: 코드 변경 사항이 발생하면 Jenkins, CircleCI, GitHub Actions와 같은 CI/CD 도구를 통해 자동으로 테스트, 빌드, 배포되어 지속적으로 애플리케이션을 업데이트할 수 있게 해줘. Docker를 이용한 컨테이너화는 환경 간의 일관성을 보장하며, 배포 과정의 오류를 줄여준다.</p>
</li>
</ul>
</li>
</ul>
<h1 id="그래서-정확히-어떻게-이걸-구성하는데">그래서 정확히 어떻게 이걸 구성하는데?</h1>
<p>MLOps의 정의와 중요성을 이해했다면, 왜 그렇게 다양한 도구와 기술이 필요한지 명확히 알 수 있다. MLOps는 머신러닝 시스템의 복잡한 엔드투엔드 라이프사이클을 관리하기 위해 여러 핵심 구성 요소로 이루어져 있으며, 각 구성 요소는 특정 기능을 수행하는 데 필요한 전문 도구와 기술을 요구하기 때문이다.</p>
<ol>
<li><p><strong>데이터 관리 및 수집 (Data Management &amp; Ingestion):</strong></p>
<ul>
<li>MLOps는 데이터 웨어하우스를 구축하고 <strong>ETL(Extract, Transform, Load)</strong> 파이프라인을 생성하여 다양한 소스(데이터베이스, 스트리밍 서비스, API 등)에서 데이터를 자동으로 수집하고 저장하는 데 중점을 둔다.</li>
<li>이러한 과정에는 <strong>Kafka, Apache Kafka</strong>와 같은 스트리밍 서비스 도구와 <strong>MongoDB, MySQL</strong>과 같은 데이터베이스 지식이 필요할 수 있다. 이는 MLOps가 데이터 엔지니어링 개념과 밀접하게 연결되어 있기 때문이다.</li>
</ul>
</li>
<li><p><strong>버전 관리 (Version Control):</strong></p>
<ul>
<li>코드뿐만 아니라 데이터와 모델까지도 변경 사항을 추적하고 필요할 때 이전 버전으로 되돌릴 수 있도록 버전 관리가 필수적다.</li>
<li>이를 위해 <strong>Git, GitHub, Bitbucket</strong>과 같은 도구가 사용된다. 특히 데이터 버전 관리를 위해서는 <strong>DVC(Data Version Control)</strong>와 같은 도구가 활용된다.</li>
</ul>
</li>
<li><p><strong>자동화 및 ML 파이프라인 (Automation &amp; ML Pipelines):</strong></p>
<ul>
<li>MLOps의 핵심은 데이터 수집부터 모델 훈련, 평가, 배포에 이르는 전 과정을 자동화된 파이프라인으로 구축하는 것이다.</li>
<li>파이프라인 구축을 위해 <strong>DVC</strong>가 주요 도구로 언급되며, <strong>Kubeflow, Airflow</strong>와 같은 도구가 가장 유명하다.</li>
<li>코드 구현 측면에서는 주피터 노트북과 같은 단일 파일 방식 대신, 유지보수, 재사용, 협업, 테스트 용이성을 위해 각 단계를 별도의 컴포넌트로 분리하는 <strong>모듈형 코딩</strong> 방식(Python OOP 개념 포함)이 권장된다.</li>
</ul>
</li>
<li><p><strong>실험 추적 (Experiment Tracking):</strong></p>
<ul>
<li>하이퍼파라미터 튜닝과 같이 다양한 모델 실험 결과를 자동으로 기록하고 시각화하여 최적의 모델을 효율적으로 식별하는 기능이 필요함.</li>
<li>이러한 실험 추적을 위해 <strong>MLflow</strong>라는 강력한 도구로 사용된다. MLflow는 사용자 인터페이스를 통해 실험 결과를 비교하고 최적의 모델을 선택할 수 있다.</li>
</ul>
</li>
<li><p><strong>CI/CD (Continuous Integration/Continuous Delivery/Deployment):</strong></p>
<ul>
<li>코드 변경 사항이 발생하면 자동으로 테스트, 빌드, 배포되어 서비스 중단 없이 애플리케이션을 지속적으로 업데이트하는 과정이다.</li>
<li><strong>Jenkins, CircleCI, GitHub Actions</strong>와 같은 CI/CD 도구들이 활용되며, 애플리케이션의 일관된 실행 환경을 보장하기 위해 <strong>Docker</strong>를 사용한 컨테이너화가 필수적이다.</li>
</ul>
</li>
<li><p><strong>모니터링 및 재훈련 (Monitoring &amp; Retraining):</strong></p>
<ul>
<li>배포된 모델의 성능을 지속적으로 모니터링하고(예: 데이터 드리프트 감지), 성능 저하 시 자동으로 모델을 재훈련하는 시스템이 필요하다.</li>
<li>모니터링에는 <strong>Grafana, Evidently</strong>와 같은 도구가 사용되며, 재훈련은 자동화된 파이프라인(DVC, Airflow 등)을 통해 이루어진다.</li>
</ul>
</li>
<li><p><strong>인프라 관리 및 배포 (Infrastructure Management &amp; Deployment):</strong></p>
<ul>
<li>ML 모델은 실제 프로덕션 환경에서 대규모 트래픽을 처리할 수 있도록 견고한 인프라 위에 배포되어야 한다.</li>
<li>이를 위해 <strong>AWS, GCP(Google Cloud Platform), Azure</strong>와 같은 클라우드 플랫폼이 사용되며, 각 플랫폼 내의 다양한 서비스(예: AWS의 EC2, S3, ECR, IAM, SageMaker, CodePipeline; GCP의 Vert.x AI, GCS buckets, VM instances)가 활용된다.</li>
<li>특히, 프로덕션 서버의 대부분이 <strong>Linux 기반 운영 체제</strong>를 사용하며, 머신러닝 및 딥러닝 프레임워크(Scikit-learn, TensorFlow, PyTorch 등)가 Linux에 최적화되어 있어 Linux 명령어를 다루는 능력도 중요하다.</li>
</ul>
</li>
</ol>
<h1 id="결론">결론</h1>
<p>이렇게 대충 MLOps란 뭐고 어떤걸 중요하게 생각하는지, 이를 위해 어떤 구성으로 Flow를 제공하고 어떤 도구를 주로 사용하는지 어렴풋이 다루게 되었다. </p>
<p>앞으로는 각각 구성에 대해서 자세히 보며 어떻게 할지 딥다이브 할 예정이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS VPC [1/2]]]></title>
            <link>https://velog.io/@j_user0719/VPC%EC%9D%98-%EC%B6%94%EA%B0%80%EC%A0%81%EC%9D%B8-%ED%8A%B9%EC%A7%95</link>
            <guid>https://velog.io/@j_user0719/VPC%EC%9D%98-%EC%B6%94%EA%B0%80%EC%A0%81%EC%9D%B8-%ED%8A%B9%EC%A7%95</guid>
            <pubDate>Mon, 14 Aug 2023 09:13:20 GMT</pubDate>
            <description><![CDATA[<h1 id="vpc-fundmental">VPC Fundmental</h1>
<h2 id="vpc">VPC</h2>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/144c9d8b-50d2-4d5d-8229-1321e8dae728/image.png" alt=""></p>
<ul>
<li><p>가상 프라이빗 클라우드는 AWS 계정 전용 가상 네트워크입니다. AWS 클라우드의 다른 가상 네트워크와 논리적으로 격리되어 있습니다.</p>
</li>
<li><p>VPC를 통해 사용자는 자신의 IP 주소 범위 선택, 서브넷 생성, 라우트 테이블 및 네트워크 게이트웨이 구성 등 가상 네트워킹 환경을 완벽하게 제어할 수 있습니다.</p>
</li>
<li><p>VPC에서는 리소스 및 애플리케이션에 안전하고 쉽게 액세스할 수 있도록 VPC에서 IPv4와 IPv6를 모두 사용할 수 있습니다.</p>
</li>
<li><p>VPC는 지역 서비스이며 해당 지역의 모든 AZ에 걸쳐 제공됩니다. 가용 영역(AZ)은 각 리전 내의 격리된 여러 위치입니다.</p>
</li>
</ul>
<h3 id="vpc-sizing">VPC Sizing</h3>
<ul>
<li><p>VPC는 2^16(65536) IP 주소를 사용할 수 있는 10.0.0.0/16과 같은 클래스 없는 도메인 간 라우팅(CIDR) 블록 형태의 IP 주소 집합이 필요합니다.</p>
</li>
<li><p>허용되는 CIDR 블록 크기는 다음 사이입니다.</p>
<ul>
<li>/28 넷마스크(2^4 - 16 사용 가능한 IP 주소의 경우 최소) 및</li>
<li>/16 넷마스크(2^16 - 65536 IP 주소 사용 시 최대) 사이입니다.</li>
</ul>
</li>
<li><p>사설(공개적으로 라우팅할 수 없는) IP 주소의 CIDR 블록을 할당할 수 있습니다.</p>
<ul>
<li>10.0.0.0 - 10.255.255.255(10/8 접두사)</li>
<li>172.16.0.0 - 172.31.255.255(172.16/12 접두사)</li>
<li>192.168.0.0 - 192.168.255.255(192.168/16 접두사)</li>
</ul>
</li>
<li><p>공개적으로 라우팅 가능한 IP 주소의 범위를 지정할 수 있지만, 현재 VPC의 공개적으로 라우팅 가능한 CIDR 블록에서 인터넷에 직접 액세스하는 것은 지원되지 않습니다.</p>
</li>
<li><p>VPC에 한 번 할당된 CIDR 블록은 수정할 수 없습니다.  </p>
<blockquote>
<p><strong>참고 - 이제 VPC 크기를 조정할 수 있습니다.</strong> <a href="https://aws.amazon.com/ko/about-aws/whats-new/2017/08/amazon-virtual-private-cloud-vpc-now-allows-customers-to-expand-their-existing-vpcs/">AWS 블로그 게시물</a>을 참조하세요.</p>
</blockquote>
</li>
<li><p>VPC와 회사 또는 홈 네트워크 간 연결은 설정할 수 있지만, CIDR 블록이 겹치지 않아야 합니다(예: CIDR 10.0.0.0/16인 VPC는 10.1.0.0/16 회사 네트워크와 통신할 수 있지만, IP 주소가 겹쳐서 10.0.37.0/16 회사 네트워크에 연결을 시도하면 연결이 끊어집니다).</p>
</li>
</ul>
<h3 id="vpc-특징">VPC 특징</h3>
<ul>
<li><p>VPC에서 시작된 인스턴스에 대한 <strong>tenancy 옵션</strong>을 설정할 수 있습니다. 기본적으로 tenancy 옵션은 공유됩니다. 전용 옵션을 선택하면 그 안에 있는 모든 인스턴스가 개별 인스턴스 테넌시 설정을 무시하고 전용 하드웨어에서 시작됩니다.
(Tenancy: 이 VPC에서 EC2 인스턴스를 생성할 때 전용 하드웨어 사용 옵션)</p>
</li>
<li><p>VPC를 삭제하려면 VPC 내의 모든 인스턴스를 종료하고 서브넷, 보안 그룹, 네트워크 ACL, 라우트 테이블, 인터넷 게이트웨이, VPC 피어링 연결, DHCP 옵션 등 VPC와 관련된 모든 구성 요소를 삭제한 후에만 삭제할 수 있습니다.</p>
</li>
<li><p>VPC 피어링은 두 VPC(동일하거나 다른 계정 및 지역) 간에 네트워킹 연결을 제공하여 개인 IPv4 주소 또는 IPv6 주소를 사용하여 트래픽을 라우팅할 수 있도록 합니다.</p>
</li>
<li><p>NAT 게이트웨이는 사설 서브넷의 인스턴스가 인터넷에 연결할 수 있도록 허용하지만 인터넷이 인스턴스와의 연결을 시작하지 못하도록 차단합니다.</p>
</li>
<li><p>VPC 엔드포인트를 사용하면 프라이빗 IP 주소를 사용하여 VPC와 지원되는 AWS 서비스 및 PrivateLink로 구동되는 VPC 엔드포인트 서비스 간에 프라이빗 연결을 생성할 수 있습니다.</p>
</li>
</ul>
<h2 id="subnets">Subnets</h2>
<ul>
<li><p>서브넷은 단일 가용 영역에 걸쳐 있으며, 다른 AZ의 장애로부터 격리되도록 설계된 별개의 위치이며, AZ를 가로질러 확장될 수 없습니다.</p>
</li>
<li><p>서브넷은 인터넷 게이트웨이로 구성하여 인터넷을 통한 통신을 사용하거나, 가상 사설 게이트웨이(VPN) 연결을 통해 회사 네트워크와의 통신을 사용할 수 있습니다.</p>
</li>
<li><p>서브넷은 public 또는 private일 수 있으며 인터넷 연결이 있는지, 즉 IGW를 통해 인터넷으로 트래픽을 라우팅할 수 있는지 여부에 따라 달라집니다.</p>
</li>
<li><p>public 서브넷 내의 인스턴스는 인터넷과 통신할 수 있도록 공용 IP 또는 Elastic IP 주소가 할당되어야 합니다.</p>
</li>
<li><p>인터넷에 연결되지 않고 Virtual Private Gateway를 통해서만 트래픽이 라우팅되는 서브넷을  VPN-only 서브넷이라고 합니다.</p>
</li>
<li><p>서브넷은 기본적으로 서브넷 내에서 시작된 모든 인스턴스에 Public IP 주소 할당을 사용하도록 구성할 수 있으며, 인스턴스를 생성하는 동안 재정의할 수 있습니다.</p>
</li>
<li><p>AWS는 각 서브넷에서 사용할 수 없고 인스턴스에 할당할 수 없는 5개의 IP 주소(처음 4개 및 마지막 1개의 IP 주소)를 assigned 합니다. 예를 들어, CIDR 블록이 10.0.0.0/24인 서브넷의 경우 다음 5개의 IP가 예약됩니다.</p>
<blockquote>
<ol>
<li>10.0.0.0: 네트워크 주소</li>
<li>10.0.0.1: VPC 라우터를 위해 AWS가 assigned</li>
<li>10.0.0.2: Amazon 제공 DNS에 매핑하기 위해 AWS에서 assigned</li>
<li>10.0.0.3: 향후 사용을 위해 AWS에서 assigned</li>
<li>10.0.0.255: 네트워크 브로드캐스트 주소. AWS는 VPC에서 브로드캐스트를 지원하지 않으므로 이 주소는 예약되어 있습니다.</li>
</ol>
</blockquote>
</li>
</ul>
<h3 id="subnet-routing">Subnet Routing</h3>
<ul>
<li>각 서브넷은 트래픽을 제어하는 라우트 테이블과 연결되어 있습니다. 만약 테이블이 없다면 vpn 의 main 라우트 테이블을 사용합니다.</li>
</ul>
<h3 id="subnet-security">Subnet Security</h3>
<ul>
<li>서브넷 보안은 보안 그룹 및 NACL을 사용하여 구성할 수 있습니다.</li>
<li>보안 그룹은 인스턴스 수준에서 작동하고 NACL은 서브넷 수준에서 작동합니다.</li>
</ul>
<h1 id="vpc--subnet-sizing">VPC &amp; Subnet Sizing</h1>
<ul>
<li><p>IPv6 CIDR 블록은 선택적으로 VPC에 연결할 수 있습니다.</p>
</li>
<li><p>VPC IPv4 CIDR 블록은 한 번 생성되면 수정할 수 없으며, 기존 CIDR 블록의 크기를 늘리거나 줄일 수 없습니다. <strong>그러나 보조 CIDR 블록을 VPC에 연결하여 VPC를 확장할 수 있습니다.</strong></p>
<blockquote>
<p>제한 사항</p>
</blockquote>
<ul>
<li>허용되는 블록 크기는 /28 netmask와 /16 netmask 사이입니다.</li>
<li>CIDR 블록은 VPC에 연결된 기존 CIDR 블록과 겹치지 않아야 합니다.</li>
<li>CIDR 블록은 VPC 라우트 테이블에 있는 경로의 CIDR 범위와 같거나 커서는 안 됩니다(예: 10.0.0.0/24 CIDR 블록의 경우 10.0.0.0/25와 같은 더 작은 CIDR 블록만 연결할 수 있음).</li>
</ul>
</li>
</ul>
<h1 id="ip-addresses">IP Addresses</h1>
<h2 id="private-ip-addresses">Private IP Addresses</h2>
<ul>
<li><p>Private IP 주소는 인터넷을 통해 연결할 수 없으며, VPC 내의 인스턴스 간 통신에만 사용할 수 있습니다.</p>
</li>
<li><p>모든 인스턴스에는 서브넷의 IP 주소 범위 내에서 기본 네트워크 인터페이스에 Private IP 주소가 할당됩니다.</p>
</li>
<li><p>기본 IP 주소는 인스턴스가 중지되었다가 다시 시작되는 경우에도 평생 동안 네트워크 인터페이스에 연결되며 인스턴스가 종료될 때만 해제됩니다.</p>
</li>
<li><p>Additional Private IP 주소라고 하는 Additional Private IP 주소를 인스턴스에 할당할 수 있으며, 이러한 주소는 한 네트워크 인터페이스에서 다른 네트워크 인터페이스로 재할당할 수 있습니다.</p>
</li>
</ul>
<h2 id="public-ip-address">Public IP address</h2>
<ul>
<li><p>Public IP 주소는 인터넷을 통해 연결할 수 있으며, 인스턴스와 인터넷 간 또는 공용 엔드포인트가 있는 다른 AWS 서비스와의 통신에 사용할 수 있습니다.</p>
</li>
<li><p>인스턴스에 대한 Public IP 주소 할당은 서브넷에 대해 Public IP 주소 지정이 활성화되어 있는지 여부에 따라 달라집니다.</p>
</li>
<li><p>인스턴스를 생성하는 동안 서브넷의 Public IP 주소를 재정의하여 인스턴스에 공용 IP 주소를 할당할 수도 있습니다.</p>
</li>
<li><p>Public IP 주소는 AWS IP 주소 풀에서 할당되며 AWS 계정과 연결되지 않으므로 인스턴스가 중지되었다가 다시 시작되거나 종료될 때 해제됩니다. 즉, 새로운 Public IP가 할당 됩니다.</p>
</li>
</ul>
<h2 id="elastic-ip-address">Elastic IP address</h2>
<ul>
<li><p>Elastic IP 주소는 필요에 따라 인스턴스와 연결 및 연결 해제할 수 있는 정적 영구 공용 IP 주소입니다.</p>
</li>
<li><p>Elastic IP 주소는 VPC에 할당되며, 해제되지 않는 한 계정이 소유합니다.</p>
</li>
<li><p>네트워크 인터페이스에는 Public IP 또는 Elastic IP를 할당할 수 있습니다. 이미 Public IP가 있는 인스턴스에 Elastic IP를 할당하면 Public IP가 해제됩니다.</p>
</li>
<li><p>Elastic IP 주소는 한 인스턴스에서 다른 인스턴스로 이동할 수 있으며, 이는 동일한 계정 내의 동일하거나 다른 VPC 내에 있을 수 있습니다.</p>
</li>
<li><p>Elastic IP는 사용하지 않는 경우, 즉 중지된 인스턴스 또는 연결되지 않은 네트워크 인터페이스와 연결되지 않거나 연결되지 않은 경우 요금이 부과됩니다.</p>
</li>
</ul>
<h1 id="elastic-network-interface-eni">Elastic Network Interface (ENI)</h1>
<p>각 인스턴스는 ENI(기본 네트워크 인터페이스 eth0)에 연결되며 인스턴스에서 분리할 수 없습니다.</p>
<ul>
<li>ENI는 인스턴스에서 연결 또는 분리되었다가 다른 인스턴스에 다시 연결될 때 attributes은 유지 됩니다. ENI가 한 인스턴스에서 다른 인스턴스로 이동하면 네트워크 트래픽이 새 인스턴스로 redirected 됩니다.</li>
</ul>
<blockquote>
<p>ENI의 속성 <br/></p>
</blockquote>
<ul>
<li><p>기본 private IP 주소</p>
</li>
<li><p>하나 이상의 secondary private IP 주소</p>
</li>
<li><p>Private IP 주소당 하나의 Elastic IP 주소</p>
</li>
<li><p>인스턴스를 시작할 때 eth0용 네트워크 인터페이스에 자동 할당될 수 있는 하나의 public IP (기존 ENI를 사용하는 대신 eth0용 네트워크 인터페이스를 생성하는 경우에만 해당).</p>
</li>
<li><p>하나 이상의 보안 그룹</p>
</li>
<li><p>MAC 주소</p>
</li>
<li><p>소스/대상 확인 플래그</p>
</li>
<li><p>설명</p>
</li>
<li><p>여러 ENI를 인스턴스에 연결할 수 있습니다.</p>
<blockquote>
<p>ex)  관리 네트워크 생성, 
VPC에서 네트워크 및 보안 어플라이언스 사용,
서로 다른 서브넷에 워크로드/역할이 있는 듀얼 홈 인스턴스 생성,
저예산, 고가용성 솔루션 만들기...</p>
</blockquote>
</li>
</ul>
<h1 id="route-tables">Route Tables</h1>
<ul>
<li><p>각 VPC에는 Main Route table이 있으며 여러 개의 사용자 지정 경로 테이블을 생성할 수 있습니다.</p>
</li>
<li><p>서브넷은 라우트 테이블에 명시적으로 연결되지 않은 경우  Main Route table에 암시적으로 연결됩니다.</p>
</li>
<li><p>모든 라우트 테이블에는 수정하거나 삭제할 수 없는 VPC 내의 통신을 가능하게 하는 로컬 경로가 포함되어 있습니다.</p>
</li>
<li><p>경로 우선 순위는 트래픽과 일치하는 경로 테이블에서 가장 구체적인 경로로 결정됩니다.</p>
</li>
<li><p>인터넷 게이트웨이, 가상 사설 게이트웨이, VPC 피어링, VPC 엔드포인트, NAT 장치 등에 대한 경로를 정의하려면 경로 테이블을 업데이트해야 합니다.</p>
</li>
</ul>
<h1 id="sg-vs-nacls">SG vs NACLs</h1>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/735cef4d-b0b3-4dcb-bbf2-0d62f32d58c1/image.png" alt=""></p>
<p>VPC에서는 보안 그룹과 네트워크 ACL(NACLS)이 함께 계층화된 네트워크 방어를 구축하는 데 도움이 됩니다.</p>
<p>보안 그룹 - 연결된 인스턴스에 대한 가상 방화벽 역할을 하여 인스턴스 수준에서 인바운드 및 아웃바운드 트래픽을 모두 제어합니다.</p>
<p>NACL(네트워크 액세스 제어 목록) - 연결된 서브넷에 대한 방화벽 역할을 하여 서브넷 수준에서 인바운드 및 아웃바운드 트래픽을 모두 제어합니다.</p>
<h2 id="sg">SG</h2>
<ul>
<li><p>서브넷 수준이 아닌 인스턴스 수준에서 작동합니다.</p>
</li>
<li><p>서브넷 내의 각 인스턴스에는 서로 다른 보안 그룹 집합이 할당될 수 있습니다.</p>
</li>
<li><p>인스턴스에는 <strong>5개의 보안 그룹</strong>이 할당될 수 있으며 각 보안 그룹에는 <strong>50~60개</strong>의 규칙이 있습니다.</p>
</li>
<li><p>인바운드 및 아웃바운드 트래픽에 대해 별도의 규칙을 허용합니다.</p>
</li>
<li><p>인스턴스에 대한 인바운드(수신) 및 아웃바운드(송신) 트래픽 모두에 대한 규칙을 추가하거나 제거(액세스 권한 부여 또는 취소)할 수 있습니다.</p>
</li>
</ul>
<blockquote>
<ul>
<li>default 보안 그룹은 외부 인바운드 트래픽을 허용하지 않지만 동일한 보안 그룹을 가진 인스턴스에서 인바운드 트래픽을 허용합니다.</li>
</ul>
</blockquote>
<ul>
<li><p>default 보안 그룹은 모든 아웃바운드 트래픽을 허용합니다.</p>
</li>
<li><p><strong>허용 규칙만 지정할 수 있고 거부 규칙은 지정할 수 없습니다.</strong></p>
</li>
<li><p>특정 IP, CIDR 범위 또는 VPC 또는 피어 VPC의 다른 보안 그룹에 대한 액세스 권한을 부여할 수 있습니다(VPC 피어링 연결 필요).</p>
</li>
<li><p><strong>Stateful 합니다. 즉, 허용된 인바운드 트래픽에 대한 응답은 아웃바운드 규칙에 관계없이 아웃바운드로 흐르도록 허용되며, 그 반대의 경우도 마찬가지입니다. 따라서 응답에 대한 아웃바운드 규칙이 필요하지 않습니다.</strong></p>
</li>
<li><p>ENI(네트워크 인터페이스)와 연결되어 있습니다.</p>
</li>
<li><p>인스턴스와 연결되어 있고 변경할 수 있으며, 변경하면 기본 네트워크 인터페이스(eth0)와 연결된 보안 그룹이 변경되고 변경 사항은 보안 그룹과 연결된 모든 인스턴스에 즉시 적용됩니다.</p>
</li>
</ul>
<h3 id="connection-tracking">Connection Tracking</h3>
<p>인바운드 트래픽에 대한 응답은 아웃바운드 보안 그룹 규칙에 관계없이 인스턴스 밖으로 흐를 수 있으며, 그 반대의 경우도 마찬가지입니다.</p>
<blockquote>
<p>ex)
인스턴스(호스트 A)가 호스트 B로 트래픽을 시작하고 TCP, UDP 또는 ICMP 이외의 프로토콜을 사용하는 경우, 인스턴스의 방화벽은 호스트 B의 응답 트래픽을 허용하기 위한 목적으로 IP 주소 및 프로토콜 번호만 추적합니다.
호스트 B가 원래 요청 또는 응답 후 600초 이내에 별도의 요청으로 인스턴스에 대한 트래픽을 시작하는 경우, 인스턴스는 응답 트래픽으로 간주되므로 인바운드 보안 그룹 규칙에 관계없이 이를 수락합니다.</p>
</blockquote>
<h2 id="nacls">NACLs</h2>
<ul>
<li><p>네트워크 ACL(NACL)은 하나 이상의 서브넷에 들어오고 나가는 트래픽을 제어하기 위한 방화벽 역할을 하는 VPC의 선택적 보안 계층입니다.</p>
</li>
<li><p>세분화된 제어를 위한 것이 아니며 서브넷 수준에서 할당되고 해당 서브넷의 모든 인스턴스에 적용됩니다.</p>
</li>
<li><p>별도의 인바운드 및 아웃바운드 규칙이 있으며, 각 규칙은 트래픽을 허용하거나 거부할 수 있습니다.</p>
</li>
<li><p>기본 ACL은 모든 인바운드 및 아웃바운드 트래픽을 허용합니다.</p>
</li>
<li><p>새로 만든 ACL은 모든 인바운드 및 아웃바운드 트래픽을 거부합니다.</p>
</li>
<li><p>서브넷에는 하나의 NACL만 할당할 수 있으며 명시적으로 연결되지 않은 경우 기본 NACL과 암시적으로 연결됩니다.네트워크 ACL을 여러 서브넷에 연결할 수 있습니다.</p>
</li>
<li><p>번호가 가장 낮은 규칙부터 순서대로 평가되어 네트워크 ACL과 연결된 서브넷의 트래픽 허용 여부를 결정하는 번호가 매겨진 규칙 목록입니다. </p>
<blockquote>
<p>ex) 규칙 번호 100이 모두 허용이고 110이 모두 거부인 경우 모두 허용이 우선시되고 모든 트래픽이 허용됩니다.</p>
</blockquote>
</li>
<li><p>허용된 인바운드 트래픽에 대한 응답은 아웃바운드 트래픽에 대한 규칙의 적용을 받습니다.</p>
<blockquote>
<p>ex) 특정 IP 주소의 포트 22에서 인바운드 SSH를 사용하도록 설정한 경우 해당 응답에 대한 아웃바운드 규칙도 추가해야 합니다.</p>
</blockquote>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/5d4e2cc0-9e69-44f4-811d-46ed0fcd63b6/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Devops] Pod란 무엇인가?]]></title>
            <link>https://velog.io/@j_user0719/Devops-Pob%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@j_user0719/Devops-Pob%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Sun, 02 Apr 2023 13:43:14 GMT</pubDate>
            <description><![CDATA[<h1 id="파드란">파드란?</h1>
<p><strong>파드</strong> 
= 쿠버네티스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨팅 단위
= 하나 이상의 컨테이너를 포함한 컨테이너 그룹</p>
<p>그래서 파드는 스토리지 및 네트워크 스택을 컨테이너끼리 공유하게 된다.</p>
<blockquote>
<p>🙋 네트워크 스택을 공유한다는게 무슨 의미?
🤖 Pod 안의 모든 컨테이너가 localhost를 통해 서로에게 도달이 가능하다는 것</p>
</blockquote>
<p>예를들어 로컬컴퓨터에서 react를 실행하면 localhost:3000으로 실행이 가능하고, 만약 spring be를 실행한다면 localhost:8080으로 접근이 가능할것이다. 이는 같은 컴퓨터에서 작동했긴때문에, 즉 같은 네트워크 스택을 <strong>공유</strong>하기 때문에 port로 접근할 수 있다는 뜻이다.</p>
<blockquote>
<p>🙋 근데 왜 공유해야하는데?
🤖 파드간의 네트워킹 구성을 단순화하고 여러 네트워크 인터페이스를 관리하는 오버헤드를 줄이기 위해서야.</p>
</blockquote>
<p>만약 컨테이너 한개를 파드에 실행해보자.<img src="https://velog.velcdn.com/images/j_user0719/post/af4a4214-f00a-4f70-a86e-5f2d0902d9e7/image.png" alt=""></p>
<ul>
<li>eth : physical network interface (LAN)</li>
<li>veth : virtual network interface </li>
</ul>
<blockquote>
<p>🙋 veth 가 뭔데? VM과 같은거야?
🤖 ㄴㄴ 다름 둘다 하나의 컴퓨터를 여러대처럼 운용하지만, 가상 네트워크 인터페이스는 많은 프로그램이 동시에 인터넷에 액세스하는데 도움주는것이고,
반면에 VM은 서로 간섭하지 않고 동일한 컴퓨터에서 다른 작업을 수행하기 위함임.</p>
</blockquote>
<p>예시를 보면, docker0과 veth0은 같은 네트워크(172.17.0.0/24)로 묶여있고 docker0는 veth0의 default gateway 역할을 하고 있다.</p>
<blockquote>
<p>🙋 default gateway 가 뭔데? 
🤖 기본 게이트웨이는 인터넷의 올바른 위치로 메시지를 보내는 역할임.
🙋 좀 자세히 설명해줘;;
🤖 컴퓨터가 무엇을 어디로 보내야 할지 모를 경우 기본 게이트웨이로 보내면서 &quot;이것을 올바른 곳으로 보내주세요!&quot; 라고 하는거라고;;</p>
</blockquote>
<p>이때 docker가 컨테이너를 실행할 때 네트워크 namespace를 적절히 설정하여 container1 안에서는 veth0만 보이게 된다.</p>
<blockquote>
<p>🙋  namespace 가 뭔데? 
🤖 시스템 내에서 리소스를 분리하고 격리하는거임.
🙋 그게 왜 필요한데?
🤖 동일한 리소스의 여러 인스턴스가 서로 간섭하지 않게 하기 위해서요.
🙋 그걸 어케 나누는데?
🤖 ㅂㄷㅂㄷ;; 리소스와 리소스를 사용하는 시스템 간에 추상화 수준을 제공해서 다른 리소스로부터 격리 시킴. </p>
</blockquote>
<p>여기서 두번째 컨테이너를 실행해보자.</p>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/9ead7d9d-d771-4610-a58b-7e14bef4fd25/image.png" alt=""></p>
<p>veth1이 새롭게 지정되었고, 마찬가지로 첫번째 컨테이너와 같은 네트워크 대역이기 때문에 서로의 IP를 알면 서로 통신할 수 있다.</p>
<blockquote>
<p>🙋 컨테이너와 bridge간의 연결은 어케하는데?
🤖 linked virtual ethernet device pair로 연결함.
🙋 하..그게뭔데 10덕아..
🤖 물리적 이더넷 케이블로 연결된 것처럼 서로 통신할 수 있도록 두 개의 가상 네트워크 인터페이스를 함께 연결하는 방법임. 
🙋 좀 쉽게  설명해봐;;
🤖 가짜 전화선에 연결된 가짜 전화기 두개라고 생각하세용</p>
</blockquote>
<p>이렇게 되면,  Pod의 네트워크 스택이 veth0, veth1 로 서로 나뉘어져있게 된다. 그래서 도커에서는 컨테이너를 실행할 때 새로운 virtual network interface(veth)를 생성하는 대신 기존에 생성된 interface를 이용하게 된다. </p>
<p>이게 가능한 이유는 namespace는 매우 유연한 구조로 되어있기 때문이다.</p>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/4e8d686d-f17e-4f7c-aad3-d2f449398123/image.png" alt=""></p>
<p>이제 두 컨테이너는 같은 veth0을 공유하게 되었다. 이 특징은 두가지를 의미하는데</p>
<ol>
<li><p>서로의 ip를 알필요없이 port를 통해 컨테이너끼리 통신할 수 있다.</p>
</li>
<li><p>두 컨테이너 모두 바깥에서 172.17.0.2로 접근을 할 수 있다.</p>
</li>
</ol>
<p>사실상 두개가 같은 말이긴 하지만.. (<del>그냥 나눠보고 싶었음</del>) 쿠버네티스에서는 이러한 것을 특별한 컨테이너를 통해 구현한다.</p>
<p>이 컨테이너는 각 Pod마다 존재하며 다른 컨테이너에게 network interface를 제공하는 역할만을 담당한다.</p>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/a36781e4-a14f-4a35-bf33-18d1f4d96f4c/image.png" alt=""></p>
<p>만약 쿠버네티스 Pod가 실행되는 worker node에 들어가서 <code>docker ps</code>라고 검색을 하면 적어도 한개 이상의 <code>pause</code>라는 명령으로 실행된 컨테이너를 볼 수 있을것이다. </p>
<p><code>pause</code> 명령을 가진 컨테이너는 쿠버네티스가 <code>SIGTERM</code> 명령을 내리기 전까지 아무것도 하지 않고 sleep 상태로 존재합니다. 하는 일이 거의 없지만 이 <code>pause</code> 컨테이너가 서로 다른 컨테이너끼리, 바깥 세상과의 통신을 담당하는 <strong>Pod의 핵심</strong>이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Devops] Terraform 의 원리]]></title>
            <link>https://velog.io/@j_user0719/Devops-Terraform-%EC%9D%98-%EC%9B%90%EB%A6%AC</link>
            <guid>https://velog.io/@j_user0719/Devops-Terraform-%EC%9D%98-%EC%9B%90%EB%A6%AC</guid>
            <pubDate>Wed, 08 Mar 2023 13:15:54 GMT</pubDate>
            <description><![CDATA[<p>테라폼을 본격적으로 하기에 앞서, 테라폼의 원리를 이해해야 내가 <strong>무엇을</strong> 해야하고, <strong>무엇이 잘못</strong> 되었는지 알 수 있다. (<del>또한 예비군간 내 동기를 위해</del>) </p>
<h1 id="어떻게-테라폼이-작동할까">어떻게 테라폼이 작동할까?</h1>
<p>테라폼에는 3가지 주체가 있다.</p>
<ul>
<li>Backend</li>
<li>Local</li>
<li>실제 리소스</li>
</ul>
<p>이 세가지 공간은 서로 다르다. 그리고 보통의 테라폼 구현 순서는 아래와 같다.</p>
<blockquote>
<p>로컬에서 .tf 파일을 작성 -&gt; <code>terraform apply</code> -&gt; 실제 리소스에 반영</p>
</blockquote>
<p>좀더 자세히 나누자면, 아래와 같이 나타날 수 있다.</p>
<blockquote>
<p>로컬에서 .tf 파일을 작성 -&gt;<code>terraform init</code> -&gt; <code>terraform apply</code> -&gt; 실제 리소스에 반영</p>
</blockquote>
<p>이 과정 중에서 <code>terraform init</code> 은 뭘 해주는걸까? 하나씩 천천히 알아가 BOZA</p>
<h2 id="terraform-init">terraform init</h2>
<p>결론부터 말하자면, 내가 작성하고 있는 tf파일의 메타데이터를 저장할 공간을 마련하는 것이다.</p>
<p>s3 버킷 안에 백엔드 파일에  </p>
<blockquote>
<p>🙋 왜 공간을 만들어주나요?
🤖 테라폼 입장에서 어떤 인프라와 매핑되는지 알 수 없기 때문이다.</p>
</blockquote>
<h3 id="tfstatetf">tfstate.tf</h3>
<p>실제 리소스가 가지고 있는 상태 파일</p>
<h3 id="naming">Naming</h3>
<p>로컬과 실제 S3 디렉토리 구조를 똑같이 구성한다.</p>
<blockquote>
<p>EX ) provisioning/terrafrorm/eks/dax_{region}/dax000-vbab/backend.tf</p>
</blockquote>
<h1 id="리소스---tf">리소스 -&gt; tf</h1>
<h2 id="1-terraform-import">1. terraform import</h2>
<p>만약 AWS EC2 가 3 개가 있다고 가정 했을때, terraform이 관리하도록 가져오는것이 목적이라 하자.</p>
<blockquote>
<p>Terraform aws_instance 문서를 보면 <code>terraform import aws_instance.web i-12345678</code> 처럼 사용방법을 볼 수 있다.</p>
</blockquote>
<p>자세히 뜯어 보자면</p>
<blockquote>
<p><code>terraform import {내가 만든 tf 리소스 이름} {AWS에서 만든 인스턴스ID}</code></p>
</blockquote>
<p>과 같은 명령어가 나온다. 좀더 예제를 자세히 하자면,</p>
<blockquote>
</blockquote>
<pre><code>resource &quot;aws_instance&quot; &quot;web&quot; {}</code></pre><p><code>terraform import aws_instance.web i-12345678</code> -&gt; 실제 리소스ID인 <code>i-12345678</code> 를 내가 만든 tf파일의 &quot;aws_instance.web&quot; 라는 이름으로 가져오겠다는 뜻이다.</p>
<p>인스턴스ID 는 하나의 리소스와 매핑 되므로, 리소스가 여러개일 경우 각각의 리소스마다 <code>import</code> 를 해줘야한다.</p>
<p>import를 처음 완료하고 <code>terraform.tfstate</code> 파일이 없다면 ,<code>terraform.tfstate</code> 파일을 자동으로 만들어준다.</p>
<p>이어서 나머지 리소스를 import 하게 된다면, 테라폼이 알아서 <code>terraform.tfstate</code> 에 잘 합쳐준다.</p>
<h2 id="2-terraform-plan">2. terraform plan</h2>
<p>이제 내가 로컬에 적은 <code>resource &quot;aws_instance&quot; &quot;web&quot; {}</code> 코드와 실제 클라우드 서비스에 있는 EC2 리소스 i-12345678 는 서로 <strong>연결</strong> 된 상태이다.</p>
<p>그러나 내가 만든 코드는 아무런 내용도 없는 깡통에 불과하다. 그래서 <code>terraform plan</code> 을 해주게 된다면, 엄청나게 많은 리소스들이 함께 지워질 거라는 경고를 해준다.</p>
<p>여기서 힌트를 얻어서 모든 내용을 추가해주면, </p>
<blockquote>
<p>최종적으로 <code>terraform plan</code> 후 <strong>No changes. Infrastructure is up-to-date.</strong> 가 나오면 해당 tf 코드는 성공적으로 작성한 것이 된다.</p>
</blockquote>
<h2 id="3-git-pr-날리기">3. git PR 날리기</h2>
<p>git webhook에서 아틀란티스로 자동 연결하면 아틀란티스에서 테라폼을 원격으로 plan해서 보여준다.</p>
<p><strong>그러나</strong> 치명적인 단점이 있다. 아틀란티스는 로컬의 plan결과를 캐시해서 pr을 날린 시점의 리소스와 실제 리소스 상태의 차이가 있을 수 있다.</p>
<p>즉, pr날린 시점에서는 terraform plan 을 했을 시 no change 였지만, 누군가 내가 merge 하기전에 pr을 날리고 merge를 하게 되면, (<del>물론 락이 걸려 안되긴 하겠지만</del>) 정상적으로 apply를 할 수 없게 된다.</p>
<p><strong>그래서</strong> 깃 댓글로 <code>atlantis plan -p {project name}</code> or <code>atlantis plan</code> 을 해서 변경점을 확인하고,</p>
<p><strong>git rebase</strong>를 통해 변경점을 내 코드에 적용 후 merge(apply) 를 진행해야한다.</p>
<h2 id="4-이후-리펙토링">4. 이후 리펙토링</h2>
<blockquote>
<p>절대 처음부터 리펙토링 하면 안돼. 팩토링이 우선이다.</p>
</blockquote>
<p>리펙의 도구로는</p>
<ul>
<li>module</li>
<li>output</li>
<li>remote state</li>
</ul>
<p>을 애용하면 된다.</p>
<h3 id="module">module</h3>
<p>모듈은 한개 또는 여러개의 .tf, .tf.json 파일로 구성 되어 있고 한개 이상의 resource를 포함한다. 쉽게 생각하자면 일종의 library이다. 각 모듈은 자체적으로 인프라스트럭처를 구성하며, 모듈 간에 의존성을 정의할 수 있다.</p>
<p>module 은 크게 두가지로 나눌 수 있는데,</p>
<ul>
<li><p>Root module : Terraform command 를 수행하는 directory 에 있는 파일들로 구성된 module 을 Root module 이라고 한다.</p>
</li>
<li><p>Child module : 다른 module (Root module 포함) 에서 호출하여 사용되는 module 을 Child module 이라고 한다. Child module 은 여러번 호출되어 사용될 수 있고 module 에 따라 다른 configuration 값을 전달하여 사용할 수도 있다.</p>
</li>
</ul>
<blockquote>
<p>🙋 만약 리펙토링 하게 되면, 이름이 &quot;resource.arn&quot; 에서 &quot;module.resource.arn&quot; 로 바뀌면, resource가 삭제 됐다가 다시 생성되자나유
🤖 그렇게 되면 다 옷벗어야해. 그렇기 때문에 <code>state mv FROM TO</code>를 통해서 이동 시켜줌
🤖 그러면 key가 바뀌게 되면서 </p>
</blockquote>
<h3 id="remote-state">Remote state</h3>
<p>다른 디렉토리의 Terraform 모듈에서 생성된 리소스의 state를 공유하는 기능이다. <code>remote state</code> 를 사용해서 다른 모듈의 리소스를 쉽게 가져올 수 있다.</p>
<h3 id="output">output</h3>
<p>Terraform 모듈에서 생성된 값 또는 리소스의 속성을 외부로 노출하는 기능이다. output을 사용하여 생성된 인프라 리소스의 정보를 다른 Terraform 모듈에서 참조할 수 있다.</p>
<h3 id="사용-예제">사용 예제</h3>
<pre><code># main.tf
provider &quot;aws&quot; {
  region = &quot;us-west-2&quot;
}

data &quot;terraform_remote_state&quot; &quot;db&quot; {
  backend = &quot;s3&quot;
  config = {
    bucket = &quot;my-terraform-state-bucket&quot;
    key    = &quot;db/terraform.tfstate&quot;
    region = &quot;us-west-2&quot;
  }
}

module &quot;vpc&quot; {
  source = &quot;./modules/vpc&quot;
}

module &quot;web&quot; {
  source = &quot;./modules/web&quot;
  vpc_id = module.vpc.vpc_id

  # 가져올 remote_state 설정
  db_instance_id = data.terraform_remote_state.db.outputs.db_instance_id
}

output &quot;web_lb_dns_name&quot; {
  value = module.web.lb_dns_name
}

output &quot;web_sg_id&quot; {
  value = module.web.sg_id
}</code></pre><p>위 코드에서는 <code>main.tf</code> 파일에서 <code>vpc</code>와 <code>web</code> 모듈을 호출하고, <code>web</code> 모듈은 <code>vpc</code> 모듈에서 생성된 VPC ID를 인자로 전달받는다.
또한, <code>data.terraform_remote_state</code>를 사용하여 db 모듈에서 생성된 DB 인스턴스 ID를 가져온다.</p>
<p><code>output</code>을 사용하여 <code>web</code> 모듈에서 생성된 로드밸런서 DNS 이름과 보안 그룹 ID를 외부로 <strong>노출</strong>한다. 이러한 출력을 통해 다른 모듈에서 생성된 인프라스트럭처를 참조할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS 기반 대규모 마이크로서비스 인프라 운영 노하우 ]]></title>
            <link>https://velog.io/@j_user0719/AWS-%EA%B8%B0%EB%B0%98-%EB%8C%80%EA%B7%9C%EB%AA%A8-%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%9D%B8%ED%94%84%EB%9D%BC-%EC%9A%B4%EC%98%81-%EB%85%B8%ED%95%98%EC%9A%B0</link>
            <guid>https://velog.io/@j_user0719/AWS-%EA%B8%B0%EB%B0%98-%EB%8C%80%EA%B7%9C%EB%AA%A8-%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%9D%B8%ED%94%84%EB%9D%BC-%EC%9A%B4%EC%98%81-%EB%85%B8%ED%95%98%EC%9A%B0</guid>
            <pubDate>Fri, 03 Mar 2023 15:51:48 GMT</pubDate>
            <description><![CDATA[<h1 id="intro">Intro</h1>
<p>최근 AWS에 관해 공부를 하다가 AWS 유튜브 채널에 상당히 좋은 내용들이 많아 들으며 일부 내용을 발췌하면서 조금 이해하기 쉽게, 간략하게 정리할 예정이다. 시간이 된다면 전문을 한번 보는것을 추천한다.</p>
<p>(출처 : <a href="https://www.youtube.com/watch?v=9PTdO7DM6XQ&amp;t=1580s">https://www.youtube.com/watch?v=9PTdO7DM6XQ&amp;t=1580s</a>)</p>
<h1 id="운영을-고려한-terraform-구조화">운영을 고려한 Terraform 구조화</h1>
<p>엔터프라이즈급 특히 대규모 인프라를 구축할 경우 고려해야할 세 가지 Terraform을 <strong>잘</strong> 쓸 수 있는지 알아BOZA</p>
<h2 id="관리-범위-쪼개기">관리 범위 쪼개기</h2>
<p>처음 Terraform을 접하는 테린이 (<del>필자..</del>)의 경우 하나의 폴더에 리소스를 추가하면서 시작하게 된다.</p>
<p>이럴 경우 큰 단점이 있는데</p>
<ul>
<li><code>terraform plan</code>, <code>terraform apply</code>  시간이 오래걸림</li>
<li>팀 규모가 커지면, 병목 현상이 일어나기 쉽다</li>
</ul>
<p>그렇다면 BestPractice는 뭘까?</p>
<blockquote>
<p>MS단위로 쪼개는걸 베이스로 한다.</p>
</blockquote>
<h2 id="동일-코드-기반의-인프라-구성">동일 코드 기반의 인프라 구성</h2>
<ul>
<li><p>환경 별 리소스 차이를 최소화하라.</p>
<blockquote>
<p>환경 별로 다를 수 있는거 알지만, 최소한 Prod 에 있는 리소스는 모든 환경별로 기본적으로 <strong>포함</strong> 하고 있어야한다.</p>
</blockquote>
</li>
<li><p>당연하겠지만 동일 코드로 DEV -&gt; STG -&gt; PROD 환경으로 단계적으로 승격한다.</p>
</li>
<li><p><code>terraform workspaces</code> : 분리된 tfstate 공간을 제공한다. ex) <code>terraform workspaces select dev</code>, <code>terraform workspaces select qa</code>..</p>
</li>
<li><p>그러나 실수하기 매우  쉽기 때문에 테라폼 apply를 자동화 한 경우에만 쓰는걸 권장한다.</p>
</li>
</ul>
<h2 id="재사용-가능한-공용모듈">재사용 가능한 공용모듈</h2>
<ul>
<li>일관된 인프라 관리가쉬워 지고 신규 서비스 추가가 용이하다.</li>
<li>주로 VPC, ECS, EKS, ALB , ServerGroup 은 공용모듈로 사용하기 때문에 작성시 재사용성을 항상 고려해야한다.</li>
</ul>
<h2 id="terraform-폴더-구조">Terraform 폴더 구조</h2>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/4da25128-95cb-40a2-96cb-af7e907acc6d/image.png" alt=""></p>
<p>메인 레포의 폴더 구조를 설명하자면, 아래와 같다.</p>
<ul>
<li>주로 메인 레포와 MS 레포로 <strong>대분류</strong>를 한다.</li>
<li>환경을 별도 <strong>account</strong> 로 관리하기 때문에 account별로 <strong>중분류</strong>를 한다.</li>
<li>account 별 <strong>region</strong> 별로 <strong>소분류</strong>를 한다.<ul>
<li>사용하는 MS 모듈 호출만 한다. (버저닝 필요)<ul>
<li>vpc</li>
</ul>
</li>
<li>vpc는 remote storage(s3)에 저장하면 vpc에서 만든 서브넷ID 등을 다른 폴더에서 참조해서 사용할 수 있다.</li>
</ul>
</li>
</ul>
<p>그리고 MS 레포의 폴더링 구조는 모든 리소스를 포함하는걸 기본으로 한다.</p>
<blockquote>
<p>iam은 글로벌리소스인데 ms모듈에 있는게 맞아?</p>
</blockquote>
<ul>
<li>ms에서 이게 빠지거나..담당자 바뀌다보면 어딧는지 못찾아..</li>
<li>nameing 규칙만 잘 지켜줘..</li>
</ul>
<h1 id="terraform-모듈-코드-테스트">Terraform 모듈 코드 테스트</h1>
<blockquote>
<p>모듈을 테스트 가능한가? 인프라에 반영해봐야 아는거 아냐??</p>
</blockquote>
<ul>
<li><p>공용모듈만 새로운 버전으로 업뎃 했을때 A MS는 되고 B MS는 안되면 어떡할려?</p>
</li>
<li><p>region 에 따라 안될수도 있음 (특히 중국 region)</p>
</li>
<li><p>terraform 버전에 따라 다를 수 있음</p>
</li>
</ul>
<p>이런걸 미리 테스트 해봐야 된다.</p>
<blockquote>
<p>아니 그니까 어떤 테스트가 가능한데??</p>
</blockquote>
<h2 id="코드-테스트">코드 테스트</h2>
<ul>
<li>Linting<ul>
<li>정적 코드 분석으로 잠재적 버그 찾기!</li>
<li><code>terraform fmt</code></li>
<li><code>terraform validate</code></li>
</ul>
</li>
<li>Dry-run
  -<code>terraform plan</code></li>
<li><strong>단위/통합 테스트</strong><ul>
<li>CI 툴 사용
ex) InSpec , awspec(젤 많이씀!) , terratest(go)
<img src="https://velog.velcdn.com/images/j_user0719/post/1aed098c-21f5-486e-a817-bcf074509400/image.png" alt=""></li>
</ul>
</li>
</ul>
<ul>
<li>보안 준수 검수</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS VPC]]></title>
            <link>https://velog.io/@j_user0719/AWS-VPC</link>
            <guid>https://velog.io/@j_user0719/AWS-VPC</guid>
            <pubDate>Sun, 19 Feb 2023 09:09:23 GMT</pubDate>
            <description><![CDATA[<h1 id="vpc란-무엇인가">VPC란 무엇인가?</h1>
<blockquote>
<p><strong>AWS 공식문서</strong></p>
</blockquote>
<ol>
<li>사용자의 AWS 계정 전용 가상 네트워크입니다.</li>
<li>VPC는 AWS 클라우드에서 다른 가상 네트워크와 논리적으로 분리되어 있습니다.</li>
<li>EC2 인스턴스 같은 AWS 리소스를 VPC에서 실행할 수 있다.</li>
</ol>
<p>공식 문서를 요약하자면, <strong>VPC는 가상 네트워크다.</strong> 라고 요약할 수 있다. 가상 네트워크를 많이 들어봤는데.. 정확히 그게 뭔데?! 라고 말하면 잘 생각이 나지 않는다. </p>
<p>그러다 <a href="https://medium.com/harrythegreat/aws-%EA%B0%80%EC%9E%A5%EC%89%BD%EA%B2%8C-vpc-%EA%B0%9C%EB%85%90%EC%9E%A1%EA%B8%B0-71eef95a7098">( 출처 ) Harry 님의 미디엄</a>에서 아주 Git똥찬 예시를 발견하였는데..</p>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/7e78b531-f703-4666-b172-b821615c98a5/image.png" alt=""></p>
<p>회사에 인터넷이 이렇게 깔려있다고 치자. 층은 A , B로 나뉘어져 있지만, 주황회사와 파란회사는 사실상 다른 회사라고 가정하자. </p>
<p>그렇다면 아래와 같이 네트워크를 <strong>분리</strong> 시켜야한다.</p>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/116c579d-5e21-4e70-a759-67de67821393/image.png" alt=""></p>
<p>그럼 어떻게 분리할 수 있을까? 기존의 인터넷선을 다 뜯어내고, 각각의 회사마다 전용선을 다시 깔아야할까?</p>
<p>이를 해결하기 위해 나온게 <strong>VPN(가상사설망)</strong> 이다. 사실상 같은 네트워크상에 있지만, 논리적으로 서로를 <strong>분리</strong>시킨 상태를 의미한다.</p>
<blockquote>
<p>🙋 근데 그게 VPC는 아니잖아요
🤖 VPN을 클라우드에 적용하면 VPC겠지
🙋 뭔가 더 쉽게 설명해줘
🤖 공홈 설명 3을 보면 이해가 쉽다.</p>
</blockquote>
<p>설명 3을 보면 <strong>EC2 인스턴스 같은 AWS 리소스를 VPC에서 실행할 수 있다.</strong> 라고 정의했다. 왜 이런 기능을 VPC의 정의에 넣었을까? 반대로 생각해보자.</p>
<p>만약 vpc없이 aws리소스를 사용하면 어떤 문제가 생길까?</p>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/eb5d34ff-0863-4e18-bab9-6ac68154fac0/image.png" alt=""></p>
<p>위와 같이 한 계정에서 만든 모든 aws 리소스들이 한 클라우드 위에 떠있을 것 이다. </p>
<p>그렇게 된다면, 파란색 회사가 새로운 직원을 뽑아서 컴퓨터를 추가할때, 주황색 회사에게도 알려줘야하는 엄청난 복잡도를 높이게 될것이다.</p>
<p>그래서 아래와 같이 VPC를 서로 나눠, 각자 필요한 자원들만 그 안에 위치시켜 사용하도록 하는 것이다.</p>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/59bf14d9-18e8-4df5-a708-2ed50a2b403f/image.png" alt=""></p>
<p>요약하자면, VPC는 클라우드에서 사설 네트워크를 만들어줌으로써 보안성을 향상시키고, 네트워크 관리를 쉽게 할 수 있도록 도와준다.</p>
<h1 id="vpc-구축-과정">VPC 구축 과정</h1>
<p>VPC는 한마디로 &quot;마을&quot; 을 구축하는 과정과 유사하다.</p>
<h2 id="사설-ip-대역-설정">사설 IP 대역 설정</h2>
<p>먼저 어디까지 &quot;마을&quot;로 지정할건지 설정해야한다.</p>
<blockquote>
<p>🙋 이걸 왜 하는데?
🤖 놀이터 가자고 친구가 그러면 당연히 &quot;동네&quot; 놀이터를 의미하지, 3시간 걸리는 곳의 놀이터를 가지는 않을꺼잖아?
🙋 당연하지..?
🤖 그러니까 내부적으로 놀이터의 위치(사설IP)를 사설 IP 대역에서 할당 받는거지
🙋 그럼 다른 VPC에서는 내 VPC를 접근 못하는거야? 촌장이 쇄국정책 펼치냐?
🤖 그럴땐 마을 주소 (공용IP) 를 알려주면 우리 동네 놀이터로 올 수 있겠지</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/debb9bfd-7d2a-4d15-be53-13233216682a/image.png" alt=""></p>
<h2 id="서브넷">서브넷</h2>
<p>서브넷은 VPC를 잘게 쪼개는 과정이다. 거대한 &quot;VPC 마을&quot; 에서 존재하는 &quot;우리집&quot;, &quot;놀이터&quot; 라는 서브넷을 의미한다. VPC 보다 작은 단위기 때문에 IP의 범위도 더 작은 값을 가지게 된다.</p>
<blockquote>
<p>🙋 왜 이렇게 잘게 나눔..?
🤖 마을 내에서 더 많은 네트워크망을 만들기 위해서야</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/5fa3b9a8-ae39-4090-b0c7-27c0e6870db9/image.png" alt=""></p>
<h2 id="라우팅-테이블-라우터">라우팅 테이블, 라우터</h2>
<p>네트워크 요청이 발생되면 어디로 가야할지 우선 라우터로 향하게 됩니다. 이 라우터는 목적지를 알려주는 &quot;VPC 마을&quot;의 <strong>가이드</strong>입니다. 이 가이드는 각각 정의된 라우팅 테이블을 보고 목적지를 알려줍니다. </p>
<p>만약 서브넷A에 대한 요청이 있다면, 이 서브넷A의 라우팅 테이블을 보고 VPC 네트워크 범위를 갖는 요청은 로컬에서 찾도록 되어있다. 하지만 외부로 통하는 다른 트래픽은 인터넷 게이트 웨이를 통해 처리하게 된다.</p>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/41d807f0-9248-4dbc-95a0-6e70f6e6227d/image.png" alt=""></p>
<h2 id="게이트웨이-및-엔드포인트">게이트웨이 및 엔드포인트</h2>
<p>VPC와 인터넷을 연결해주는 하나의 관문이다. 서브넷B의 라우팅테이블을 잘보면 0.0.0.0/0으로 정의되어있습니다. 이뜻은 모든 트래픽에 대하여 IGA(인터넷 게이트웨이) A로 향하라는뜻이다. </p>
<p>인터넷과 연결되어있는 서브넷을 퍼블릭서브넷, 인터넷과연결되어있지않는 서브넷을 프라이빗서브넷이라고한다.</p>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/e4c2bb5a-269a-4ff6-82a5-df95471c41ef/image.png" alt=""></p>
<h2 id="네트워크-acl과-보안그룹">네트워크 ACL과 보안그룹</h2>
<ul>
<li><p>보안그룹 : 모든 허용을 차단하도로록 기본 설정 되고 필요한 설정은 따로 허용해줘야한다. 각각의 보안 그룹별로, 서브넷, 인스턴스에도 따로 설정할 수 있다</p>
</li>
<li><p>네트워크 ACL : 모든 허용을 허용하고 불필요한 트래픽을 막는 용도이다. 서브넷 단위로 적용되고 보안 그룹과 충돌이 있을시 보안 그룹을 우선 순위로 한다.</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/87bbe550-e86c-4be1-99b4-56d8a74570ba/image.png" alt=""></p>
<h2 id="nat-게이트웨이">NAT 게이트웨이</h2>
<p> 프라이빗서브넷이 인터넷과 통신하기위한 아웃바운드 인스턴스이다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Devops] EC2 접속이 안돼요!]]></title>
            <link>https://velog.io/@j_user0719/Devops-EC2-%EC%A0%91%EC%86%8D%EC%9D%B4-%EC%95%88%EB%8F%BC%EC%9A%94</link>
            <guid>https://velog.io/@j_user0719/Devops-EC2-%EC%A0%91%EC%86%8D%EC%9D%B4-%EC%95%88%EB%8F%BC%EC%9A%94</guid>
            <pubDate>Sun, 19 Feb 2023 06:26:09 GMT</pubDate>
            <description><![CDATA[<h1 id="ec2">EC2</h1>
<p>컴퓨팅 머신이다. 우리가 컴퓨터를 클라우드에 띄워서 사용하게 되는데, 당연히 서버가 필요하다. 서버 = 컴퓨팅 엔진 =&gt; 이걸 제공하는게 컴퓨팅 머신.</p>
<p>특징적으로 cpu 갯수나 그런것들을 맘대러 서버를 구성할 수 있다.</p>
<h1 id="근데-접속이-안됨-ㅠ">근데 접속이 안됨 ㅠ</h1>
<p>보통 SSH를 통해서 EC2에 접속하게 되는데, 
<img src="https://velog.velcdn.com/images/j_user0719/post/96a8fac5-833c-4ba9-8a72-85af621c748b/image.png" alt=""></p>
<h2 id="public-ip-확인">Public Ip 확인</h2>
<p>포트와 퍼블릭 ip 를 확인</p>
<blockquote>
<p>🙋 그걸 모르냐?
🤖 private IP 사용하면 안되니까 그러지.(10.0.x.x , 192.168.x.x, 172.16~32.x.x)</p>
</blockquote>
<h2 id="시큐리티-그룹-확인">시큐리티 그룹 확인</h2>
<p>ec2는 기본적으로 방화벽 솔루션으로 시큐리티 그룹을 사용하는데, vpc안에다 ec2를 생성하면 이 그룹에서 내 클라이언트의 ip와 허용된 ip가 일치해야지 접속이 가능하기때문이다.</p>
<h2 id="인스턴스가-퍼블릭-서브넷에-위치했는가">인스턴스가 퍼블릭 서브넷에 위치했는가?</h2>
<p>프라이빗 서브넷에 위치 돼있으면 외부와 통신을 할 수 없음. 라우팅 테이블 확인.
<img src="https://velog.velcdn.com/images/j_user0719/post/bdb38886-7ed9-4180-95c6-72b6abaf52ae/image.png" alt=""></p>
<p>보면 Routes에 0.0.0.0/0 을 확인할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Devops] Terraform 기본]]></title>
            <link>https://velog.io/@j_user0719/Devops-Terraform-%EA%B8%B0%EB%B3%B8</link>
            <guid>https://velog.io/@j_user0719/Devops-Terraform-%EA%B8%B0%EB%B3%B8</guid>
            <pubDate>Wed, 15 Feb 2023 10:26:57 GMT</pubDate>
            <description><![CDATA[<h1 id="intro">Intro</h1>
<blockquote>
<p>Infra as Code</p>
</blockquote>
<p>IaC, 코드로 인프라를 이루는 요즘 트랜드에 맞춰서 한번 공부해보기로 하자.. IaC는 코드동작 = 인프라 동작으로 작동하기 때문에 툴이 필요하다. 다양한 툴이 있지만, 테라폼은 이 씬을 정복한 최고봉이다.</p>
<p>.tf 형식으로 문법도 쉽고 자료도 많다.</p>
<blockquote>
<p>🙋 툴인데 뭔 설명을 하고있냐?
🤖 기본을 모르고 쓰면 어캄?</p>
</blockquote>
<p>먼저 테라폼의 구성요소를 하나씩 살펴보자</p>
<h1 id="테라폼-구성요소">테라폼 구성요소</h1>
<h2 id="provider">Provider</h2>
<p>테라폼으로 생성할 인프라의 종류를 의미합니다. 즉 리소스를 다루기 위한 파일들(sdk 등등) 을 다운로드 하는 역할.</p>
<pre><code>provider &quot;aws&quot; &lt;- 실제 Provider들이 여기 들어감{
    region = &quot;ap-northest-2&quot; &lt;- 여기부터는 파라미터들..
    version = &quot;~^ 3.0&quot; 
}
</code></pre><h2 id="resource">Resource</h2>
<p>테라폼으로 실제로 생성할 인프라 자원을 의미함.</p>
<pre><code># main.tf , vpc.tf 등 원하는 형태로 파일 이름 사용함.
# 테라폼으로 VPC 생성하는 코드
resource &quot;aws_vpc&quot; &lt;- ㄹㅇ 리소스 이름, 타입이라 생각하면됨 &quot;example&quot; &lt;- 이름{
    cidr_block = &quot;10.0.0.0/16&quot; &lt;- 여기서부턴 파라미터들..
}</code></pre><h2 id="state">State</h2>
<p>테라폼을 통해 생성한 자원의 상태 (파일 형태로 최종적으로 실행하는 파일)</p>
<pre><code># 생성한 리소스의 결과값이지, 현재 작동하는 인프라의 실제 상태는 아님
# state 상태 = 현재 인프라로 sync 를 맞춰주는게 데브옵스의 역할임
{
    &quot;version&quot; :4,
    ....
}</code></pre><h2 id="output">Output</h2>
<p>테라폼으로 만든 자원을 변수 형태로 state에 저장하는 것</p>
<pre><code>resource &quot;aws_vpc&quot; &quot;example&quot;{
    cidr_block = &quot;10.0.0.0/16&quot; &lt;- 여기서부턴 파라미터들..
}
# aws_vpc 를 만들면 vpcId , cidr 값이 생기는데 이걸 저장하는 변수 느낌.
# 리소스 값을 변수로 state를 만드는것. 나중에 리모트로 이걸 참조해서 사용가능.
ouput &quot;vpc_id&quot; {
    value = vpcId
}

ouput &quot;cidr&quot; {
    value = vpcId
}</code></pre><h2 id="module">Module</h2>
<p>공통적으로 사용하는 코드를 문자 그대로 모듈 형태로 정의한것. 재사용성이 아주 높아서 자주 씀.(공통 함수로 뺀st)</p>
<h2 id="remote">Remote</h2>
<p>다른 경로의 state를 참조하는것. output 변수를 불러올때 사용한다. 원격 참조 개념 (import)</p>
<h1 id="기본-명령어">기본 명령어</h1>
<ul>
<li>init : 각종 설정 진행</li>
<li>plan : 예측결과 보여줌</li>
<li>apply : 실제 인프라 생성</li>
<li>import : 만들어진 resource를 state 파일로 옮겨줌.</li>
<li>state : state를 다루는 명령어</li>
<li>destroy : state 파일 삭제</li>
</ul>
<blockquote>
<p>init (내부 설정 진행) -&gt; plan(흡사 컴파일?백퍼는 아님) -&gt; apply(ㄹㅇ 적용)
🙋 이것만 알면 되나요?
🤖 ㅇㅇ 이게 90퍼임</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DevOps] Helm 차트란??]]></title>
            <link>https://velog.io/@j_user0719/DevOps-Helm-%EC%B0%A8%ED%8A%B8%EB%9E%80</link>
            <guid>https://velog.io/@j_user0719/DevOps-Helm-%EC%B0%A8%ED%8A%B8%EB%9E%80</guid>
            <pubDate>Sun, 05 Feb 2023 07:49:54 GMT</pubDate>
            <description><![CDATA[<p>쿠버네티스는 container orchestration 으로 컨테이너를 쉽고 빠르게 배포,관리 해주는 툴이다. 쿠버네티스는 컨테이너화된 어플리케이션을 쉽게 배포할 수 있다.</p>
<p>이런 쿠버네티스를 활용하기 위해서는 가장 먼저 yaml 파일을 작성해야한다. 쿠버네티스에 오브젝트를 정의하고 생성할때 yaml 파일 형식을 활용하기 때문이다. 
쿠버네티스를 통해 어플리케이션을 배포하기 위해서는 많은 오브젝트가 필요한데, 대표적으로 deployment, pod, configmap, secret, service, persistent volume, persistent volume claim 등이 있다.</p>
<p>위와 같은 리소르를 다루는데 활용된느 yaml 파일을 관리하는 것은 매우 반복적이고 지루한 작업이다. </p>
<p>어플리케이션을 배포하다 보면 비슷한 틀과 내용을 공유하고, configuration만 일부 변경하면 되는데, 어플리케이션마다 모두 yaml 파일을 만들어줘야 하다보니 매우 번거롭다.</p>
<p>하지만 개발자는 항상 불편함을 개선하는 사람들...이를 편하게 만든 것이 <code>helm</code>이다.<code>helm</code>은 쿠버네티스에서 어플리케이션을 쉽게 배포하기 위해 사용되는 대표적인 패키징 툴이다. </p>
<p><code>helm</code>을 이용하면 어플리케이션을 쿠버네티스에 쉽게 설치할 수 있고 <code>helm-chart</code> 는 쿠버네티스의 리소스를 하나로 묶은 패키지에 해당한다( 이것도 yaml ). 
<code>helm</code>으로 차트를 관리하는 목적은 여러개의 yaml 파일을 쉽게 관리하기 위해서 이다. </p>
<p>그렇다면 본격적으로 <code>helm</code>,<code>helm chart</code>에 대해 알아보자</p>
<h1 id="helm-helm-chart-란-무엇인가">helm, helm-chart 란 무엇인가??</h1>
<p><code>helm</code> 은 쿠버네티스의 패키지 매니저다. 여기서 패키지는 쿠버네티스 리소스를 하나로 묶은 <code>helm chart</code>를 의미한다.</p>
<blockquote>
<p>🙋 패키지 매니저가 뭔데?
🤖 Mac의 brew, Node의 npm 같은거.</p>
</blockquote>
<p>그리고 <code>helm chard</code>는 yaml 파일의 묶음으로 이 묶음을 public or private registry에 push 해두고 <code>helm</code> 명령어를 활용해 <code>helm chart</code> 를 설치하여 쿠버네티스 리소스를 배포할 수 있다.</p>
<blockquote>
<p>🙋 아까 리소스 말해줬는데, 그게 각각 다 뭔데??
🤖 </p>
</blockquote>
<ul>
<li>service : pod를 외부 IP에 노출 시키기 위해</li>
<li>deployment : pod를 관리하기 위해</li>
<li>statefulset: database와 같은 어플리케이션을 위해</li>
<li>configMap : external config 설정을 위해</li>
<li>secret : credential 같은 secret 정보를 저장하기 위해</li>
</ul>
<p>원래는 이런 오브젝트를 생성하기 위해서는 각각의 yaml을 생성해줘야한다. 그리고 위와같은 yaml을 사전에 정의해두고 패키징 한 뒤, 쿠버네티스 클러스터에 어플리케이션을 배포할때 위와같은 오브젝트를 쉽게 배포하기 위해 패키징한게 <code>helm chart</code> 다.</p>
<p>정리하자면, <code>helm chart</code>  는 쿠버네티스 리소스를 정의해둔 yaml 파일의 묶음(패키지)이다. <code>helm</code>는 이런 패키지를 쉽게 관리할 수 있는 툴이다.</p>
<h1 id="helm의-기능은-어떤게-있나">helm의 기능은 어떤게 있나?</h1>
<h2 id="template-engine">template engine</h2>
<p>여러개의 ms를 개발한다고 가정하면, 이를 배포하는데 사용하는 yaml 파일은 거의 똑같은 구조로 작성돼 리소스를 정의하고 있을 것이다.</p>
<p>만약 helm이 없다면, 각 ms 마다 필요한 오브젝트에 대한 yaml을 개별로 관리해야한다. 하지만 <code>helm</code> 을 사용하면 공통적인 yaml 구조로 <code>helm chart</code> 를 만들고, 그 구조에서 value 만 수정해다며 ms 배포할 때 재사용 할 수 있다!!</p>
<p>이를 <code>value injection</code>이라고 하는데, values.yaml 파일을 만들어 템플릿에 override 하는 방법도 있고, helm 으로 실행할 때 set flag를 cli와 함께 사용할 수 있다.</p>
<blockquote>
<p>yaml 사용하는 경우
<code>helm i -f values.yaml -f override.yaml myredis ./redis</code>
--set flag 사용시
<code>helm i --set name=prod myredis ./redis</code></p>
</blockquote>
<h2 id="하나의-차트-여러-환경">하나의 차트, 여러 환경</h2>
<p>ms를 구현해두고 각각 다른 환경에 배포하는 경우 하나의 <code>helm chart</code> 를 작성하면 여러 환경에 배포할 수 있다.</p>
<h2 id="release-management--tiller">release management , Tiller</h2>
<p>helm 버전 2,3 의 가장 큰 차이점은 Tiller가 삭제된 것이다. 갑자기?? 싶겠지만 release management를 다루기 위해서임을 이해해달라.. 먼저 Tiller는 <code>helm chart</code> 를 통합 관리와 설치를 위해 활용되는 특별한 pod다. Tiller는 기존에 설치한 Chart를 통합 관리하고 이에 따라 아래와 같은 release management 기능을 Tiller를 통해 실행할 수 있도록 해준다.</p>
<p><code>helm history {RELEASE NAME} -n {NAMESPACE NAME}</code>
을 통해 배포돼왔던 release들의 history를 확인한 뒤,
<code>helm rollback {RELEASE NAME} {REVISTION NUMBER}</code>
을 통해 이전의 버전으로 rollback 할 수 있다.</p>
<p>또한 <code>helm upgrade</code>를 통해 helm 차트 변동사항을 release에 적용할 수 있다.
<code>helm upgrade {RELEASE NAME} &lt;차트경로&gt; -n {NAMESPACE NAME}</code></p>
<p>하지만 버전2의 Tiller를 사용하는 방식은 쿠버 1.6부터 적용된 RBAC를 위해 Tiller에 cluster-admin 을 부여하며 너무 많은 권한을 Tiller가 가져서 보안문제가 발생하게 됐다. </p>
<blockquote>
<p>🙋 RBAC 권한이 뭡니까?
🤖 사용자에게 리소스에 대한 액세스 권한 부여 여부를 결정하기 위해 역할과 권한을 정의하는 액세스 제어 메커니즘</p>
</blockquote>
<p>이런 문제를 방지하기 위해 Tiller가 아닌 쿠버네티스 API를 통해 설치된 <code>helm chart</code>들을 쿠버네티스 그 자체에 저장하게 된다.</p>
<p>또한 chart를 설치하는 RBAC 권한은 사용자가 사용한 kubeconfig 를 활용하는 방식으로 수정됐다. 따라서 좀더 직관적으로 변했고 Cluster관리자들은 release가 클러스터에 기록 되는 동안 유저의 접근 권한을 제어할 수 있고 나버지 Helm기능은 전과 같이 사용 하면서 prod 환경에서 더 안심하고 Helm 을 사용할 수 있게 된다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DB] Serializability 와 Recoverable]]></title>
            <link>https://velog.io/@j_user0719/DB-Serializability-%EC%99%80-Recoverable</link>
            <guid>https://velog.io/@j_user0719/DB-Serializability-%EC%99%80-Recoverable</guid>
            <pubDate>Sun, 05 Feb 2023 06:37:38 GMT</pubDate>
            <description><![CDATA[<h1 id="intro">Intro</h1>
<p>이번에 다룰 개념인 Serializability 와 Recoverable 는 만약 트랜잭션을 동시에 실행할 경우, 이상 현상이 일어나지 않도록 하는 중요한 특성이다. 트랜잭션을 말할때 꼭 알아야 하는 내용이므로 한번 정리해보자! </p>
<h1 id="serializability">Serializability</h1>
<p>DBMS는 여러 사용자의 요청을 동시에 수행하는 것이 필수적이다. 하지만 동시에 일어나는 경우 트랜잭션간의 간섭을 없애고 데이터 정합성을 일관성있게 제공해야만한다. 이를 <strong>Isolation</strong> 을 보장한다고 흔히 표현하는데, 이를 다른말로 하면 <strong>Serializability</strong>가 보장된다고 표현할 수 있다. Serializability는 한국말로 직역하면 직렬화를 의미하는데, 말 그대로 동시에 온 트랜잭션 요청을 순차적인 <strong>직렬화</strong>를 시켜 트랜잭션간의 간섭을 없애고 데이터간의 정합성을 맞추는 것을 의미한다.</p>
<blockquote>
<p>🙋 아니 그래서 그걸 어케 하냐고요
🤖 삐빅..이제부터 알아BOZA</p>
</blockquote>
<h2 id="schedule">Schedule</h2>
<p>Schedule은 다수의 트랜잭션이 동시에 실행될 때 그 트랜잭션들에 속한 operation들의 실행 순서를 의미한다. 예를 들어 T1,T2,T3가 동시에 실행된다면(여기서 동시는 정말 동시를 의미한다.), 내부의 operation이 겹쳐서 실행될 때 어떻게 실행되냐에 따라 실행결과가 다르게 나타날 수 있기때문에 DBMS는 Schedule을 <code>serial schedule</code> , <code>non-serial schedule</code> 로 구분한다.</p>
<h3 id="non-serial-schedule">non-serial schedule</h3>
<p>Interleave 실행기법을 통해 트랜잭션 내부 연산이 번갈아가면서 병렬로 실행되는 스케줄 기법을 의미한다. </p>
<blockquote>
<p>🙋 아니 인터리브가 뭡니까?
🤖 서로 다른 memory bank에 번갈아 가며 가용성을 높이는 메모리 기법입니당.
🙋 아니...좀 쉽게 설명해봐 이 깡통아
🤖 ... 10명이 화장실 1개를 쓰면 어떡함? 1명 들어가면 화장실 못쓰지? 그니까 화장실을 늘려서 번갈아가게 들어가면 1개의 화장실을 써도 다음 사람이 다른 화장실 들어가면 되니까 가용성이 높아지자너
👍</p>
</blockquote>
<p>이 방법은 병렬적으로 처리하기 때문에 동시성이 높아지는 장점이 있다. 즉 다른 트랜잭션이 I/O 작업 등 시간이 소요되는 작업을 하는동안 다른 작업을 수행할 수 있다. 하지만, 단점은 <code>Serializability</code> 를 보장하지 않기 때문에 순서가 바뀜으로서 의도치않은 결과값이 나올 수 있다.</p>
<h3 id="serial-schedule">serial schedule</h3>
<p>여러 트랜잭션이 들어와도 각 트랜잭션별로 구분해서 겹치지않도록 하고, 한 트랜잭션이 모두 실행되면 다른 트랜잭션을 실행하는 기법이다.</p>
<blockquote>
<p>🤖 화장실이 하나란 뜻 ㅎ..</p>
</blockquote>
<p>이 기법의 장점은 명확하다. 순서를 완벽하게 보장할 수있다는 점이다. 반면에 단점도 명확하다. 바로 성능이다. 예를들어 operation이 디스크 I/O가 필요하다면, 끝날 때까지 다른 트랜잭션을 실행할 수 없기 때문에 모든 트랜잭션들이 CPU보다 훨 느린 I/O가 끝날때 까지 기다려야한다.. (그래서 현실적으로 잘 안씀.)</p>
<blockquote>
<p>🤬 아니 둘다 치명적인 약점이 있는데, 그러면 뭘 쓰라는거에요?!
🤖 그래서 나온게 있죵.</p>
</blockquote>
<h3 id="⭐️-serializability-scedule">⭐️ Serializability scedule</h3>
<p>위의 두가지 방법은 서로 매우 치명적인 trade-off가 있다. 그래서 이를 해결하기 위한 기법으로, 성능 개선을 위해 <code>non-serial schedule</code>를 사용하면서도 <code>serial schedule</code> 과 동일한 결과가 나올 수 있도록한다. 이를 <code>conflict serializable</code> 이라고도 하고 <code>serial schedule</code> 과 <code>conflict equivalent</code> 하다고 표현한다.</p>
<blockquote>
<p>🙋 conflict 가 뭔데 이놈아
🤖 후.. 자세히 설명해줌.</p>
</blockquote>
<h4 id="conflict">Conflict</h4>
<p>두개의 operation이 충돌하는 것을 의미한다. 여기서 충돌은 아래 세가지 조건을 충족하면 충돌이라고 한다.</p>
<ol>
<li>operation이 서로 다른 트랜잭션에 속하는 경우</li>
<li>operation이 같은 데이터에 작업하는 경우</li>
<li>둘 중 하나의 operation이 쓰기 작업하는 경우</li>
</ol>
<blockquote>
<p>🙋 전혀 이해를 못하겠는데요?
🤖 예를 들어보자.. 아래와 같은 경우를 의미해</p>
</blockquote>
<ol>
<li>R1(A), W2(B) = read는 A에 대한 작업, write는 B에 대한 작업</li>
<li>R1(A), W2(A) = read는 A에 대한 작업, write는 A에 대한 작업 </li>
<li>W1(A), W2(A) = write는 A에 대한 작업, write는 A에 대한 작업
🙋 아니 그런데 이게 뭐가 문제냐니까??
🤖 두 개의 트랜잭션이 동시에 처리될때 이 경우는 실행 순서가 바뀌면 서로 실행결과가 바뀌니까..
👍</li>
</ol>
<h4 id="conflict-equivalent">Conflict equivalent</h4>
<p>이 의미는 아래의 두 조건을 충족할 경우를 의미한다.</p>
<ol>
<li>같은 트랜잭션들의 operation 들로 구성된 schedule</li>
<li>양쪽 트랜잭션 내의 conflicting operation의 실행순서가 동일</li>
</ol>
<blockquote>
<p>🙋 알지?뭔말할지?
🤖 ... 예를 들어보자 아래의 두 스캐줄이 있을 경우
S1: R1(A), W1(A), R2(A), W2(A), R1(B), W1(B), R2(B), W2(B)
S2: R1(A), W1(A), R1(B), W2(B), R2(A), W1(A), R2(B), W2(B)
<br/>
S1의 경우, conflict 가 일어날 데이터 순서는 아래와 같다.</p>
</blockquote>
<ul>
<li>R1(A) -&gt; W2(A)</li>
<li>W1(A) -&gt; R2(A)</li>
<li>W1(A) -&gt; W2(A)</li>
<li>R1(B) -&gt; W2(B)</li>
<li>W1(B) -&gt; R2(B)</li>
<li>W1(B) -&gt; W2(B)<br/>
R2(A), R1(B)의 순서만 바뀌었고, conflict operation의 순서는 그대로기 때문에 Conflict equivalent 이라 표현한다.
🙋 ... 예시가 더 어려운데요?? 한줄 요약해줘
🤖 ... conflict 가 일어날 거 같은 실행은 순서 고정해둔단거여...


</li>
</ul>
<h1 id="recoverability">Recoverability</h1>
<p>Recoverability 는 트랜잭션이 실패했을 때의 회복 가능성을 의미한다. 트랜잭션은 하드웨어 이슈, 시스템 충돌, 소프트웨어 이슈등 다양한 이유로 중간에 실패할 수 있는데, 이때도 트랜잭션은 atomicity가 보장 돼야 하기 때문에 트랜잭션이 실패하면 트랜잭션 이전 상태로 복원될 수 있어야한다. 흔히 Rollback이라고 표현하는데, </p>
<p>Recoverability은 한마디로 Rollback 에 이상현상 없는가? 를 의미한다. DBMS는 스케줄이 recoverable 하도록 보장해야하며 recoverable한 스케줄이 무엇인지 알아보자</p>
<h2 id="irrecoverable-schedule">irrecoverable schedule</h2>
<p>irrecoverable schedule 이란 롤백해도 이전 상태로 회복 불가능한 스케줄을 의미한다. 이러한 스케줄은 DBMS에서 허용하면 안되기 때문에 어떤 경우에 스케줄이 irrecoverable 한지 보자</p>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/d071091d-c762-46ee-aa7e-8dec75c05042/image.png" alt=""></p>
<p>Dirty read는 위와 같이 T1의 트랜잭션이 작업이 다 끝나지 않았지만, T2에서 트랜잭션에서 작업 내용을 보는 경우를 의미한다. 위의 예시를 보면, T1이 중간에 실패해 롤백을 하게 되면 T2는 유효하지 않은 데이터를 읽고 고친 후 commit 까지 진행한 상태라 Dirty Data를 가진 상태로 롤백하지 못하는 경우를 irrecoverable schedule라고 표현한다.</p>
<blockquote>
<p>🙋 그러면 dirty read 만 안하면 되는건가요?
🤖 그러면 트랜잭션 하나만 하는거랑 다를바 없음..</p>
</blockquote>
<h2 id="recoverable-schedule">recoverable schedule</h2>
<p>recoverable schedule 이란 트랜잭션은 자신이 읽고있는 데이터를 변경하고 있는 다른 트랜잭션들이 모두 커밋, 롤백 되기 전까지 커밋하지 않는 스케줄을 의미한다. </p>
<p>예를 들어 T1이 T2가 변경하고 쓴 값을 읽는다면 T2가 커밋된 후에나 T1이 커밋되는 경우를 의미한다. 만약 T1 -&gt; T2 -&gt; T3 -&gt; T4 의 데이터를 사용하고 있다면, T4가 커밋 혹은 롤백 되기 전까지 이전 트랜잭션들이 기다리는 것을 의미한다.</p>
<blockquote>
<p>🙋 아니 근데 커밋되는거야 뭐 그렇다고 쳐도 rollback 하면 너무 비용이 큰데..?
🤖 아주 좋은 지적. 그걸 <strong>cascading rollback</strong>이라고 하고 이를 방지하기 위해 <strong>cascadeless schedule</strong> 이라고 한다.</p>
</blockquote>
<h3 id="cascadeless-schedule">cascadeless schedule</h3>
<p>cascadeless schedule은 데이터를 W 한 트랜잭션이 커밋 혹은 롤백된 뒤에만 데이터를 읽을 수 있는 스케줄을 의미한다.</p>
<h3 id="strict-scedule">strict scedule</h3>
<p>하지만 cascadeless schedule 은 read를 하지 않는 스케줄이고 write까지 막지는 않는다. 만약</p>
<blockquote>
<p>W1(A) -&gt; W2(A) -&gt; W2 Commit -&gt; W1 rollback</p>
</blockquote>
<p>같은 순서라면, W1이 롤백하면서 W1이 발생하기 전의 데이터로 복구 되면서 W2가 커밋한 데이터가 사라지는 경우가 발생할 수 있다. 하지만 위 스케줄은 read자체가 없기 때문에 cascadeless 하다고 볼 수 있다. 
여기에 추가적으로 보강해 읽지도 않을 뿐, 쓰지도 못하게 하는 경우를 strict scedule 라고 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DB] 트랜잭션이란?]]></title>
            <link>https://velog.io/@j_user0719/DB-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@j_user0719/DB-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Sun, 15 Jan 2023 06:56:45 GMT</pubDate>
            <description><![CDATA[<h1 id="intro">Intro</h1>
<p>현업에서 실무를 진행하며, 필연적으로 DB에 접근하는 무수하고 복잡한 쿼리를 접하게 되었다. 실력있는 백엔드 개발자라면 DB 접근을 얼마나 효율적이고 &quot;잘&quot; 다루는지에 따라 나뉜다고 해도 과언이 아니다. 왜냐하면 DB 접근을 이전보다 10% 빠르고 효율적으로 수정했다면 곧 서버의 운영비용을 절감 시키는 <strong>비용</strong> 의 절감으로 이어지기 때문이다.</p>
<p>이전의 프로젝트는 소규모 였기 떄문에 <strong>트랜잭션</strong>에 대한 큰 이해가 없어도 장애없는 DB를 사용할 수 있었지만..(ex <code>REPEATABE READ</code>, <code>SERIALIZABLE</code>..) 점점 이러한 지식의 부족을 인지하고 있었고, 다소 여유가 생긴 지금 트랜잭션에 대해 정리해보려고 한다! 목표는 <strong>어딜가서 누가 물어보면 아주 확신을 가지고 말할 수 있도록!!!</strong> 아마 몇편에 나눠서 포스팅을 진행할 것 같다!!</p>
<h1 id="트랜잭션이란">트랜잭션이란??</h1>
<p>트랜잭션은 DBMS가 DB를 다룰 때 사용하는 논리적인 작업 단위다. 이때 논리적 단위는 하나의 작은 작업의 묶음 덩어리다.</p>
<blockquote>
<p>🙋 벌써 어려운데 하차해도 됩니까? 한줄 요약 부탁드려요.
🤖 ALL or NOTHING
🙋 너무 줄이면 어쩌자는 겁니까;;; 그게 뭡니까?</p>
</blockquote>
<p>간단한 예시를 들자면, 만약 당신이 친구에게 100만원을 입금 한다고 가정하자. 그런데 어라? 에러가 발생했다. 여기서 친구에게 송금될 금액은?</p>
<ol>
<li>100만원</li>
<li>일부</li>
<li>0원</li>
</ol>
<blockquote>
<p>🙋 이게 문제야? 0 원이지 에러났으면 입금되면 안되지!!!
🤖 정답.</p>
</blockquote>
<p>그렇다면 반대로 만약 입금했을 때, 성공적으로 입금이 완료 되었다. 이때 입금된 금액은?</p>
<ol>
<li>100만원</li>
<li>일부</li>
<li>0원</li>
</ol>
<blockquote>
<p>🙋 장난? 당연히 다 입금 돼야지!
🤖 정답.</p>
</blockquote>
<p>은행에 입금하는 것은 다양한 로직을 거쳐 DB에 접근하는 것을 의미한다. 그렇기 때문에 정말 단 하나라도 이상이 생기면 모든 작업이 수행되지 않는다. 그래서 트랜잭션은 모두 실행되거나 모두 실행하지 않거나. <code>ALL or NOTHING</code>을 기억하자.</p>
<blockquote>
<p>🙋 근데 ALL or NOTHING 처리를 어케 하는데?
🤖 완료시 Commit, 실패시 Rallback
🙋 그럼 그건 어떻게 작동하는데?
🤖 좀 이따 알려줌 ㅎ</p>
</blockquote>
<p>트랜잭션은 크게 4가지 일을 하는데 <code>CREATE , UPDATE , DELETE , SELECT</code> 이다. 이중에 <code>SELECT</code> 는 조금 특별한데, 읽고 있는 데이터가 중간에 수정될 수 있기 때문이다. 그래서 이를 방지하기 위해 트랙잰션의 <code>isolation level</code> 을 설정해 사용하는 것을 잊지말자!</p>
<blockquote>
<p>🙋 아니 근데 그냥 순차적으로 해버리면 중간에 수정되는 걸 방지할 수 있자너?
🤖 병렬 처리를 하지 않으면 데이터 부정합을 해결할 수 있지만 요청이 많아지면 처리가 어렵기때문에 쩔 수 없음.</p>
</blockquote>
<h2 id="트랜잭션의-생명주기">트랜잭션의 생명주기</h2>
<p>위에서 말한것 처럼 완료시 Commit이 실패시 Rollback이 진행된다. 그럼 자연스럽게 </p>
<blockquote>
<p>🙋 그래서 아직 실패인지, 성공인지 모르는 상태의 트랜잭션은 어케 처리하는데?</p>
</blockquote>
<p>라는 질문이 나올 수 있다. 그래서 트랜잭션의 생명주기를 나열하자면,</p>
<ol>
<li><code>Active States</code> : 트랜잭션이 실행되고 있는 상태</li>
<li><code>Partially Committed</code>: 트랜잭션이 실행되면서 데이터 변경사항을 DB에 적용 전 메모리 공간에만 변경해놓은 상태</li>
</ol>
<p>3-1. <code>Commited</code> : 실제로 메모리에서 DB에 데이터를 쓴 상태. (Rollback 불가)
3-2. <code>Failed</code> : 에러로 트랜잭션이 취소된 상태</p>
<ol start="4">
<li><code>Terminated State</code> : 트랜잭션이 성공해 영구 반영되거나 실패해서 롤백된 후 실질적으로 트랜잭션의 종료인 상태.</li>
</ol>
<h1 id="트랜잭션의-특성--acid">트랜잭션의 특성 : ACID</h1>
<p>전공자면 전공 수업에서도, 정보처리기사 시험에서도 주구장창 나오는 말이었지만 정작 자세히 알진 못했다. ACID는 트랜잭션하면 꼭 알아야할 특성이다. 이상적으로는 모든 트랜잭션은 이 특성을 만족해야하지만... 현실적으로 완벽히 지켜지기란 아주 쉽지않다.. 왜냐면 모두 엄격히 지켜버리면 DB의 성능을 포기해야하기 때문이다. 자세히는 왜인지 하나씩 뜯어보며 알아보자!</p>
<h2 id="atomicty-원자성">Atomicty (원자성)</h2>
<p>원자성은 앞에서 말했던 <code>ALL or NOTHING</code> 을 의미한다. 트랜잭션 내의 모든 작업이 모두 반영되거나, 전혀 반영되지 않아야한다는 것이다. 즉, 커밋 이전에는 디스크에 쓰지 않고 메모리 버퍼에만 저장해 두었다가 중간에 실패하면 디스크에 반영하지 않는 방식으로 원자성을 보장한다.</p>
<h2 id="consistency-일관성">Consistency (일관성)</h2>
<p>일관성은 모든 트랜잭션이 정해진 규칙을 어기지 않고 오류가 없는 일관적인 상태임을 의미한다. 예를 들어 한도가 100만원인데, 트랜잭션 중 100만원 이상의 금액을 송금하는 작업은 할 수 없다던지, 문자열이 들어온다던지 등..당연히 지켜야할 규칙을 일관적으로 지킴을 의미한다. (다소 당연한 것...)</p>
<h2 id="isolation-격리성">Isolation (격리성)</h2>
<p>격리성은 하나의 트랜잭션을 수행할 때 다른 트랜잭션이 접근할 수 없음을 의미한다. 즉 <strong>모든 트랜잭션은 다른 트랜잭션으로부터 독립되어야 한다</strong>.</p>
<blockquote>
<p>🙋 아니 그럼 동시 처리 못하는거랑 다름이 없잖아?? 다른 사람 하는거 기다려야해???
🤖 ㄴㄴ 1,2,3,4 모두 같이 요청해도 마치 1 -&gt; 2 -&gt; 3 -&gt; 4 처럼 수행하듯이 만들어야 한다는것. 이게 <code>Serializability</code> 다.
🤖 이건 내용이 많아 나중에 따로 다룰게</p>
</blockquote>
<h2 id="durability-지속성">Durability (지속성)</h2>
<p>지속성도 너무 당연한 이야기다. 커밋 되었다면 영원히 지속 되어야한다는 특성이다.</p>
<blockquote>
<p>🙋 아니 너무 당연한걸 왜 넣었는데?
🤖 영원히 지속 = 성공 로그를 남김 = 문제 생기면 복구 가능</p>
</blockquote>
<p>단순하지만 꼭 필요한 특성이다. DBMS가 이 지속성을 위해서 종류마다 다르게 동작하고 격리성도 마찬가지로 조금씩 다르다. 그래서 모든 DBMS가 같지않고 어떤 DBMS를 사용하는지에 따라 맞춰 공부할 필요가 있다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JWT 사용시 주의사항]]></title>
            <link>https://velog.io/@j_user0719/JWT-%EC%82%AC%EC%9A%A9%EC%8B%9C-%EC%A3%BC%EC%9D%98%EC%82%AC%ED%95%AD</link>
            <guid>https://velog.io/@j_user0719/JWT-%EC%82%AC%EC%9A%A9%EC%8B%9C-%EC%A3%BC%EC%9D%98%EC%82%AC%ED%95%AD</guid>
            <pubDate>Mon, 02 Jan 2023 07:50:57 GMT</pubDate>
            <description><![CDATA[<h1 id="intro">Intro</h1>
<p>흔히 사용자 인가 기능을 구현할때 크게 두가지 방법을 사용하는데, 바로 Session과 JWT 방식이다.</p>
<p>백엔드를 잘 접하지 않아도 jwt가 session 방식보다 많이 쓴다는것을 알것이다. 그렇다면 jwt는 무적인가? jwt를 클론코딩과 똑같이하거나, 단순 복붙을 한다면 사용자 정보와 관련된 문제이므로 장차 큰 문제로 이어질 수 있다.</p>
<p>그래서 jwt를 사용할때 주의할 점을 정리해보았다.</p>
<h1 id="상상해보자">상상해보자</h1>
<p>서울에 새롭게 J 놀이동산이 개장하였다. 이 놀이동산에 들어오기 위해서는 사용자는 입장권을 사야하고, 놀이동산 내에서 놀이기구를 탈때도 역시 직원이 사용자의 입장권을 확인하고 사용을 할 수 있다.
session 방식이든, jwt 방식이든 기본적인 원리는 입장권 형식으로 유사하다. 그러나 차이점은 그 <strong>입장권에 적혀있는 정보</strong> 이다.</p>
<h1 id="session-방식">Session 방식</h1>
<p>session 방식은 입장권에 많은 정보가 있지않다. 발급 번호 딱 한줄이 있다.</p>
<blockquote>
<p>그럼 어케 구분하는데???</p>
</blockquote>
<p>입장권을 직원에게 제시하면, 직원은 입장권 발급 목록 같은 장부를 확인하여 이 사용자가 올바른 사용자인지 확인을 하게 된다.</p>
<blockquote>
<p>여기서 장부를 session storage 이라고 한다.</p>
</blockquote>
<h1 id="jwt-방식">JWT 방식</h1>
<p>jwt 방식은 입장권에 적혀있는 정보가 제법 많이 있다.  유저의 발급일, 유효기간 등등... 그래서 직원은 입장권 하나만 보고 유효한지 안한지 판단을 하고 인가를 내려주게 된다.</p>
<blockquote>
<p>아니 그럼 JWT가 무조건 좋아보이는데?? </p>
</blockquote>
<p>이게 JWT의 장점입니다. 사용자가 1억명이면 왜인지 확실하게 상상할 수 있을것이다.
그렇다면 JWT가 어떻게 생겼는지 맛만 보자</p>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/50b70bb2-7890-4251-903f-907276936fbc/image.png" alt=""></p>
<p>헤더에 기본 세팅값을 적어주고, Payload에 입장권에 적을 정보를 입력해주면 정보를 문자열로 암호화 하게 된다. 그리고 secret 값을 추가로 설정해주면 전혀다른 문자열 값을 얻을 수 있다. 그래서 위조 여부도 쉽게 알 수 있다.</p>
<h1 id="jwt-주의사항">JWT 주의사항</h1>
<p>JWT를 많이 사용하며 대게 많은 백엔드 클론 코딩에서도 이를 사용하고 있는데, JWT도 문제점이 많기 때문에 이를 꼭 인지하고 사용했으면 좋겠다.</p>
<ol>
<li><p>alg : none 
none으로 알고리즘란을 적고 jwt를 만들어서 서버로 보내는 악성 유저가 있다. 왜 이런짓을 하냐면, 가끔 어떤 사이트들은 alg 가 none일 경우 인가를 해주는 경우가 있기 때문이다. 그래서 alg : none일 경우 이를 막아주는지 확인을 해야한다. 그러나 최근 라이브러리들은 이런 걱정 필요없다.</p>
</li>
<li><p>JWT Decoding
JWT는 decoding이 쉬운 편이다. 그래서 JWT에 사용자의 민감한 정보를 많이 넣는것은 주의하고 최소한의 정보만을 넣어야한다.</p>
</li>
<li><p>시크릿키 문제
JWT를 구현하게 될때 시크릿키를 개발자가 지정할 수 있는데, 이 시크릿키를 대충 구현하는 개발자들이 많다. 매우 짧은 문자를 적는 경우도 있고, 특히 클론 코딩이나, 코드를 붙여오는 경우도 그렇다. 대충 적으면 때려맞추기가 아주 쉬워서 Brute force 공격이 이 허점을 이용하기도 하고 유명한 블로거, 유튜버에서 만든 시크릿키를 그대로 넣어서 공격하기도 하니 주의하도록 하자..</p>
</li>
</ol>
<blockquote>
<p>아니 주의만 주지말고 그럼 어떻게 하라는건데??</p>
</blockquote>
<p>일단.. 1) 키를 매우 길게 설정한다. 2) 공유 금지 3) 생성용키/검증용키 2개 사용 (jwt 라이브러리에 있으니 적극 사용해보자!)</p>
<ol start="4">
<li>JWT 탈취
만약 누가 JWT를 탈취한 경우는 어떻게 될까?</li>
</ol>
<blockquote>
<p>놀이동산에 입장권 누가 훔쳐가면 누구탓? 카드 잃어버리면 누구탓? 물론 사용자 탓이지만... 개발자가 조치는 취해야함...</p>
</blockquote>
<p>카드사라면 사용 정지를 시킬 수 있지만, JWT는 발급한것을 다시 회수하거나 사용 정지시킬 수 없다. (주면 끝이기 때문에..) </p>
<blockquote>
<p>그럼 손 놓고 있냐?</p>
</blockquote>
<p>일단 1) 탈취하기 어렵게 만드는게 중요하다. 훔치기 힘든 저장소 (http only cookie) 에 jwt를 저장해둔다. 2) JWT 블랙리스트를 따로 운영하는 것이다. 그러면 사용 정지를 모방할 수 있다.</p>
<blockquote>
<p>??? 아니 그럼 블랙리스트가 커지면 session이랑 다를게 뭐냐???</p>
</blockquote>
<p>그래서 나온 솔루션이 3) JWT 유효기간을 짧게 설정한다. 유통기한을 매우 짧게 설정해서 조금더 안전해질 수 있다. </p>
<blockquote>
<p>그러면 사용자도 짧게 이용하잖아 ㅋㅋㅋㅋㅋ</p>
</blockquote>
<p>그래서 JWT를 재발급시켜주는 refesh token을 따로 운영하면 된다. </p>
<blockquote>
<p>refesh 토큰을 탈취하면??</p>
</blockquote>
<p>그래서 refesh token rotation이라고 하는 정책을 운영하는데, 탈취 당한 유저가 refesh 토큰을 재발급하거나, refesh 토큰을 재사용하게 된다면 refesh token rotation을 요구하게 되는데, 이게 없다면 토큰을 발행해주지 않는다. 그래서 refesh 토큰을 1회용으로 설정하면 조금 더 안전한 JWT 사용이 가능해진다. 당근 라이브러리가 잘 되어있어서 잘 찾아보고 쓰면 될듯하다.</p>
<p>별일 없으면 session 방식으로 하는게 간단하고 안전하다. 회원이 아주 많을거같으면 or 마이크로 서비스가 많으면 JWT 사용하는 것이 바람직하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SDK 개발에 대한 얕은 지식]]></title>
            <link>https://velog.io/@j_user0719/SDK-%EA%B0%9C%EB%B0%9C%EC%97%90-%EB%8C%80%ED%95%9C-%EC%96%95%EC%9D%80-%EC%A7%80%EC%8B%9D</link>
            <guid>https://velog.io/@j_user0719/SDK-%EA%B0%9C%EB%B0%9C%EC%97%90-%EB%8C%80%ED%95%9C-%EC%96%95%EC%9D%80-%EC%A7%80%EC%8B%9D</guid>
            <pubDate>Sat, 07 May 2022 06:56:11 GMT</pubDate>
            <description><![CDATA[<h1 id="sdk-란-무엇인가">SDK 란 무엇인가.</h1>
<p>sdk와 api에 대한 비교는 마치 수육을 먹기위해 마트에서 <strong>고기를 사는것</strong>과 <strong>수육용 밀키트</strong>를 사는것의 차이라고 할 수 있다. 
sdk는 밀키트 처럼 수육을 만들고자 한다면, 좀 더 상세하고 사용자가 수육을 만들기 쉽게 (소스, 조리 시간 등등..) 미리 준비해서 최대한 준비해주는 것이다. 그러나 api는 소스도 본인이 만들고 , 불의 강약도 스스로 조절하며 수육을 만들어야한다.</p>
<p>대충 감을 잡고 위의 예시를 개발자 언어로 바꾸자면... sdk는 소프트웨어 개발자 키트의 줄임말이고 같은 api 콜을 한다고해도 일반 api 콜과는 달리 에러 컨트롤, 로그 분석 등 백오프 기능을 포함해 사용자가 사용하기 편한 모든 정보와 기능의 <strong>꾸러미</strong>라고 할 수 있다.
일반적인 sdk는 관련 문서와 코드 및 구현(시나리오) 샘플, 사용자 가이드, 제한 사항 등등의 추가 제품이 포함되어있어야 한다.</p>
<h1 id="best-practices-in-sdk">Best Practices in SDK</h1>
<p>sdk든 api든 사용자가 실제로 사용할 수 있는 경우에만 가치가 있다. 바꿔 말하자면, 아무도 안먹는 음식을 제공하는 가게는 망하게 된다. 그렇다면 sdk 개발시 고려해야할 점들은 어떤게 있을까? </p>
<h2 id="simple">Simple</h2>
<p>당연하겠지만 지나치게 복잡한 코드, 방법론은 사용자를 방해해 sdk를 사용하는 이유인 <strong>효율성</strong>을 해쳐서는 안된다. 이를 위해서는 <strong>모든 단계에서 단순성</strong>을 보장해야한다.</p>
<blockquote>
<p>🙋‍♂️ 단순성을 보장하는게 무슨 뜻이냐?
🤖 일반적으로 클래스나 메서드의 우선 순위를 지정하는 것을 의미합니다.
🙋‍♂️ 그건 또 무슨 의미냐..?
🤖 실제로 사용할 수 없는 메서드나 기능으로 옵션을 난독화 하지 않고 사용자가 사용하는 기능만 표시할 수 있어야한다는 것을 의미합니다.
😡 그니까 그게 무슨 뜻이냐고
🤖 후...특정 기능을 수행하는데 필요한 매개변수만 사용해서 최대한 적은 수 의 매개변수를 사용한다고</p>
</blockquote>
<h2 id="usable">Usable</h2>
<p>사용자의 사용성을 높이기 위해 설계 뿐만아니라 문서로 허들을 낮출 필요가 있다.</p>
<blockquote>
<p>🙋‍♂️ 그걸 어떻게 낮추냐?
🤖 입문서, 예제를 통해 사용 가이드를 제공하면 코드 접근 방식의 복잡성과 특성을 소개하는데 큰 도움이 될 수 있음.
🙋‍♂️ 그 기준은 어떻게 측정하냐?
🤖 해당 코드베이스의 언어에 익숙하다고 가정하면, 사용자는 5-10분 내에 SDK를 사용할 수 있어야 함.</p>
</blockquote>
<h2 id="endpoints-correctly">Endpoints Correctly</h2>
<p>api와 마찬가지로 엔드포인트의 매핑을 정확히 해야 의도한 기능과 예상되는 응답이 무엇인지 명확하게 알 수 있다. 이는 곧 sdk가 지속적으로 업데이트 되는지를 의미합니다. 기능을 서비스 개발에 발 맞춰 진행하고 문서의 추가도 잊지 않아야한다. </p>
<p><a href="https://nordicapis.com/ultimate-guide-to-30-api-documentation-solutions/">자동 문서 추가</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Caver-js에 대한 얕은 지식.]]></title>
            <link>https://velog.io/@j_user0719/%ED%81%B4%EB%A0%88%EC%9D%B4%ED%8A%BC-%EB%AA%A8%EB%A5%B4%EB%8A%94-%EA%B2%83</link>
            <guid>https://velog.io/@j_user0719/%ED%81%B4%EB%A0%88%EC%9D%B4%ED%8A%BC-%EB%AA%A8%EB%A5%B4%EB%8A%94-%EA%B2%83</guid>
            <pubDate>Fri, 06 May 2022 07:09:58 GMT</pubDate>
            <description><![CDATA[<h1 id="계정">계정</h1>
<h2 id="계정키">계정키</h2>
<p>계정과 연결된 키 구조.</p>
<ol>
<li><p>AccountKeyNil : 공백 키를 나타냄.</p>
</li>
<li><p>AccountKeyLegacy : 키 쌍에서 파생된 주소를 가진 계정에 사용.</p>
<blockquote>
<p>키쌍에서 파생된지 어케아냐?</p>
<ul>
<li>공개키를 ecrecover(txhash, txsig)로 얻기.</li>
<li>주소는 발신자입니다..???</li>
</ul>
</blockquote>
</li>
<li><p>AccountKeyPublic : 하나의 공개 키를 가진 계정에 사용</p>
<blockquote>
<p>ecrecover(txhash, txsig) === 공개키?? 로 판별.</p>
</blockquote>
</li>
<li><p>AccountKeyFail : 트랜잭션 유효성 검증 프로세스는 항상 실패하게 됨.</p>
</li>
<li><p>AccountKeyWeightedMultiSig : threshold + WeightedPublicKeys( 공개키 + 가중치 + 리스트 )</p>
<blockquote>
<p>threshold : 서명시 공개키의 가중치보다 작아야함.
서명된 공개키 &lt; WeightedPublicKey 여야함.</p>
</blockquote>
</li>
<li><p>AccountKeyRoleBased : 역할마다 엑세스 범위를 나눈 역할 기반 키.</p>
<blockquote>
<p>RoleTransaction :  TxTypeAccountUpdate 이외
RoleAccountUpdate : TxTypeAccountUpdate 만
RoleFeePayer : FeePayer 트랙잭션시</p>
</blockquote>
</li>
</ol>
<h1 id="트랜잭션">트랜잭션</h1>
<h2 id="구성요소">구성요소</h2>
<p><img src="https://velog.velcdn.com/images/j_user0719/post/f69dfd47-6118-4a3f-83d6-5f0d04c37050/image.png" alt=""></p>
<blockquote>
<p>🙋‍♂️ 발신자가 동일한 논스를 가진 두 개의 트랜잭션을 생성하면 하나만 실행된다...? 논스를 설정할 수 있다고??</p>
</blockquote>
<h3 id="클레이튼에서의-트랜잭션-서명">클레이튼에서의 트랜잭션 서명</h3>
<p>기존 : 공개키 &lt;-&gt; 서명 (서로 파생)
클레이튼 : 공개키(키쌍) // 서명 =&gt; 서명에서 주체의 주소를 가져올 수 없음 =&gt; from(계정키)이 있는 이유. </p>
<h2 id="sendertxhash">SenderTxHash</h2>
<p>트랜잭션 수수료 납부자의 주소와 서명이 <strong>없는</strong> 트랜잭션의 해시</p>
<blockquote>
<p>🙋‍♂️ 서명없이 해시를 어케 만드냐?
🤖 납부자가 동의하는 서명을 하면 해시 생성됨.
🤖 약간 착불같은 느낌</p>
</blockquote>
<p>SenderTxHash를 얻기 위한 방법은 <strong>트랜잭션 유형</strong>에 따라 다름
<img src="https://velog.velcdn.com/images/j_user0719/post/17dc7291-d347-4dd3-9e71-3501a1233c05/image.png" alt=""></p>
<h3 id="트랜잭션-유형-종류">트랜잭션 유형 종류</h3>
<p>앞에 (TxType)은 생략하겠음..(<del>너무길어</del>)</p>
<ol>
<li><p><strong>LegacyTransaction</strong> : 이전에 Klaytn에 존재했던 트랜잭션 유형</p>
</li>
<li><p><strong>ValueTransfer</strong> : 사용자가 KLAY를 전송할 때 사용하는 유형</p>
</li>
<li><p><strong>ValueTransferMemo</strong> : 특정 메시지와 함께 KLAY를 보내려고 할 때 사용하는 유형</p>
</li>
<li><p><strong>SmartContractDeploy</strong> : 지정된 주소에 스마트 컨트랙트를 배포 할 때 사용하는 유형</p>
</li>
<li><p><strong>SmartContractExecution</strong> : to가 스마트 컨트랙트 계정일 때 스마트 컨트랙트를 실행하고, input에 입력된 데이터를 이용.</p>
</li>
<li><p><strong>AccountUpdate</strong> : 해당 계정의 키를 업데이트</p>
</li>
<li><p><strong>Cancel</strong> : 트랜잭션 풀에서 같은 논스를 가진 트랜잭션을 취소할 때 사용.</p>
</li>
<li><p><strong>ChainDataAnchoring</strong> : 서비스체인 데이터를 Klaytn 메인체인에 앵커링하는 트랜잭션 유형.</p>
</li>
</ol>
<h3 id="트랜잭션-비용-위임-종류">트랜잭션 비용 위임 종류</h3>
<ol>
<li><p><strong>FeeDelegatedValueTransfer</strong> : 사용자가 KLAY를 보내려고 할 때 사용</p>
</li>
<li><p><strong>FeeDelegatedValueTransferMemo</strong> : 메시지와 함께 Klay를 보내려고 할때 사용</p>
</li>
<li><p><strong>FeeDelegatedSmartContractDeploy</strong> : 수수료 위임하는 컨트랙트를 배포.</p>
</li>
<li><p><strong>FeeDelegatedSmartContractExecution</strong> : to가 스마트 컨트랙트 계정일 때 스마트 컨트랙트를 실행하고, input에 입력된 데이터를 이용. 트랜잭션 수수료는 지정된 수수료 납부자가 지불. </p>
</li>
<li><p><strong>FeeDelegatedAccountUpdate</strong> : 해당 계정의 키를 업데이트시 수수료 납부자가 지불.</p>
</li>
<li><p><strong>FeeDelegatedCancel</strong> : 같은 논스를 가진 트랜잭션을 취소시 수수료 납부자가 지불.</p>
</li>
<li><p><strong>FeeDelegatedChainDataAnchoring</strong> : 앵커링시 수수료를 납부자가 지불.</p>
</li>
</ol>
<h3 id="부분-비용-위임-종류">부분 비용 위임 종류</h3>
<p>트랜잭션 비용 위임 종류와 똑같지만 Ratio 기능의 추가로 일부는 납부자가, 일부는 본인이 지불하는 기능.</p>
<h1 id="caver-예시">Caver 예시</h1>
<h3 id="basic-keyring이란">Basic: keyring이란?</h3>
<p>Klaytn 계정의 주소와 개인 키를 포함하는 구조.</p>
<ul>
<li>SingleKeyring :하나의 주소와 하나의 개인 키를 저장</li>
<li>MultipleKeyring : 하나의 주소와 여러 개인 키를 저장</li>
<li>RoleBasedKeyring : 각 역할에 대해 하나의 주소와 하나 이상의 개인 키를 저장.</li>
</ul>
<blockquote>
<p>🙋‍♂️ 역할은 어떻게 표현하나요?
🤖 [[roleTransactionKey],[roleAccountUpdateKey],[FeePayerKey]]이런 이차원 배열로 표현.
🙋‍♂️ 역할은 뭐가 있나요?
🤖<img src="https://velog.velcdn.com/images/j_user0719/post/6c7f2c4f-03e3-48a8-a08c-6f2b93f3675c/image.png" alt="">
🙋‍♂️ 보니까 키링을 월렛에 추가해주는거 같은데 왜 그러나요?
🤖 월렛에 있어야지 그때그때 또 생성하는게 아니라 한번만 만들고 계속 쓰징</p>
</blockquote>
<h4 id="키링-생성방법">키링 생성방법</h4>
<ul>
<li>singleKey 생성</li>
<li>개인키로 SingleKeyring 생성</li>
<li>개인키와 계정 주소로 SingleKeyring 생성</li>
<li>여러 개인키로 MultipleKeyring 생성</li>
<li>개인키로 RoleBasedKeyring 생성</li>
</ul>
<h3 id="caver을-이용한-몇가지-예시">Caver을 이용한 몇가지 예시.</h3>
<h4 id="예시-트랜잭션-서명">예시) 트랜잭션 서명</h4>
<p>서명은 wallet을 통해 할 수 있고 트랜잭션을 보낼려면 2가지 단계를 거침.</p>
<ol>
<li><p>서명 (caver.wallet에 키링추가 or transction.sign )</p>
<ul>
<li><p>방법 1. 키링 월렛에 추가.</p>
<pre><code>// 키링 생성
const keyring = caver.wallet.keyring.createFromPrivateKey(&#39;0x{private key}&#39;)
caver.wallet.add(keyring)

// Create a value transfer transaction
const valueTransfer = caver.transaction.valueTransfer.create({
  from: keyring.address,
  to: &#39;0x176ff0344de49c04be577a3512b6991507647f72&#39;,
  value: 1,
  gas: 30000,
})
// 월렛에서 서명.
await caver.wallet.sign(keyring.address, valueTransfer)
// rlp로 만들어줌.
const rlpEncoded = valueTransfer.getRLPEncoding()
// 만든 rlp 전송.
const receipt = await caver.rpc.klay.sendRawTransaction(rlpEncoding)
console.log(receipt)</code></pre></li>
<li><p>방법 2. transction.sign() 사용</p>
<pre><code>// 키링 생성
const keyring = caver.wallet.keyring.createFromPrivateKey(&#39;0x{private key}&#39;)
// 트랜젝션 생성
const valueTransfer = caver.transaction.valueTransfer.create({
  from: keyring.address,
  to: &#39;0x176ff0344de49c04be577a3512b6991507647f72&#39;,
  value: 1,
  gas: 30000,
})

// {transaction}.sign 으로 사인해줌.
await valueTransfer.sign(keyring)
// 전송~
const receipt = await caver.rpc.klay.sendRawTransaction(valueTransfer)</code></pre></li>
</ul>
</li>
<li><p>RLP 인코딩된 서명된 트랜잭션을 <code>caver.rpc.klay.sendRawTransaction</code>을 통해 Klaytn에 전송</p>
</li>
</ol>
<h3 id="다른-트랜잭션-타입-실행">다른 트랜잭션 타입 실행</h3>
<blockquote>
<p>🙋‍♂️ 다른 트랜잭션 타입 왜 나누는데?
🤖 목적에 따라 최적의 트랜잭션을 제공하면 사용자가 사용하기 좋거든.
🙋‍♂️ 이해가 안가요
🤖 목적에 따라 거래의 유형을 바꾼다는 걸로 생각하면, 작은 금액은 &quot;일시불&quot;로 거래 하고 비싼 금액은 &quot;할부&quot;로 <strong>거래</strong> 하는걸 생각하면 될거같아.
🙋‍♂️ 다른 블록체인이 나누지 않는 이유는 뭔지?
🤖 ...</p>
</blockquote>
<h4 id="예시--fee-delegation-타입-실행">예시 ) Fee Delegation 타입 실행</h4>
<ul>
<li>수수료 대납자의 서명이 없는 경우,<pre><code>async function test() {
// 보내는 사람의 키링 생성 후 지갑에 넣어줌.
  const sender = caver.wallet.keyring.createFromPrivateKey(&#39;0x{private key}&#39;)
  caver.wallet.add(sender)
// Fee Delegation 할 트랜젝션 생성
  const feeDelegatedTx = caver.transaction.feeDelegatedValueTransfer.create({
      from: sender.address,
      to: &#39;0x176ff0344de49c04be577a3512b6991507647f72&#39;,
      value: 5,
      gas: 50000,
  })
// 해당 트랜젝션에 서명 
  await caver.wallet.sign(sender.address, feeDelegatedTx)
// 서명된 트랜젝션에서 RLP 문자열 가져올 수 있음.
  const rlpEncoded = feeDelegatedTx.getRLPEncoding()
//  수수료 납부자 키 만들기
  const feePayer = caver.wallet.keyring.createFromPrivateKey(&#39;0x{private key}&#39;)
// 월렛에 추가.
  caver.wallet.add(feePayer)
// Sender 서명한 TX 생성
  const feeDelegateTxFromRLPEncoding = caver.transaction.feeDelegatedValueTransfer.create(rlpEncoded)
// 거기에 Fee payer의 서명 추가해줌.
  feeDelegateTxFromRLPEncoding.feePayer = feePayer.address
  await caver.wallet.signAsFeePayer(feePayer.address, feeDelegateTxFromRLPEncoding)
// 비로소 해당 트랜잭션을 클레이튼 네트워크에 전송할 수 있음.
  const receipt = await caver.rpc.klay.sendRawTransaction(rlpEncoded)
  console.log(receipt)
}
</code></pre></li>
</ul>
<pre><code>
### 계정 업데이트
&gt;🙋‍♂️ 계정 업데이트는 뭘 의미하는가?
🤖 계정의 개인키를 변경하는 것을 의미합니다. + 타입의 변경??
🙋‍♂️ 보안때문에?? 왜??
🤖 ⚠️ 아마도 보안 문제가 클거같음.
🙋‍♂️ 그냥 바꾸면 되는거 아니야?
🤖 트랜잭션을 검증할때 공개키가 사용되는데, 공개키와 개인키는 쌍이라서 공개키를 변경 후 개인키를 바꿔야함.
🙋‍♂️ 자세하게 어떻게 진행되는데?
🤖 원하는 타입의 키링 생성 -&gt; 키링에서 계정 인스턴스 생성-&gt; 인스턴스를 클레이튼에 전송 -&gt; 키링 교체
</code></pre><p>async function testFunction() {
    let sender = caver.wallet.keyring.createFromPrivateKey(&#39;0x{private key}&#39;)
    caver.wallet.add(sender)
// 월렛에서 새로운 개인키 생성. ( 만들 키 갯수 ) default = 1
    const newPrivateKey = caver.wallet.keyring.generateSingleKey()
    console.log(<code>new private key string: ${newPrivateKey}</code>)
// 계정 주소 + 개인키로 새로운 키링 생성.
    const newKeyring = caver.wallet.keyring.createWithSingleKey(sender.address, newPrivateKey)</p>
<p>// Account instance 생성
    const account = newKeyring.toAccount()
// 인스턴스 클레이튼에 전송. ( tx 생성 -&gt; 사인 -&gt; 전송 )
    const updateTx = caver.transaction.accountUpdate.create({
        from: sender.address,
        account: account,
        gas: 50000,
    })
    await caver.wallet.sign(sender.address, updateTx)
    const receipt = await caver.rpc.klay.sendRawTransaction(updateTx)
    console.log(receipt)</p>
<p>// 월렛의 키링 업데이트.
    sender = caver.wallet.updateKeyring(newKeyring)
}</p>
<pre><code>
### 스마트 컨트랙트 사용성 개선

caver은 저수준의 ABI가 주어지면 모든 메소드를 자동으로 JS 호출로 변환하는 기능이있습니다.

&gt;🙋‍♂️ 이 기능이 왜 필요합니까?
🤖 스마트 컨트랙트는 솔리디티로 작성되는데 이를 친근한 JS 호출로 변환합니다.

1. 스마트 컨트랙트인 .sol 파일을 컴파일해서 바이트 코드 , ABI를 얻음.
2. ABI로 컨트랙트 인스턴스 생성 가능.
2-1. 배포 되어있지 않다면, 주소를 두번째 인자로 넣어줌.
3. 배포 하기
3-1. 스마트 컨트랙트의 바이트 코드를 data 필드에 넣어주면 배포 가능.
3-2. 배포시 수수료 대납을 위하면, </code></pre><p>const deployedInstance = await contractInstance.deploy({
        from: deployer.address,
        feeDelegation: true,
        feePayer: feePayer.address,
        gas: 1500000,
    }, byteCode)</p>
<pre><code>3-3. sender(deployer)과 대납자의 서명을 따로 하고 배포할때,</code></pre><p>const contractInstance = caver.contract.create(abi)
// deployer 서명?
const signed = await contractInstance.sign({
        from: deployer.address,
        feeDelegation: true,
        gas: 1500000,
    }, &#39;constructor&#39;, byteCode)
// 대납자 서명.
    await caver.wallet.signAsFeePayer(feePayer.address, signed)
// 클레이튼에 tx 전송
    const receipt = await caver.rpc.klay.sendRawTransaction(signed)
// 배포 결과 가져오기.
    const deployed = caver.contract.create(abi, receipt.contractAddress)</p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[RPC란 무엇인가..?]]></title>
            <link>https://velog.io/@j_user0719/RPC%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@j_user0719/RPC%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Fri, 18 Feb 2022 01:01:32 GMT</pubDate>
            <description><![CDATA[<h1 id="rpc란-무엇일까">RPC란 무엇일까?</h1>
<blockquote>
<p>별도의 원격 제어를 위한 코딩 없이 다른 주소 공간에서 리모트의 함수나 프로시저를 실행 할 수 있게 해주는 프로세스간 통신 </p>
</blockquote>
<p>기존에는 프로세스간 통신을 위해 소켓통신, RPC 같은 방식이나 RPC를 활용한 CORBA, RMI 같은 방식을 많이 사용했다면 현재는 웹기술의 발달로 인한 SOAP, REST 등과 같은 방식들이 대세를 이루고 있다고 합니다. 
2015년 구글에서는 RPC와 웹기술을 혼합한 gRPC를 처음 발표하기도 했고 많은 사람들의 관심을 받기도 했었죠 </p>
<p>RPC 모델은 분산컴퓨팅 환경에서 많이 사용되어왔으며, 현재에는 MSA에서 마이크로 서비스간에도 많이 사용되는 방식입니다. <strong>서로 다른 환경이지만 서비스간의 프로시저 호출을 가능하게 해줌에 따라 언어에 구애받지 않고 환경에 대한 확장이 가능하며, 좀 더 비지니스 로직에 집중하여 생산성을 증가시킬 수 있습니다.</strong></p>
<h1 id="프로시저와-함수">프로시저와 함수</h1>
<p>&quot;프로시저 또는 함수를 호출한다&quot; 라는 내용을 보면 함수와 프로시저에 차이점에 대해서 궁금하실 수 있는데, 함수의 경우 일반적으로 &quot;인풋에 대비한 아웃풋이 발생을 목적&quot;으로 하며, 프로시저는 결과값에 집중하기 보단 &quot;명령 단위가 수행하는 절차&quot;를 의미하는 것을 목적으로 합니다.</p>
<blockquote>
<p>결과적으로 구조상의 차이는 없으나 목표에 따라 구분을 하고 있습니다.</p>
</blockquote>
<h1 id="rpc의-동작은-어떻게-이루어질까">RPC의 동작은 어떻게 이루어질까?</h1>
<p><img src="https://images.velog.io/images/j_user0719/post/09a11a2e-bead-4e0c-9040-98c63a521dcc/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-18%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%209.56.57.png" alt=""></p>
<h3 id="동작-과정">동작 과정</h3>
<ol>
<li><p>우선 IDL(Interface Definition Language)를 통해 호출에 대한 인터페이스를 정의합니다.</p>
</li>
<li><p>IDL에 의해 정의된 인터페이스는 client의 stub과 server의 skeleton 생성의 기반이 되며, rcpgen(유틸리티)를 통해 각각의 stub과 skeleton을 생성합니다.</p>
</li>
<li><p>클라이언트는 리모트의 프로시저를 사용하기 위해 설계된 스텁의 프로시저를 호출하고, 프로시저 호출에 필요한 인자와 비지니스에 로직에 필요한 메소드를 호출합니다.</p>
</li>
<li><p>스텁은 서버가 이해할 수 있는 형태로 데이터의 캐스팅 진행하고, 서버 측 RPC로 호출을 진행합니다.</p>
</li>
<li><p>서버는 수신된 호출에 대한 데이터를 처리합니다.</p>
</li>
<li><p>서버측 RPC 프로토콜은 처리된 데이터를 캐스팅하여 클라이언트로 응답합니다.</p>
</li>
</ol>
<h3 id="설명">설명</h3>
<ol>
<li><p>IDL이란 말그대로 <strong>인터페이스에 대한 정의</strong>를 진행하는 언어이며, 각각의 시스템을 연결하는 고리가 됩니다. 
RPC를 사용하는 Client와 Server간에 같은 형태의 언어를 사용할 수도, 그렇지 않을 수도 있습니다. 다른 언어간의 프로시저가 서로의 요청에 대해서 이해하기 위해서는 인터페이스를 통해 규칙을 명세해두고 각자의 시스템이 이해할 수 있는 형태로의 변형이 필요합니다.</p>
</li>
<li><p>정의된 IDL을 기반으로 rcpgen이라는 rpc 프로토콜 컴파일러를 통해 코드(stub)가 생성됩니다. 스텁을 통해 Client는 프로시저 호출을 위한 참조자가 생겼고, Server는 프로시저 이해를 위한 참조가 생기게 됩니다.</p>
</li>
<li><p>RPC 호출을 위해 필요한 파라메터를 넣어 호출을 진행합니다.</p>
</li>
<li><p>작성된 코드를 통해 생성된 데이터는 RPC 프로토콜의 XDR 필터를 통해 인코딩되어(데이터 캐스팅) 서버로 전송됩니다. </p>
</li>
<li><p>서버측 RCP 프로토콜은 클라이언트로부터 전달 받은 데이터를 디코딩하고 데이터를 처리합니다.</p>
</li>
<li><p>서버에서는 처리된 데이터를 XDR 필터를 통해 인코딩하고 클라이언트에게 전달하여 줍니다. 데이터를 전달 받은 클라이언트는 인코딩된 데이터를 다시 디코딩하고 결과 값을 받아보게 됩니다.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[쿠버네티스에 대한 얕은 이해]]></title>
            <link>https://velog.io/@j_user0719/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4%EC%97%90-%EB%8C%80%ED%95%9C-%EC%96%95%EC%9D%80-%EC%9D%B4%ED%95%B4</link>
            <guid>https://velog.io/@j_user0719/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4%EC%97%90-%EB%8C%80%ED%95%9C-%EC%96%95%EC%9D%80-%EC%9D%B4%ED%95%B4</guid>
            <pubDate>Thu, 17 Feb 2022 00:39:06 GMT</pubDate>
            <description><![CDATA[<h1 id="쿠버네티스란">쿠버네티스란</h1>
<p>도커가 이미지를 컨테이너에 올려 돌아가게 만드는 <strong>가상화 플랫폼</strong>이라고 하면 쿠버네티스는 <strong>이 컨테이너들을 관리하는 플랫폼</strong>이라고 생각하면 된다.</p>
<blockquote>
<p>컨테이너의 생태계를 관리한다고 나는 이해했다. </p>
</blockquote>
<p>죽으면 살리고 배포할 때 어떻게 띄울 것이며 카나리 전략을 사용할 수 있게 해주는 일종의 분산 컨테이너를 관리하는 툴이라고 생각하면 편한 것 같다.
로깅과 모니터링도 가능하다고 한다.</p>
<p><img src="https://images.velog.io/images/j_user0719/post/3d95e8ba-d5df-4edc-83c3-bd3549c1a43e/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.16.06.png" alt=""></p>
<h1 id="마스터">마스터</h1>
<p>마스터(Kubernetes Master)는 쿠버네티스 클러스터 전체를 컨트롤 하는 시스템이다.</p>
<p>AWS EKS같은 경우 마스터를 AWS 자체 관리하여 안정성을 높였고(마스터에 접속 불가), 개발 환경이나 소규모 환경에선 마스터와 노드를 분리하지 않고 같은 서버에 구성하기도 한다. </p>
<p>마스터 서버는 다양한 모듈이 확장성을 고려하여 기능별로 쪼개져 있으며,  크게 API서버, 스케쥴러, 컨트롤러 매니저, etcd로 구성되어 있다.</p>
<h3 id="1-api-서버">1. API 서버</h3>
<p>쿠버네티스는 모든 명령과 통신을 API를 통해서 하는데, 그 중심이 되는 서버가 API서버이다. 쿠버네티스의 모든 기능들을 REST API로 제공하고 그에 대한 명령을 처리한다.</p>
<p>노드에서 실행중인 컨테이너의 로그를 보여주고 명령을 보내는 등 디버거 역할도 수행한다. </p>
<h3 id="2-etcd">2. etcd</h3>
<p>API서버가 명령을 주고 받는 서버라면, etcd는 <strong>쿠버네티스 클러스터의 데이터베이스 역할</strong>을 하는 서버로 RAFT 알고리즘을 이용한 key-value 저장소이다.</p>
<h3 id="3-스케쥴러">3. 스케쥴러</h3>
<p>스케쥴러는 Pod, 서비스 등 각 리소스들을 적절한 노드에 할당하는 역할을 한다.</p>
<h3 id="4-컨트롤러-매니저">4. 컨트롤러 매니저</h3>
<p>컨트롤러 매니저는 컨트롤러(Replica Controller, Service Controller, Volume Controller, Node Controller 등)를 생성하고 이를 각 노드에 배포하며 이를 관리하는 역할을 한다.</p>
<h3 id="5-dns">5. DNS</h3>
<p>쿠버네티스는 리소스의 엔드포인트(EndPoint)를 DNS로 맵핑하고 관리한다. Pod나 서비스 등은 IP를 배정받지만 동적으로 생성되는 리소스이므로 컨테이너 기동/삭제에 따라 IP주소가 변경되기 때문에, 그 리소스에 대한 위치정보가 필요하다. 내부 위치정보를 DNS 서버를 두고 관리한다. 새로운 리소스가 생기면 그 리소스에 대한 IP와 DNS 이름을 등록하여, DNS 이름 기반으로 리소스에 접근할 수 있도록 한다. </p>
<h1 id="노드">노드</h1>
<p>노드는 컨테이너화 된 어플리케이션을 실행하는 단위 클러스터의 노드! 라고 생각하면 편하다 <strong>클러스터 내에서 분산되어서 일하는 단위</strong> 인거다.</p>
<h3 id="1-파드">1. 파드</h3>
<p>파드는 애플리케이션이 실행중인 <strong>하나 이상의 컨테이너들을 관리하는 작은 단위</strong>이다. 노드내의 파드들은 격리가 적용되고 파드내의 컨테이너들도 각각 하위격리가 적용된다. 쿠버네티스의 특징중의 하나는 컨테이너를 개별적으로 하나씩 배포하는 것이 아니라 Pod 라는 단위로 배포하는데, Pod는 하나 이상의 컨테이너를 포함한다.</p>
<p><img src="https://images.velog.io/images/j_user0719/post/cc90265f-1167-41de-a556-82e234e2d22d/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-17%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%209.45.07.png" alt=""></p>
<ul>
<li><p>apiVersion은 이 스크립트를 실행하기 위한 쿠버네티스 API 버전이다 보통 v1을 사용한다.</p>
</li>
<li><p>kind 에는 리소스의 종류를 정의하는데, Pod를 정의하려고 하기 때문에, Pod라고 넣는다.</p>
</li>
<li><p>metadata에는 이 리소스의 각종 메타 데이타를 넣는데, 라벨(뒤에서 설명할)이나 리소스의 이름등 각종 메타데이타를 넣는다</p>
</li>
<li><p>spec 부분에 리소스에 대한 상세한 스펙을 정의한다.</p>
<ul>
<li>Pod는 컨테이너를 가지고 있기 때문에, container 를 정의한다. 이름은 nginx로 하고 도커 이미지 nginx:1.7.9 를 사용하고, 컨테이너 포트 8090을 오픈한다.</li>
</ul>
</li>
</ul>
<h3 id="2-kube-proxy">2. Kube-proxy</h3>
<p>노드로 들어오는 네트워크 트래픽을 적절한 컨테이너로 라우팅하고, 로드밸런싱 등 노드로 들어오고 나가는 네트워크 트래픽을 프록시하고, 노드와 마스터간의 네트워크 통신을 관리한다.</p>
<p>각 노드에서 실행중인 네트워크 프록시 바깥 네트워크 세상과 노드 내부를 연결해주고 파드랑도 연결해 준다.</p>
<h3 id="3-kubelet">3. Kubelet</h3>
<p>노드에 배포되는 에이전트로, 마스터의 API서버와 통신을 하면서, 각 노드의 에이전트, 파드에서 컨테이너가 제대로 실행될 수 있도록 한다. 반대로 노드의 상태 등을 마스터로 전달하는 역할을 한다. </p>
<h3 id="4-container-runtime">4. Container runtime</h3>
<p>Pod를 통해서 배포된 컨테이너를 실행하는 컨테이너 런타임이다.</p>
<h3 id="5-cadvisor">5. cAdvisor</h3>
<p>cAdvisor는 각 노드에서 기동되는 모니터링 에이전트로, 노드에서 기동되는 컨테이너들의 상태와 성능 등의 정보를 수집하여, 마스터 서버의 API 서버로 전달한다. 주로 모니터링에 사용됨.</p>
<h1 id="애드온">애드온</h1>
<p>애드온은 클러스터 내부에서 필요한 기능들을 위해 실행되는 포드들이다.  </p>
<h3 id="1-네트워킹-에드온">1. 네트워킹 에드온</h3>
<p>쿠버네티스는 클러스터 내부에서 가상 네트워크를 구성해서 사용하는데, 이때 kube-proxy 이외에 네트워킹 관련한 애드온을 사용한다. 
(AWS, Azure, GCP 같은 클라우드 서비스에서 제공하는 쿠버네티스를 사용한다면 별도의 네트워킹 애드온을 사용하지 않더라도 각 클라우드 벤더에서 구현하고 있으니 신경쓰지 않아도 된다.)</p>
<p>쿠버네티스를 직접 보유중인 서버들에 설치해서 구성을 하려면 네트워킹 관련 애드온을 설치해서 사용해야한다. </p>
<h3 id="2-dns-애드온">2. DNS 애드온</h3>
<p>DNS 애드온의 경우 실제로 클러스터 내에서 작동하는 DNS서버이다. 쿠버네티스 서버들에 DNS 레코드를 제공하는 역할을 한다. 내부에서 실행된 컨테이너들은 자동으로 DNS서버에 등록된다. (kube-dns , core-dns)</p>
<h3 id="3-대시보드-애드온">3. 대시보드 애드온</h3>
<p>kubectl이라는 CLI(command Line Interface)를 많이 사용한다. 하지만 웹 UI가 필요한 경우 사용할 수 있는 대시보드</p>
<h3 id="4-컨테이너-자원-모니터링">4. 컨테이너 자원 모니터링</h3>
<p>실행중인 컨테이너의 상태를 모니터링 하기 위해서는 cpu, 메모리 같은 필요한 메트릭 데이터를 시계열형식으로 저장하고 볼수 있는 방법을 제공하는데 필요한 애드온이다.</p>
<p>kubelet안에 cAdvisor라는 컨테이너 모니터링 도구가 포함되어 있으며, 이 데이터들을 수집해서 사용할 수 있는 힙스터(heapster)를 이용하면 손쉽게 필요한 데이터들을 수집해서 모니터링에 이용할 수 있다.</p>
<h3 id="5-클러스터-로깅">5. 클러스터 로깅</h3>
<p>클러스터 내의 각 개별 컨테이너에서 나오는 로그와 쿠버네티스 구성요소들에서 나오는 로그들을 중앙화된 로그 수집 시스템에서 모아서 볼 수 있다. 로그를 수집해서 제공해주는 역할로는 ELK(ElasticSearch, Logstash, Kibana)를 많이 사용한다.</p>
<h1 id="helm-chart">Helm Chart</h1>
<p>업무상 많이 나오는 단어로 처음에 몰라서 행차트..? 라고 검색했던 기억이 난다...일반적으로 Kubernetes Manifest 파일은 정적인 형태이다. 따라서 데이터를 수정하기 위해선 파일 자체를 수정해야 한다. 잘 관리를 한다면야 큰 어려움은 없겠지만, 문제는 CI/CD 등 자동화된 파이프라인을 구축해서 애플리케이션 라이프사이클을 관리할 때 발생합니다.</p>
<p>보통 애플리케이션 이미지를 새로 빌드하게 되면, 빌드 넘버가 변경됩니다. 이렇게 되면 새로운 이미지를 사용하기 위해 Kubernetes Manifest의 Image도 변경되어야 합니다. 하지만 Kubernetes Manifest를 살펴보면, 이를 변경하기 쉽지 않다는 것을 깨닫게 됩니다. Image Tag가 별도로 존재하지 않고 Image 이름에 붙어있기 때문입니다. 이를 자동화 파이프라인에서 변경하려면, <code>sed</code> 명령어를 쓰는 등의 힘든 작업을 (눈물의 똥꼬쇼를)해야 합니다. </p>
<p>이 외에도 배포하는 이름에 따라 ConfigMap을 바꿔주고, 또 배포할 때마다 큰 틀은 같지만 조금씩 다른 형태로 데이터를 배포해야 할 때, 매번 Manifest를 수정하는 것은 너무나 비효율적입니다.</p>
<p>Helm Chart는 이런 어려움을 단번에 해결해줍니다. 물론 차트를 처음 만들 때는 번거롭긴 합니다. 필요로 하는 데이터를 template 형태로 작성해서 관리하고 있어야 하고, 단순히 배포만 하면 끝나던 것이 아니라, Helm 차트 자체를 관리해야 하는 노고도 추가됩니다. 그럼에도 불구하고 Helm Chart는 훌륭한 도구이며, 개인적인 의견으론 반드시 사용해야 하는(!) 도구라고 생각합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[도커에 대한 얕은 지식]]></title>
            <link>https://velog.io/@j_user0719/%EB%8F%84%EC%BB%A4%EC%97%90-%EB%8C%80%ED%95%9C-%EC%96%95%EC%9D%80-%EC%A7%80%EC%8B%9D</link>
            <guid>https://velog.io/@j_user0719/%EB%8F%84%EC%BB%A4%EC%97%90-%EB%8C%80%ED%95%9C-%EC%96%95%EC%9D%80-%EC%A7%80%EC%8B%9D</guid>
            <pubDate>Wed, 16 Feb 2022 09:08:19 GMT</pubDate>
            <description><![CDATA[<p>도커는 직접 써보지는 않았지만 한번쯤은 들어본 용어일 것이다. + 대충 컨테이너 형태의 두루뭉술한 가상 서버?</p>
<p>그래서 도커가 뭔데? 라고 하면 사실 정확히 설명하지 못하기 때문에 이번 기회에 정리하며 넘어가도록 하겠슴다..( 이후 반말..)</p>
<h1 id="가상화">가상화</h1>
<p><strong>가상화</strong>는 하나의 서버의 자원이 100% 사용하지 않는다는 문제점을 해결하고자 다양한 가상화 기법이 탄생하게 되었고 가상화의 종류 대표적으로 자바의 JVM, VPN 등이 있다.</p>
<blockquote>
<p>🙋‍♂️그럼 서버를 가상화하면서 얻을 수 있는 이점은 무엇이 있을까? 
바로 컴퓨팅 자원을 여러 개로 분할하여 최대한 사용하여 그 효율성을 극대화할 수 있다는 점이다.</p>
</blockquote>
<h2 id="서버-가상화">서버 가상화</h2>
<p>서버 가상화에서 가장 핵심이 되는 것이 바로 하이퍼바이저이다. 우리가 사용하고 있는 윈도우, 리눅스, mac os 등은 기본적으로 컴퓨터에 직접 설치되고 하드웨어와 프로그램 및 스케줄링과 같은 대부분의 중요 작업은 운영체제의 커널에서 수행된다. 즉, 우리가 어떤 운영체제를 사용하는지에 따라서 커널의 역할을 비슷하지만 그 동작 방식이 다르다고 할 수 있으며, 이에 따라 다른 운영체제와 호환할 수 있는 애플리케이션을 제작하기 위해서는 응용 프로그래머가 이에 맞춰서 별도로 개발해야 하는 수고스러움이 존재한다.</p>
<p><img src="https://images.velog.io/images/j_user0719/post/18afe8d2-9835-4412-8388-1ca054694523/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.06.25.png" alt=""></p>
<p>위 그림을 보자면 기존에는 3가지의 애플리케이션을 실행하기 위해서는 3개의 서버가 별도로 존재하는 것을 알 수 있다. 하지만 가상화를 사용하면 하나의 하드웨어 즉 서버에 3가지의 운영체제와 각각의 애플리케이션이 동작하는 모습을 볼 수 있다.</p>
<blockquote>
<p>🙋‍♂️ 우리가 사용하는 애플리케이션이 하나의 컴퓨팅에서 여러 개 동작하듯이 서버 하나에서 여러 개의 애플리케이션을 동작하면 되지 않을까?
🤖 가..가능...근데 서버의 장애가 발생하거나, 서비스의 자원이 부족하면 어떡하실..?
🙋‍♂️ 크...큰일남</p>
</blockquote>
<p>가상화를 사용하면 사용하는 컴퓨팅 자원 즉 하드웨어는 동일하지만 격리된 공간에서 독립적으로 구성되기 때문에 특정 서버에 문제가 발생하더라도 다른 서버에 문제가 생기지 않고, 서버 구입 비용을 획기적으로 줄일 수 있으며 백업과 복구의 관리가 용의 해진다는 장점이 있다.</p>
<h2 id="서버-가상화의-종류">서버 가상화의 종류</h2>
<p>종류의 구분에 앞서 일반적으로 알아야 하는 내용부터 빠르게 보고가자.
일반적으로 운영체제를 설치하면 설치된 운영체제가 커널을 통해 하드웨어를 제어하게 되는데, 하이퍼바이저의 자체에서는 하드웨어를 제어할 수 없기 때문에 Dom0 (Domain 0)라는 관리 머신이 함께 동작한다.Dom0는 하드웨어에 접근할 수 있는 특별한 권한을 가지고 있고 디바이스 드라이버 역시 포함되어 있다. </p>
<blockquote>
<p>즉 하이퍼바이저에서는 Dom0가 없이는 동작할 수 없다. 따라서 Dom0가 얼마나 많은 역할을 담당하는지에 따라 가상화의 종류가 결정됨.(사진 2)</p>
</blockquote>
<p>이와 별개로 DomU (Domain U)는 하드웨어에 직접 접근할 수 있는 권한이 없는 비특권 도메인으로 가상 디스크나 네트워크 접근에 대한 부분을 관리한다. 만약 DomU가 실질적으로 물리 하드웨어에 동작을 원한다면 반드시 Dom0와 통신해야 한다. (사진 1)</p>
<p><img src="https://images.velog.io/images/j_user0719/post/c208e32d-a735-4675-9e2f-485ec28dd209/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.19.19.png" alt="사진1">
<img src="https://images.velog.io/images/j_user0719/post/2e944dbf-0861-4246-9961-3c5a4555be2c/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.19.50.png" alt="사진2"></p>
<blockquote>
<p>🙋‍♂️ 그래서 타입 1,2 차이가 뭔데???</p>
</blockquote>
<h3 id="타입-1-hypervisor-native--bare-metal--반가상화">타입 1 hypervisor (native / bare-metal / 반가상화).</h3>
<p><em>hypervisor를 bare-metal로 부르는 이유는 &quot;어떤 소프트웨어도 담겨있지 않은 하드웨어&quot;라는 의미</em></p>
<p><img src="https://images.velog.io/images/j_user0719/post/7c2e45c7-59c3-4dcd-934e-30d66e2509b6/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.21.13.png" alt=""></p>
<blockquote>
<p>즉 하드웨어 위에 운영체제가 설치되지 않고 하이퍼바이저가 하드웨어를 직접 컨트롤하는 것을 말한다.</p>
</blockquote>
<p>단일 하이퍼바이저가 하드웨어를 종합적으로 관리하기 때문에 오버헤드가 적고 리소스 관리에 유연하다는 장점이 있다. </p>
<p>하지만 운영체제 즉 커널이 정상적으로 동작하기 위해서는 system call이 아닌 hyper call를 통해 요청을 처리해야 한다. 이는 위에서 설명한 하이퍼바이저의 Dom0와 DomU에 명령을 실행하기 위한 별도의 명령어가 필요하다는 뜻이기 때문에 커널을 수정하지 않는 이상 Type 1 hypervisor 방식을 사용할 수 없다. </p>
<p>리눅스나 유닉스의 경우 오픈소스 형태이기 때문에 커널을 수정하는 것이 쉬웠으나 윈도우의 경우 커널을 공개하지 않기 때문에 원칙적으로라면 실행하지 못하는 게 정상이다. 하지만 XEN과 마이크로소프트가 Type 1 hypervisor를 지원하도록 커널을 수정하고 해당 프로그램을 제공하기 때문에 사용하는데 지장은 없다.</p>
<blockquote>
<p>종류에는 VMware ESX and ESXi, Microsoft Hyper-V, Citrix XenServer, Oracle VM...</p>
</blockquote>
<h3 id="타입-2-hypervisor-hosted--full-virtualization--전가상화">타입 2 hypervisor (hosted / Full virtualization / 전가상화)</h3>
<blockquote>
<p>Type 2 hypervisor의 경우 하드웨어 위에 일반적인 운영체제가 동작하고 있고 그 위에 하이퍼바이저를 설치하고, 모든 하드웨어 자원을 가상화하여 운영하는 방식이다.</p>
</blockquote>
<p>모든 자원을 가상화하고 이를 각각의 하이퍼바지어저가 전달해주는 방식이기 때문에 Type 1 hypervisor 보다 상대적으로 오버헤드가 크게 나타날 수밖에 없지만！ 게스트 OS의 수정이 전혀 필요하지 않다. 또한 기존 운영체제를 사용하면서 가상 머신을 운영할 수 있다는 장점이 있기 때문에 우리가 가장 흔하게 접근할 수 있는 방식이다.</p>
<h1 id="컨테이너">컨테이너</h1>
<p>도커의 핵심적인 개념으로 학습할 컨테이너도 운송용 컨테이너와 다르지 않다. 만약 본인이 Go로 작성된 어떠한 애플리케이션을 만들고 있다고 가정한다. 당연히 본인 컴퓨터에서는 관련 환경설정이 되어 있기 때문에 개발하고 운영하는데 아무런 지장이 없겠지만 다른 이가 내가 만든 애플리케이션을 이어서 개발하거나 실행하고자 한다면본인과 다른 컴퓨팅 한경 때문에 정상적으로 실행이 되지 않을 것이고 이를 실행하기 위한 별도의 세팅 과정이 필요할 것이다. 
만약 이렇게 만들어진 애플리케이션이 다양한 라이브러리와 의존성을 가지고 있다면, 서로 다른 개발자 컴퓨터 사이의 개발환경 세팅에 따라 오류가 발생할 수 있고 이를 해결하기 위한 엄청난 노력이 필요할 것이다. 
이를 효과적으로 해결할 수 있는 방법이 바로 컨테이너이다.</p>
<p>도커는 운영체제 수준에서 가상화하는 방식을 채택하기 때문에 별도의 하드웨어가 필요하지 않고 본인이 실행하고 있는 <strong>운영체제 커널을 공유해서 컨테이너를 실행하게 되며 하이퍼바이저를 사용하는 가상화 기술 대비 매우 빠른 속도로 실행</strong>되는 특징을 가지고 있다.</p>
<p>약간의 오버헤드를 가질 수 있지만 하이퍼바이저에서 발생하는 오버헤드에 비하면 미미한 수준이며, 하나의 운영체제에서 다수의 프로세스가 실행되고 있는 것과 같이 다수의 컨테이너를 실행하는 것도 가능하다.</p>
<blockquote>
<p>이렇게 격리된 컨테이너는 호스트의 환경이 아닌 독자적인 실행환경을 가지고 있기 때문에 다른 운영체제 혹은 다른 개발 환경에서도 독립적으로 실행이 가능하고, 상태를 가지지 않는 특성 때문에 다른 컨테이너에게 영향을 주지 않으면서 파일 혹은 이미지 형식으로 쉽게 공유할 수 있다.</p>
</blockquote>
<h2 id="리눅스-컨테이너-lxc--컨테이너-기능을-제공하기-위한-인터페이스">리눅스 컨테이너 LXC : 컨테이너 기능을 제공하기 위한 인터페이스</h2>
<p>이러한 컨테이너의 기능을 잘 이해하기 위해서는 리눅스 컨테이너의 동작을 이해할 필요가 있다. </p>
<p><img src="https://images.velog.io/images/j_user0719/post/f3542bdd-a416-41de-b9b8-d44f7f15752a/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.45.42.png" alt=""></p>
<p>리눅스 컨테이너 LXC가 운영체제 수준 가상화이기 때문에 namespce, Apparmor와 SELinux, Seccomp, chroot, CGroups과 같은 커널 기능을 사용하는데, <strong>여기서 가장 중요하게 살펴봐야 할 것이 namespace와 CGroups이다.</strong></p>
<h4 id="namespace">namespace</h4>
<p>하이퍼바이저에서는 게스트 머신이 독립적인 공간을 제공하고 서로 충돌이 나지 않도록 관리하는 기능을 가지고 있는데, 리눅스 커널에는 namespace가 동일한 역할을 담당한다. 리눅스 커널에는 8가지의 namespace가 제공되고 있는데 살펴보면 다음과 같다.</p>
<blockquote>
<p>mnt (파일 시스템 마운트): 호스트 파일 시스템에 구애받지 않고 독립적으로 파일 시스템을 마운트 하거나 언마운트 가능
pid (프로세스): 독립적인 프로세스 공간을 할당
net (네트워크): namespace 간에 network 충돌 방지 (중복 포트 바인딩 등)
ipc (SystemV IPC): 프로세스 간의 독립적인 통신 통로 할당
uts (hostname): 독립적인 hostname 할당
user (UID): 독립적인 사용자 할당
Time Namespace : 독립적인 시스템 시간 할당
Control group (cgroup) Namespace : 자신이 속한 cgroup의 그룹의 상대적인 경로 제공</p>
</blockquote>
<h4 id="cgroups">CGroups</h4>
<p>커널에서 사용되는 자원에 대한 제어를 가능하게 하는 기능을 말한다. 이 기능 없이는 각각의 컨테이너에서 별도의 자원을 사용할 수 없기 때문에 실행 자체가 불가능하다. CGroups에서는 다음과 같은 자원을 제어한다.</p>
<p><img src="https://images.velog.io/images/j_user0719/post/0036a650-a701-455b-b7d5-42d9932e1cde/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.49.04.png" alt=""></p>
<h1 id="도커">도커</h1>
<h2 id="docker-image">docker image</h2>
<ul>
<li><p>이미지는 컨테이너 <strong>실행에 필요한 파일과 설정값</strong> 등을 포함하고 있는 것으로 상태 값을 가지지 않고 변하지 않는다.</p>
</li>
<li><p><strong>컨테이너는 이미지를 실행한 상태라고 볼 수 있고</strong>, 추가되고 변하는 값은 컨테이너에 저장된다.</p>
</li>
<li><p>같은 이미지를 <strong>여러 개의 컨테이너에서 생성할 수 있고</strong> 컨테이너의 상태가 변경되거나, 삭제되어도 이미지는 변하지 않고 그대로 남아있다.</p>
</li>
<li><p>Ubuntu이미지는 ubuntu를 실행하기 위한 모든 파일을 가지고 있고 MySQL이미지는 debian을 기반으로 MySQL을 실행하는데 필요한 파일과 실행 명령어, 포트 정보 등을 가지고 있습니다. 좀 더 복잡한 예로 Gitlab 이미지는 centos를 기반으로 ruby, go, database, redis, gitlab source, nginx 등을 가지고 있다.</p>
</li>
<li><p>컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 의존성 파일을 컴파일하고 이것저것 설치할 필요성이 사라진다.</p>
</li>
<li><p>새로운 서버가 추가되면 미리 만들어 놓은 이미지를 다운로드하고 컨테이너를 생성하면 된다.</p>
</li>
</ul>
<p>Docker에서 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 용량이 수백MB 이상인 경우가 많다. 처음 이미지를 pull 하게 될 경우 전체 이미지를 다운로드하기 위해 시간이 걸리지만 기존 이미지에 수정사항이 생겼을 경우 이를 위해 이미지 전체를 받는 경우는 비효율적이기 때문에 유니온 파일 시스템을 이용하여 여러 개의 레이어를 하나의 파일 시스템으로 사용할 수 있게 한다.</p>
<p><img src="https://images.velog.io/images/j_user0719/post/ecaed79c-da8a-440d-8ef1-6a026c3192c9/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.54.43.png" alt=""></p>
<p>예를 들어 ubuntu 이미지가 A + B + C의 집합이라면, ubuntu 이미지를 베이스로 만든 nginx 이미지는 A + B + C + nginx가 된다. webapp 이미지를 nginx 이미지 기반으로 만들었다면 예상대로 A + B + C + nginx + source 레이어로 구성된다. webapp 소스를 수정하면 A, B, C, nginx 레이어를 제외한 새로운 source(v2) 레이어만 다운로드하면 되기 때문에 굉장히 효율적으로 이미지를 관리할 수 있다!</p>
<p>docker pull 명령어를 실행할 때, 버전을 지정하지 않으면 가장 최신 버전으로 이미지를 받는다고 이야기했다. Docker에서는 이미지에 태그를 달아서 버전을 관리할 수 있는데 구조는 다음과 같다.</p>
<p><img src="https://images.velog.io/images/j_user0719/post/532a5254-09b8-4a48-af4d-0bd66ba8de7c/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.07.01.png" alt=""></p>
<p><a href="https://github.com/pandora0667/TILD/blob/master/Docker/docker%20tutorial.md">출처</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[NFT에서 ERC-721이란?]]></title>
            <link>https://velog.io/@j_user0719/NFT%EC%97%90%EC%84%9C-ERC-721%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@j_user0719/NFT%EC%97%90%EC%84%9C-ERC-721%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Sun, 16 Jan 2022 06:55:01 GMT</pubDate>
            <description><![CDATA[<h2 id="nft의-중요성">NFT의 중요성</h2>
<p>대체불가능한 특성을 의미하는 NFT는 최근에 블록체인 커뮤니티 사이에서 중요성이 상당히 증가하였다. 디지털 자산에 대한 &#39;Ownership(소유권)&#39;의 개념은 다양한 산업들이 블록체인을 도입하면서 확고해졌다. 이는 발전하는 메타버스에 대한 공급망에서 내부적인 디지털 자산의 소유권 분쟁을 해결할 수 있기 때문이다.</p>
<h2 id="erc--20-이란">ERC -20 이란?</h2>
<p>ERC 란 Ethereum Request for Comment 의 약자로 토큰을 만들 때 따라야하는 이더리움 프로토콜을 의미하고 그중에가 20번째 프로토콜을 <strong>ERC-20</strong> 라고 명명한다. 그렇다면 이것을 왜 써야하나?? 통상적으로 안드로이드 폰이라면, A 어플에 있는 포인트를 B 어플의 포인트로 사용하지 못한다. 그러나 ERC-20으로 제작된 암호화폐는 ERC-20 기반의 다른 화폐들과도 교환이 가능하다. 게다가 토큰들은 My Ether Wallet(MEW)와 같이 ERC-20 토큰을 지원하는 Wallet들을 사용하여 자유롭게 보내질 수 있다.</p>
<blockquote>
<p>즉 <strong>누가 토큰을 가지고 있는지 상관없이 동일한 가치를 지닌다는 것</strong></p>
</blockquote>
<h1 id="erc-721이란">ERC-721이란?</h1>
<p>그렇다면 위에서 설명한 ERC-20와 Non-Fungible Token(NFT)인 ERC-721의 차이점은 무엇일까?
ERC-20은 대체가능하지만 ERC-721은 대체불가능하다는 것이다. 즉, ERC-721은 이더리움 네트워크에서 대체 불가능하다는 NFT의 개념이 도입된 토큰이다.</p>
<p>예를 들어 만약 우리가 무당벌레를 그리고, 이 그림을 &#39;무당벌레 그림&#39;이라고 하자. 여기서 그린다는 것은 &#39;무당벌레 그림&#39;과 같은 하나의 작품을 만드는 것이 되는 것이다. 이렇게 하나의 작품을 만드는 과정이 ERC-721 토큰을 만드는 과정에 해당하는 것이고, &#39;무당벌레 그림&#39;은 다른 무당벌레를 그린 그림들과 대체가 불가능하며 가치가 다르므로 ERC-721 기반의 NFT에 해댕하는 것이다.</p>
<p>NFT의 또 다른 특징은 토큰에 대한 소유권이 나뉘어 질 수 있다는 것이다. 즉, 부분적인 소유권이 허용되며 교환될 수 있다.
예를 들어 &#39;무당벌레 그림&#39;의 소유권은 James가 100ETH 모두 가질 수 있고, Rachel이 90ETH를 주고 구매한다면 James와 Rachel이 소유권을 각각 10%, 90%씩 나누어 가질수도 있다.</p>
<p><img src="https://images.velog.io/images/j_user0719/post/6a3863e0-36d4-45ab-b7b1-9b0a56747e92/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-16%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%203.52.41.png" alt=""></p>
<h2 id="erc-721을-통해-본-nft의-장점과-단점">ERC-721을 통해 본 NFT의 장점과 단점</h2>
<h3 id="nft의-장점">NFT의 장점</h3>
<p>위에서 살펴보았듯이 NFT는 사용자들의 디지털 자산에 대한 소유권을 보장하기 위해 중요한 역할을 담당한다. 현존하는 시스템에서 디지털 자산은 사용자들에 의해 완전히 소유된 것이 아니다. 예를 들어, 게임에서 사용자들이 그들의 시간과 돈을 투자하여 얻은 아이템은 해당 서비스에서만 유용성과 가치를 갖고, 서비스가 종료되면 자산들도 소멸된다. 사용자들의 시간과 자원들은 무의미해질 수 있다. 하지만 만약 NFT가 도입된다면, 모든 종류의 디지털 자산들이 블록체인에 저장되어 소유권이 보장되고 안전하게 보관될 수 있다. 블록체인 안의 정보들은 소유권을 증명할 것이고, 사용자들간의 자산을 교환하는 것은 더욱 쉬워질 것이다. 따라서, 사용자들로 하여금 그들의 디지털 자산을 관리하고 활용하도록 편하게 만들어야 한다.</p>
<h3 id="nft의-단점">NFT의 단점</h3>
<p>ERC-721의 경우를 통해 보면 NFT를 도입하여 문제가 발생한 경우가 있었다. CryptoKitties가 꽤나 유명해질때쯤, 엄청난 양의 거래 규모가 짧은 기간에 발생하였고, 이더리움 네트워크에 부담을 일으킨 적이 있었다. 이것은 불가피하게 사용자가 지불해야 하는 transaction(거래)의 수수료(gas fee)를 증가시켰다. 대부분의 NFT들은 이더리움 기반의 토큰이기 때문에 확장성 및 과도한 비용 문제는 해결되어야 한다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[블록체인에 대한 짧은 고찰]]></title>
            <link>https://velog.io/@j_user0719/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A7%A7%EC%9D%80-%EA%B3%A0%EC%B0%B0</link>
            <guid>https://velog.io/@j_user0719/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A7%A7%EC%9D%80-%EA%B3%A0%EC%B0%B0</guid>
            <pubDate>Tue, 11 Jan 2022 23:08:49 GMT</pubDate>
            <description><![CDATA[<h3 id="블록체인이란">블록체인이란?</h3>
<blockquote>
<p>정보를 블록이라고 하는 단위로 저장하여 (해시를 통해) 저장된 블록을 체인 형태로 묶는 저장기술.</p>
</blockquote>
<h3 id="블럭-간에는-어떻게-연결-되어있나">블럭 간에는 어떻게 연결 되어있나?</h3>
<blockquote>
<p>리스트 같지만 조금 다름 다음 블럭(2)은 헤더에 이전 블록(1)의 해시를 기억(해시 포인터)하고 어떤 블럭 앞에 오는지 알 수 있고 이는 곧 순서를 결정 할 수 있음.</p>
</blockquote>
<h4 id="해시포인터란">(해시포인터란?)</h4>
<blockquote>
<p>이전 블럭의 해시의 주소값을 기억하고 있는 것임.</p>
</blockquote>
<h3 id="블록체인-네트워크란">블록체인 네트워크란?</h3>
<blockquote>
<p>P2P 네트워크로 참여자(shem) 모두 동일한 순서의 블록체인을 유지하고 있는 네트워크 망</p>
</blockquote>
<h3 id="합의란-무엇인가⭐️⭐️">합의란 무엇인가?⭐️⭐️</h3>
<blockquote>
<ul>
<li>자격(ex. PoW, PoC) 있는 참여자가 새로운 블록을 제안할때 이것이 옳은 제안인지 판별하는 것.</li>
</ul>
</blockquote>
<ul>
<li>블록이 새롭게 추가됨 =&gt; 참여자가 자격을 받음 =&gt; 합의 알고리즘 통과함 =&gt; 참여자들이 새 블럭을 자신의 체인에 추가함.</li>
<li>이 과정이 사실 탈중앙화 되어있음을 의미함.</li>
</ul>
<h3 id="합의-알고리즘-비교-분석⭐️">합의 알고리즘 비교 분석⭐️</h3>
<p> <img src="https://images.velog.io/images/j_user0719/post/9e24a680-6801-4852-a5f4-6a339cd56748/image.png" alt=""></p>
<h3 id="public-vs-private">Public VS Private</h3>
<ul>
<li>누구든지 기록된 블록을 자유롭게 읽을 수 있는지??</li>
<li>명시적인 등록 또는 정보를 블록체인에 기록할 수 있는지??</li>
</ul>
<blockquote>
<ul>
<li>Public : 정보가 공개되어있고, 네트워크가 정한 기준에 따라 기록을 요청할 수 있다.</li>
</ul>
</blockquote>
<ul>
<li>Private : 정보가 공개 X , 미리 자격을 득한 사용자만 정보를 기록할 수 있음.</li>
</ul>
<h3 id="permissionless-vs-permissioned">Permissionless VS Permissioned</h3>
<ul>
<li>네트워크 참여 : 1. 블록체인 네트워크 그자체 2. 합의 과정에 참여</li>
</ul>
<blockquote>
<ul>
<li>Permissionless: 네트워크 참여에 제한 X</li>
</ul>
</blockquote>
<ul>
<li>Permissioned : 네트워크 참여에 제한 O</li>
</ul>
<h3 id="공개키--비밀키--전자-서명">공개키 , 비밀키 , 전자 서명</h3>
<blockquote>
<p>전자 서명은 보낸 사람의 비밀키(유일)로 생성 -&gt; 받는 사람은 공개키로 해당 서명을 통해 누구에게서 온 것인지 확인 가능</p>
</blockquote>
<ul>
<li>(보낼때) 수신자의 공개키로 암호한 메시지 + 본인의 비밀키로 만든 서명</li>
<li>(받을때) 본인의 비밀키로 메시지 복호화 + 송신자의 공개키로 서명 복호화</li>
</ul>
<h3 id="utxo-기반의-블록체인과-어카운트-기반의-블록체인은-어떻게-다른가요">UTXO 기반의 블록체인과 어카운트 기반의 블록체인은 어떻게 다른가요?</h3>
<blockquote>
<ul>
<li>UTXO는 돈 자체에 주소를 주고 암호화 되어있고 돈을 쓸 때 전자서명을 주는 것</li>
</ul>
</blockquote>
<ul>
<li>어카운트에 주소를 주고 밸런스를 가지고 있어서 어느 어카운트를 사용하기 위해 전자서명을 낸다.</li>
</ul>
<h3 id="utxo-기반의-블록체인이-어카운트-기반의-블록체인과-비교했을-때-가지는--장점은-무엇인가-어카운트-기반-블록체인의-장점은-무엇인가요⭐️">UTXO 기반의 블록체인이 어카운트 기반의 블록체인과 비교했을 때 가지는  장점은 무엇인가? 어카운트 기반 블록체인의 장점은 무엇인가요?⭐️</h3>
<blockquote>
<ul>
<li>UTXO : 유효성 검사가 쉽고 보안성도 좋고 병렬화가 가능. But 이자 같은것도 utxo 로 관리 되기 때문에 불필요한 공간이 많아지게 되는 것.</li>
</ul>
</blockquote>
<ul>
<li>어카운트 -&gt; 어카운트 기반은 순서대로 해야함(병렬화 X) But 상태가 생겨서 스마트 컨트랙트를 사용할 수 있음. (프로그램에 상태값이 없으면 일회성 프로그램 밖에 되질 않음)</li>
</ul>
<h3 id="이더리움-어카운트-주소--상태">이더리움 어카운트, 주소 , 상태</h3>
<blockquote>
<ul>
<li>어카운트 : 엔티티를 표현하고 그 상태를 기록하는데 사용. <ul>
<li>EOA: 사용자가 사용하는 것으로 어카운트 주소를 암호화해 eoa를 생성.</li>
<li>스마트컨트랙트: 개인간의 원하는 계약체결을 위한 기능. 외부함수..?API 같은 느낌.</li>
</ul>
</li>
</ul>
</blockquote>
<h3 id="트랜잭션이란">트랜잭션이란?</h3>
<blockquote>
<p>블록체인 내에서 저장의 단위</p>
</blockquote>
<ul>
<li>블록은 트랜잭션을 일정한 순서로 정렬한 컨테이너임</li>
<li>원장의 거래내역 같은 st 이더에서는 특히 순서가 중요.</li>
</ul>
<h3 id="confirmation-vs-finality">Confirmation VS Finality</h3>
<blockquote>
</blockquote>
<ul>
<li>Finality(불변성)<ul>
<li>블록의 완결성을 의미.</li>
<li>합의를 통해 생성된 블록이 번복되지 않음을 의미(Pow는 안됨.)</li>
</ul>
</li>
<li>Confirmation: 체인의 경쟁을 최소 6블록이내 결판이 나기 때문에 체결할때 6컨펌 거친 블록체인에 붙음.</li>
</ul>
<h3 id="bft기반-블록체인의-finality">BFT기반 블록체인의 Finality</h3>
<blockquote>
<ul>
<li>BFT는 블록의 완결성이 보장<ul>
<li>네트워크가 동기화 되어있어서</li>
<li>Pow보다 빠르고 경제적.</li>
</ul>
</li>
</ul>
</blockquote>
<ul>
<li>단점<ul>
<li>일정 수 이상 넘어가면 시간이 느려짐(네트워크 오버헤드)</li>
<li>네트워크 사용량이 높음 (동기화때문)</li>
</ul>
</li>
</ul>
<h3 id="klaytn-bft">Klaytn BFT</h3>
<p><img src="https://images.velog.io/images/j_user0719/post/b0e3d688-9674-427c-9fe8-abeace9e2a60/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-16%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.09.37.png" alt=""></p>
<blockquote>
<ul>
<li>매 블록마다 새로운 커미티를 뽑아 내부적으로 BFT실행.</li>
</ul>
</blockquote>
<ul>
<li>새로운 커미티는 VRF로 구해진 랜덤값</li>
<li>기존의 BFT에서 확장성을 개선함.</li>
</ul>
<h3 id="블록체인의-state-account">블록체인의 State (account)</h3>
<p>블록체인 : 초기 상태에서 변경사항을 적용하며 변화하는 상태기계</p>
<blockquote>
</blockquote>
<ul>
<li>Tx는 어카운트를 생성하거나 변경.</li>
<li>Tx가 반영되는 과정에서 다른 Tx의 개입은 제한됨.(순서대로 해야 같은 결과를 보장하기 때문..)</li>
</ul>
<h3 id="contract-account-vs-external-account">Contract Account VS External Account</h3>
<blockquote>
</blockquote>
<ul>
<li>External Account(EOA) : 사용자가 사용하는 어카운트</li>
<li>Contract Account : 스마트 컨트랙트를 표현하는 어카운트</li>
</ul>
<h3 id="트랜잭션과-가스">트랜잭션과 가스</h3>
<blockquote>
</blockquote>
<ul>
<li>트랜잭션의 목적: 블록체인의 상태변경 , to에 따라 세분화.<ul>
<li>EOA : 사용자</li>
<li>Contract : 해당 컨트랙트가 실행됨.</li>
<li>없음 :</li>
</ul>
</li>
<li>GAS : TX를 처리하는데 발생하는 비용.<ul>
<li>Tx 처리에 발생한 수수료</li>
<li>보내는 쪽에서 부담하고 Gas Fee라고 정의.</li>
<li>높게 적을수록 이더넷에서 빨리 처리해줌 (Klaytn은 아님)</li>
</ul>
</li>
</ul>
<h3 id="트랜잭션의-이동경로">트랜잭션의 이동경로</h3>
<blockquote>
</blockquote>
<ul>
<li>A 👉 B<ul>
<li>A가 TX 생성, 서명해서 B에 전달</li>
<li>데이터를 온전히 전달하기 위해 RLP 알고리즘으로 TX를 직렬화</li>
<li>A와 B는 같은 프로토콜로 통신</li>
</ul>
</li>
<li>B 👉 A<ul>
<li>올바른 TX 수신했으면 TX 해시를 반환</li>
<li>체결 완료시 Recipt(소요된 gas, tx해시, input의 기록)을 반환</li>
</ul>
</li>
</ul>
<h3 id="이더리움-트랜잭션-데이터에-포함되어-있는-nonce는-무엇이고-왜-필요한가">이더리움 트랜잭션 데이터에 포함되어 있는 nonce는 무엇이고 왜 필요한가?</h3>
<blockquote>
<p>어카운트에서 트랜잭션을 또 보내는 것을 방지하기 위해 순서를 매긴 값임. 어카운트 기반에서는 병렬화를 막아줌. 즉, 어카운트가 몇번째 트랜잭션을 보내주는지 말해주는것 </p>
</blockquote>
<h3 id="비트코인에서-nonce는-뭐임">비트코인에서 nonce는 뭐임?</h3>
<blockquote>
<p>작업 증명에서 어려운 문제를 풀기 위한 정답 값</p>
</blockquote>
<h3 id="스마트-컨트랙트란">스마트 컨트랙트란?</h3>
<blockquote>
<p>특정 주소에 있는 실행 가능한 코드로 함수, 상태로 나눠져 있고 함수는 상태를 변경하거나(TX 생성해 블록에 추가) 변경하지 않는 함수(노드에서 실행)로 분류됨.</p>
</blockquote>
<h3 id="블록체인에서-지갑이란">블록체인에서 지갑이란?</h3>
<blockquote>
</blockquote>
<ul>
<li>지갑은 키를 관리하는 프로그램이다.<ul>
<li>키를 보관하고 BApp이 요청할 때마다 보관중인 </li>
</ul>
</li>
</ul>
<h3 id="메타마스크나-마이이더월렛-미스트-지갑들의-차이는">메타마스크나, 마이이더월렛, 미스트 지갑들의 차이는?</h3>
<blockquote>
</blockquote>
<ul>
<li>마이이더월렛(은행창구 직원): 웹 월렛으로 키를 암호화한 스토어인 keystore 의 비밀번호를 입력하면 Tx 생성과 전송이 가능한 지갑과 가장 유사한 동작을 했음 but 이더에서는 조금 복잡해서 메타마스크가 생김. (완전 탈중앙화)</li>
<li>메타마스크 : 크롬 플러그인으로 월렛과 사용 로직이 조금 분리 되어있는 형태 플러그인이니까 다소 크롬에 종속적임. (세미 탈중앙화)</li>
</ul>
<h3 id="bip323944가-무엇인가요">BIP32,39,44가 무엇인가요?</h3>
<h3 id="각-hash알고리즘이-어떻게-되나요">각 HASH알고리즘이 어떻게 되나요?</h3>
<p>: SHA-256 , Keccak256</p>
<h3 id="블록체인에서-random함수-구현하는-방법은-무엇인가요">블록체인에서 random함수 구현하는 방법은 무엇인가요?</h3>
<p>: NBLab이 고안한 알고리즘은 블록체인을 통해 공정한 난수 생성이 가능함과 동시에 유저가 많아져도 확장이 가능합니다.</p>
<h3 id="java에서-코드재사용을-하기-위해서-해봤던-노력은">java에서 코드재사용을 하기 위해서 해봤던 노력은?</h3>
<p>: 상속은 자식 클래스를 점진적으로 추가해서 기능을 확장하는 데는 용이하지만 높은 결합도로 인해 부모 클래스를 점진적으로 개선하는 것은 어렵게 만든다. 취약한 기반 클래스 문제는 캡슐화를 약화시키고 결합도를 높인다. 그래서 부모 클래스의 코드를 하위로 내리지 말고, 자식 클래스의 코드를 상위 계층으로 올려라. 추상적인 메서드를 부모 클래스에 두면 재사용성과 응집도의 측면에서 더 나은 결과를 얻을 수 있다. </p>
<h3 id="협업-개발에서-git을-사용하는-이유는-무엇일까요">협업 개발에서 Git을 사용하는 이유는 무엇일까요?</h3>
<h3 id="대용량-처리를-위해서-고려해야-하는-요소는-무엇이-있을까요">대용량 처리를 위해서 고려해야 하는 요소는 무엇이 있을까요?</h3>
<h3 id="블록체인에서-finality란-무엇인가요-그리고-finality가-왜-중요한가요">블록체인에서 Finality란 무엇인가요? 그리고 Finality가 왜 중요한가요?</h3>
<p>: 과거의 거래장부내역을 다시 돌아가 볼 수 없도록 하는 것입니다. Finality는 어느정도의 시간을 기다려야 블록체인에 거래내역이 Finality 상태가 되도록 기다리지 않음. 그래서 보안 뿐만 아니라 상용화에 있어서 중요함.</p>
<h3 id="비트코인에서-사용하는-머클-트리와-이더리움에서-사용하는-머클-패트리샤-트리의-차이점은-무엇이고-왜-다른-자료구조를-사용할까요">비트코인에서 사용하는 머클 트리와 이더리움에서 사용하는 머클 패트리샤 트리의 차이점은 무엇이고, 왜 다른 자료구조를 사용할까요?</h3>
<p>:</p>
<h3 id="블록체인에서-tps가-늘어나면-문제점들은-무엇이-있을까-이-문제에-대한-생각하신-솔루션이-있는가요">블록체인에서 TPS가 늘어나면 문제점들은 무엇이 있을까? 이 문제에 대한 생각하신 솔루션이 있는가요?</h3>
<blockquote>
<p>높아지면 탈 중앙화의 본질을 해칠 수 있음. 합의 알고리즘 , 스마트 컨트랙트의 연산 향상</p>
</blockquote>
<h3 id="하드-포크--소프트-포크">하드 포크 , 소프트 포크</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[기술 면접 준비 : BE]]></title>
            <link>https://velog.io/@j_user0719/%EA%B8%B0%EC%88%A0-%EB%A9%B4%EC%A0%91-%EC%A4%80%EB%B9%84-BE</link>
            <guid>https://velog.io/@j_user0719/%EA%B8%B0%EC%88%A0-%EB%A9%B4%EC%A0%91-%EC%A4%80%EB%B9%84-BE</guid>
            <pubDate>Tue, 16 Nov 2021 12:05:58 GMT</pubDate>
            <description><![CDATA[<h1 id="java">JAVA</h1>
<h3 id="jvm의-구조와-java의-실행방식을-설명해주세요">JVM의 구조와 Java의 실행방식을 설명해주세요.</h3>
<p>1) JVM의 구조</p>
<ul>
<li><p>Class Loarder: 클래스를 JVM 메모리에 로드한다.</p>
</li>
<li><p>Execution Engine: 인터프리터,JIT compiler를 이용해 데이터 영역에 배치된 바이트 코드를 실행 및 GC로 메모리 관리</p>
</li>
<li><p>Runtime Data Area: 프로그램 수행을 위해 OS 에서 할당받는 공간.</p>
</li>
</ul>
<p>2) 자바 실행과정</p>
<ol>
<li>자바 컴파일러를 통해 자바 클래스 파일(.java)를 <strong>자바바이트코드(.class)로 변환</strong>함.</li>
<li><strong>클래스로더</strong>를 통해 바이트코드를 JVM 런타임 영역에 로드함.</li>
<li>실행 엔진을 통해 <strong>실행</strong></li>
</ol>
<h3 id="gc가-무엇인지-필요한-이유는-무엇인지-동작방식에-대해-설명해주세요">GC가 무엇인지, 필요한 이유는 무엇인지, 동작방식에 대해 설명해주세요.</h3>
<ul>
<li><p>GC란? : 갈비지 컬렉터로 힙 영역에 사용하지 않는 객체들을 자동으로 제거해주는 역할을 합니다.</p>
</li>
<li><p>필요이유: 자바는 개발자가 직접 메모리를 해제해줄 수 없기 때문에 필요함.</p>
</li>
<li><p>동작방식: 객체 생성 -&gt; Eden 영역에 위치 -&gt; MinorGC로 사용하지 않는 객체 제거, 살아남으면 점점 뒤로.. -&gt; Old 영역까지 밀리면 FullGC를 통해 제거됨.</p>
<h3 id="컬렉션-프레임워크에-대해서-설명해주세요">컬렉션 프레임워크에 대해서 설명해주세요.</h3>
<p>다수의 데이터를 처리하는 클래스의 집합을 의미합니다.(List,Set,Map)</p>
<h3 id="제네릭에-대해서-설명해주세요">제네릭에 대해서 설명해주세요.</h3>
<p>ArrayList가 다룰 객체를 미리 명시해줌으로써 형변환을 하지 않고 사용하는 것입니다.</p>
<h3 id="애노테이션에-대해서-설명해주세요">애노테이션에 대해서 설명해주세요.</h3>
<p>자바에서는 @ 주석으로 특정 기능을 수행하도록 하는 기술</p>
<h3 id="오버라이딩과-오버로딩이-무엇이며-어떤-차이가-있을까요">오버라이딩과 오버로딩이 무엇이며 어떤 차이가 있을까요?</h3>
</li>
<li><p>오버라이딩 : 재정의</p>
</li>
<li><p>오버로딩 : 메서드의 이름은 같지만 매개변수 타입이나 갯수가 다른 것</p>
<h3 id="인터페이스와-추상클래스의-차이점에-대해-설명해주세요">인터페이스와 추상클래스의 차이점에 대해 설명해주세요.</h3>
</li>
<li><p>추상클래스 : 일반 클래스지만 추상 메서드가 하나라도 포함된 경우</p>
</li>
<li><p>인터페이스 : 모두 추상메서드</p>
<h3 id="클래스는-무엇이고-객체는-무엇인가요">클래스는 무엇이고 객체는 무엇인가요?</h3>
</li>
<li><p>클래스 : 객체를 만들기 위한 설계도로 field,method</p>
</li>
<li><p>객체 : 클래스 구현을 통해 만들어진 무언가</p>
<h3 id="자바의-원시타입들은-무엇이-있으며-각각-몇-바이트를-차지하나요">자바의 원시타입들은 무엇이 있으며 각각 몇 바이트를 차지하나요?</h3>
</li>
<li><p>boolean - 1bit</p>
</li>
<li><p>byte - 8bit</p>
</li>
<li><p>short- 16bit</p>
</li>
<li><p>int,float - 32bit</p>
</li>
<li><p>long,double - 64bit</p>
<h3 id="접근-제어자의-종류와-이에-대해-설명해주세요">접근 제어자의 종류와 이에 대해 설명해주세요.</h3>
</li>
<li><p>public : 같은 프로젝트 안에서 사용가능</p>
</li>
<li><p>default: 같은 패키지 안에서만 사용가능</p>
</li>
<li><p>protected: 같은 패키지 + 상속 관계일 때</p>
</li>
<li><p>private : 같은 클래스 내에서만.</p>
<h3 id="객체지향에-대해서-설명해주세요">객체지향에 대해서 설명해주세요.</h3>
<p>프로그래밍에서 필요한 데이터를 <strong>추상화</strong>시켜 상태와 행위를 가진 <strong>객체를 만들고</strong> 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법</p>
</li>
</ul>
<h3 id="solid객체지향-5대원칙에-대해서-설명해주세요">SOLID(객체지향 5대원칙)에 대해서 설명해주세요.</h3>
<ul>
<li><p>Single Responsiblity (단일 책임 원칙) : 응집도는 높고 결합도는 낮은 프로그램을 의미</p>
</li>
<li><p>Open-Closed (개방-패쇄 원칙): 기존의 코드를 변경하지 않고 기능을 수정하거나 추가할 수 있도록 설계해야함(인터페이스).</p>
</li>
<li><p>Liskov Substitution (리스코프 치환 원칙) : 자식은 부모에서 가능한 행위를 수행할 수 있어야함.</p>
</li>
<li><p>Dependency Inversion (의존 역전 원칙) : 의존관계를 맺을때, 변화하기 어려운 것에 의존 해야함.</p>
</li>
<li><p>Interface Segregation (인터페이스 분리) : 한 클래스는 자신이 사용하지 않는 인터페이스는 구현하면 안됨.</p>
</li>
</ul>
<h3 id="동일성identity와-동등성equality에-대해-설명해주세요-equals-">동일성(identity)와 동등성(equality)에 대해 설명해주세요. (equals(), ==)</h3>
<ul>
<li>동일성 : 두개의 오브젝트가 완전히 같은 경우</li>
<li>동등성 : 같은 정보를 가지고 있는 경우<h3 id="원시타입과-참조타입의-차이에-대해-설명해주세요">원시타입과 참조타입의 차이에 대해 설명해주세요.</h3>
</li>
<li>원시타입 : 실제 데이터 값을 저장하는 타입</li>
<li>참조타입 : 메모리 주소를 통해 객체를 참조하는 타입</li>
</ul>
<h3 id="checked-exception과-unchecked-exception에-대해-설명해주세요">Checked Exception과 Unchecked Exception에 대해 설명해주세요.</h3>
<ul>
<li>Checked Exception : 컴파일시점에 확인, 반드시 예외처리 해야함 안하면 에러... (IOException)</li>
<li>Unchecked Exception : 런타임에 확인, 명시적으로 예외처리 안해도 됨. (NullPointException)<h3 id="java8에서-추가된-feature에-대해서-설명해주세요">Java8에서 추가된 Feature에 대해서 설명해주세요.</h3>
</li>
<li>람다 표현식</li>
<li>스트림 API : 데이터를 추상화하여 다룰 수 있게 됨</li>
<li>java.time 패키지 : 더 직관적인 Date, Time API 제공</li>
<li>나즈혼 : JS 새로운 엔진도입<h3 id="try-with-resource에-대해서-설명해주세요">try-with-resource에 대해서 설명해주세요.</h3>
try에 자원 객체를 전달하면, try 코드 블록이 끝나면 자동으로 자원 할당을 해제해주는 기능.</li>
</ul>
<h3 id="강결합과-느슨한-결합이-무엇인지-설명해주세요">강결합과 느슨한 결합이 무엇인지 설명해주세요.</h3>
<p>강결합은 서로 높은 의존성을 가지고 있음.
약결합은 서로 낮은 의존성을 지님 -&gt; 유지보수 용이</p>
<h3 id="직렬화serializable와-역직렬화에-대해서-설명해주세요">직렬화(Serializable)와 역직렬화에 대해서 설명해주세요.</h3>
<ul>
<li>직렬화 : 객체를 전송 가능형태로 만드는것을 의미.</li>
<li>역질렬화: 전송받은 직렬화 된 데이터를 다시 객체 형태로 복원하는 것<h3 id="자바의-동시성-이슈공유자원-접근에-대해-설명해주세요">자바의 동시성 이슈(공유자원 접근)에 대해 설명해주세요.</h3>
</li>
<li>여러 스레드에서 같은 자원에 접근하는 경우, 원하는 결과를 도출 못하는 상황을 의미.</li>
<li>해결 방안</li>
</ul>
<ol>
<li>암시적 Lock: 하나의 스레드가 메서드를 실행할때 다른 메서드가 해당 메서드를 실행 못하게 대기.(synchronized)</li>
<li>명시적 Lock: ReentrantLock를 사용해서 동시에 여러 Lock을 사용하고 싶을때 사용.직접 Lock객체를 생성, 사용 <h3 id="mutable-객체와-immutable-객체의-차이점에-대해-설명해주세요">Mutable 객체와 Immutable 객체의 차이점에 대해 설명해주세요.</h3>
변하다 = 주소값 유지하며 값을 변경할 수 있다,없다의 차이</li>
</ol>
<ul>
<li><p>Mutable: 변할 수 있음</p>
</li>
<li><p>Immutable: 변할 수 없음 (String, Boolean,Integer,Float,Long...)</p>
<h1 id="spring">Spring</h1>
<h3 id="spring-diioc는-어떻게-동작하나요">Spring DI/IoC는 어떻게 동작하나요?</h3>
<p>IoC는 제어의 역전으로 인스턴스의 생성 및 소멸을 개발자 대신 스프링 컨테이너가 대신 해주는 것을 의미.
이를 실제로 제어하는 방법으로 DI가 있는데 Bean(POJO=스프링 컨테이너에서 생성된 일반 자바 객체)으로 등록된 객체 생성시 의존성을 주입해준다.</p>
</li>
<li><p>동작 : Url-&gt; dispacher-servlet 으로 요청 전달 -&gt; 핸들러 매핑(요청에 맞는 컨트롤러 검사) -&gt; 컨트롤러 로직처리 후 결과를 Model And View로 반환 -&gt; ViewResolver로 View의 실제 위치 전달 -&gt; View에서 Model과 같이 jsp그린후 dispacher-servlet전달 -&gt; 최종적으로 클라이언트에게 반환.</p>
</li>
</ul>
<h3 id="spring-bean이란-무엇인가요">Spring Bean이란 무엇인가요?</h3>
<p>POJO로 XML 을 통해 생명주기, 종속성 등을 가진 스프링 컨테이너가 생성한 일반 자바객체</p>
<h3 id="스프링-bean의-생성-과정을-설명해주세요">스프링 Bean의 생성 과정을 설명해주세요.</h3>
<p>ApplicationContext를 이용해서 객체를 생성하고 스프링 컨테이너를 초기화 -&gt; 빈 객체 생성 -&gt; <code>&lt;property&gt;</code> 태그로 지정한 의존을 설정(이때 의존 주입) -&gt; 모든 의존 설정이 완료되면, 빈 객체 초기화 -&gt; 빈 소멸</p>
<h3 id="스프링-bean의-scope에-대해서-설명해주세요">스프링 Bean의 Scope에 대해서 설명해주세요.</h3>
<ul>
<li>singleton</li>
<li>prototype : 하나의 Bean 정의 다수의 객체 존재 O</li>
<li>request : 하나의 Bean 마다 하나의 HTTP request 생명주기.</li>
<li>session : session하나마다 하나의 Bean</li>
<li>global session : 글로벌 새션 주기 안에 하나의 Bean</li>
</ul>
<h3 id="ioc-컨테이너의-역할은-무엇이-있을까요">IoC 컨테이너의 역할은 무엇이 있을까요?</h3>
<ul>
<li>IoC 컨테이너는 Bean에 대한 제어권을 가지고 Bean의 생명주기 등을 관리해서 객체들간의 낮은 결합을 도와주는 역할을 합니다.</li>
</ul>
<h3 id="di-종류는-어떤것이-있고-이들의-차이는-무엇인가요🤯">DI 종류는 어떤것이 있고, 이들의 차이는 무엇인가요?🤯</h3>
<ul>
<li><p>Field Injection :  @Autowired Annotation을 붙이는 방식으로 의존성을 주입하기는 쉽지만,스프링에 의존적인 코드가 된다. </p>
</li>
<li><p>Setter Injection : setter 메소드를 통해 외부에서 제공받는 오브젝트 레퍼런스를 내부 메소드에서 사용하며 의존성을 주입하는 방식.</p>
</li>
<li><p>Constructor Injection : 필요한 의존성을 모두 포함하는 클래스의 생성자를 통해 의존성 주입.</p>
<h3 id="autowiring-과정에-대해서-설명해주세요🤯">Autowiring 과정에 대해서 설명해주세요.🤯</h3>
</li>
<li><p>Autowiring : 필요한 의존 객체의 &quot;타입&quot;에 해당하는 Bean을 Ioc컨테이너에서 찾아 주입해주는 것.</p>
</li>
<li><p>동작과정: BeanPostProccessor라는 인터페이스의 구현체인 AutowiredAnnotationBeanPostProcessor에 의해 의존성을 주입</p>
<h3 id="프론트-컨트롤러-패턴이란-무엇인가요">프론트 컨트롤러 패턴이란 무엇인가요?</h3>
</li>
<li><p>클라이언트 요청에 맞는 컨트롤러를 찾아서 호출해서 처리하는 패턴. -&gt; 공통 코드로 처리가능.</p>
<h3 id="servlet-filter와-spring-interceptor의-차이는-무엇인가요">Servlet Filter와 Spring Interceptor의 차이는 무엇인가요?</h3>
</li>
<li><p>공통점 : 여러 작업을 처리함을써 중복된 코드를 제거할 수 있음.</p>
</li>
<li><p>차이점 :</p>
</li>
</ul>
<ol>
<li>필터는 요청이 servlet 전/후에 url패턴에 맞는 부가작업을 처리할 수 있음.(Init,destroy)</li>
<li>인터셉트는 디스패처 서블릿이 컨트롤러를 호출하기 전과 후에 요청과 응답을 참조하거나 가공할 수 있는 기능
<img src="https://images.velog.io/images/j_user0719/post/71d446d8-fca2-49b2-b33f-6d64aef69d83/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-11-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.29.42.png" alt=""><h3 id="spring에서-cors-에러를-해결하기-위한-방법을-설명해주세요">Spring에서 CORS 에러를 해결하기 위한 방법을 설명해주세요.</h3>
</li>
</ol>
<ul>
<li><p>CrossOrigin 어노테이션 사용하기</p>
</li>
<li><p>WebMvcConfigurer 에서 설정하기</p>
</li>
<li><p>CorsFilter 생성하기(커스텀)</p>
</li>
</ul>
<h3 id="beancomponent-애노테이션에-대해서-설명해주시고-둘의-차이점에-대해-설명해주세요">Bean/Component 애노테이션에 대해서 설명해주시고, 둘의 차이점에 대해 설명해주세요.</h3>
<ul>
<li>공통점 : 둘 다 IoC 컨테이너에 빈으로 등록하기 위한 방법.</li>
<li>차이점 : @Bean은 개발자가 컨트롤 못하는 <strong>외부 라이브러리</strong>, @Component는 직접 컨트롤하는 <strong>클래스</strong></li>
</ul>
<h3 id="spring-web-mvc에서-요청-마다-thread가-생성되어-controller를-통해-요청을-수행할텐데-어떻게-1개의-controller만-생성될-수-있을까요">Spring Web MVC에서 요청 마다 Thread가 생성되어 Controller를 통해 요청을 수행할텐데, 어떻게 1개의 Controller만 생성될 수 있을까요?</h3>
<p>생성한 Controller 클래스에 대한 정보가 JVM 메모리 영역 중 &#39;메서드 영역&#39;에 올라가기 때문입니다. 객체는 힙에 생성 되지만, 해당 클래스의 정보는 메소드영역에 생성 됩니다. 그래서 결국 모든 쓰레드가 객체의 메서드를 공유할 수 있습니다.</p>
<h1 id="jpa">JPA</h1>
<h3 id="jpa란">JPA란?</h3>
<p>자바 인터페이스의 모음으로 자바의 ORM 기술 표준으로 DB와 스프링 프로젝트 중간에서 자동으로 매핑을 진행해주는 기술입니다.</p>
<h3 id="jpa-영속성-컨텍스트의-이점5가지을-설명해주세요">JPA 영속성 컨텍스트의 이점(5가지)을 설명해주세요.</h3>
<ul>
<li>1차 캐시 : 내부의 캐시에 엔티티를 저장할 수 있음</li>
<li>동일성 보장 : 엔티티의 동일성(주소와 값 모두..)을 보장해줌.</li>
<li>트랙잭션을 지원하는 쓰기 지연: 엔티티 매니저는 트랜잭션을 커밋하기 직전까지 내부 쿼리 저장소에 INSERT SQL을 모아 커밋할 때 모아둔 쿼리를 DB에 보냄.</li>
<li>변경 감지 : 엔티티 수정할 때는 단순히 엔티티를 조회해서 데이터를 변경하면 된다</li>
<li>지연 로딩 : <h3 id="jpa를-쓴다면-그-이유에-대해서-설명해주세요">JPA를 쓴다면 그 이유에 대해서 설명해주세요.</h3>
</li>
<li>패러다임 불일치를 대신 해결해줌 : SQL 맵핑의 중복과 반복 단점을 해결해준다. (상속, 연관관계, 객체 그래프 탐색, 비교)</li>
<li>SQL 중심적인 개발에서 객체 중심으로 개발 : 영속 계층과 관련된 로직을 컬렉션 다루듯이 사용할 수 있도록 해준다.</li>
<li>유지보수 -&gt; 필드만 추가하면 SQL은 JPA가 대신 처리</li>
<li>데이터 접근 추상화와 벤더 독립성</li>
<li>성능 최적화 (1차 캐싱, SQL 배치 요청, 지연 로딩)<h3 id="패러다임-불일치란">패러다임 불일치란?</h3>
</li>
</ul>
<p>객체와 RDB는 지향하는 목적이 다르기에 객체를 다루는 방식과 테이블을 다루는 방식간의 패러다임 불일치가 존재</p>
<ul>
<li>대표적인 불일치<ul>
<li>상속: 객체는 상속 O, DB는 X</li>
<li>방향성 : 객체는 단방향 . 테이블은 양방향</li>
</ul>
</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>