<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Luce In Altis</title>
        <link>https://velog.io/</link>
        <description>How R U Today :)</description>
        <lastBuildDate>Mon, 18 Jul 2022 01:19:04 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Luce In Altis</title>
            <url>https://images.velog.io/images/luna_0917/profile/146f5649-52df-480b-b910-528b232b2114/KakaoTalk_20220331_103430657.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Luce In Altis. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/luna_0917" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[자격증] Azure-900]]></title>
            <link>https://velog.io/@luna_0917/%EC%9E%90%EA%B2%A9%EC%A6%9D-Azure-900</link>
            <guid>https://velog.io/@luna_0917/%EC%9E%90%EA%B2%A9%EC%A6%9D-Azure-900</guid>
            <pubDate>Mon, 18 Jul 2022 01:19:04 GMT</pubDate>
            <description><![CDATA[<p>거창한거 없는 시험 후기</p>
<p>시험 30분전에 링크에 접속해서 내 사진과 시험 보는 장소 주변사진을 찍어 첨부하고 대기했다.
대기 후 인도사람인것 같은 감독관이 메시지를 보내왔고 곧 연결하겠다는 내용이었다. 감독관이 들어와서 이것저것 요청을 했는데 무슨말인지 알아듣기 어려웠다. 분명 모니터는 전원만 꺼져있으면 된다고 했는데 치워야 한다고 해서 침대 위에 책상펴고 시험 봤다. 그러던 와중에 갑자기 감독관이랑 연결이 끊어졌는데 연결이 불안정하다면서 대기열 맨뒤로 넘어갔다.....
5분인가 기다리고 다음 차례를 기다리고 있는데 연결이 불안정하다면서 다시 대기열로 넘어갔다^^
결국 시험은 원래 시간보다 10분 후에 진행이 되었다. 시험은 10분도 안걸려서 끝났다. 덤프에서 많이 나왔으며 문제는 36문제였다. 시험은 쉬운편이며 편하게 준비하고 시험에 응해도 될것같다. 
시험 후기를 기록하는 편은 아니지만 계속 대기열로 넘어가길래 검색했더니 후기가 없어서 기록해 본다. </p>
<h3 id="paas-saas-iaas-비교">Paas, Saas, Iaas 비교</h3>
<table>
<thead>
<tr>
<th></th>
<th>IaaS</th>
<th>PaaS</th>
</tr>
</thead>
<tbody><tr>
<td>서비스</td>
<td>- Azure Virtual Machines</td>
<td></td>
</tr>
<tr>
<td>- Azure Storage Account</td>
<td>- Azure App Service</td>
<td></td>
</tr>
<tr>
<td>- Microsoft SQL DB Server</td>
<td></td>
<td></td>
</tr>
<tr>
<td>- Azure Cosmos DB</td>
<td></td>
<td></td>
</tr>
<tr>
<td>- Azure Backup</td>
<td></td>
<td></td>
</tr>
<tr>
<td>특징</td>
<td>- 응용 프로그램에는 여러 필수 응용 프로그램과 서비스가 설치 되어 있음</td>
<td>- 행정적 노력을 최소화 하는 솔루션</td>
</tr>
<tr>
<td>- 운영 체제 완전한 제어 X</td>
<td></td>
<td></td>
</tr>
<tr>
<td>- 플랫폼을 자동으로 확장</td>
<td></td>
<td></td>
</tr>
</tbody></table>
<h3 id="리소스-그룹">리소스 그룹</h3>
<p>❌ 다른 리소스 그룹 내부에 리소스 그룹을 <del>생성할 수 있음</del></p>
<p>❌ Azure 가상 시스템은 여러 리소스 그룹에 <del>속할 수 있음</del></p>
<p>⭕ 리소스 그룹에는 <strong>여러 Azure영역의 리소스</strong>가 포함될 수 있음</p>
<h3 id="azure-active-directoryazure-ad">Azure Active Directory(Azure AD)</h3>
<p>⭕ Azure AD의 각 사용자 계정에는 <strong>하나의 라이선스만 할당 할 수 있음</strong></p>
<p>❌ Azure AD는 Azure 및 Microsoft365에서 호스팅되는 리소스에 대한 인증 서비스를 제공</p>
<p>❌ Azure AD는 Azure 가상 머신에 도메인 컨트롤러를 구현해야 함</p>
<p>⭕ <strong>온프레미스</strong> Active Directory에 저장된 ID를 Azure AD와 <strong>동기화 할 수 있음</strong></p>
<p>❌ Azure 리소스에 대한 액세스 권한은 Azure AD 사용자에게만 제공될 수 있음</p>
<p>⭕ <strong>Azure AD에서 그룹정책을 만들 수 있음</strong></p>
<p>❌ Android 기기 Azure AD에 가입 </p>
<p>Q. <strong>보안 토큰</strong>을 검색하나요?</p>
<p>A.  Azure AD</p>
<p>Q. 5000개의 사용자 게정, 모든 네트워크 리소르를 Azure로 마이크레이션,
사용자에게 미치는 영향 최소화</p>
<p>A. <strong>모든 Activate Directory 사용자 계정을 Azure AD에 동기화</strong></p>
<h3 id="구독">구독</h3>
<p>❌ Azure 구독을 <del>여러 Azure AD 테넌트에</del> 연결할 수 있습니다</p>
<p>⭕ <strong>Azure 구독이 연결된 Azure AD 테넌트를 변경할 수 있습니다</strong></p>
<p>❌ Azure  구독이 만료되면 관련 Azure Active Directory가 <del>자동으로 삭제됩니다.</del></p>
<h3 id="가상-머신-배포">가상 머신 배포</h3>
<p>여러 Azure 가상 머신을 배포할 계획입니다.</p>
<p>단일 데이터 센터가 실패할 경우 가상 머신에서 실행 중인 서비스를 사용할 수 있는지 확인</p>
<p>⭕ 가상 머신을 <strong>둘 이상의 지역에 배포</strong></p>
<p>❌ 가상 머신을 둘 이상의 리소스 그룹에 배포</p>
<p>❌ 가상 머신을 확장 집합에 배포</p>
<h3 id="azure-cloude-shell">Azure Cloude Shell</h3>
<p>⭕ Q.  <strong>Azure Portal</strong>에서 <strong>Azure Cloud Shell</strong>을 실행하고 <strong>PowerShell</strong>을 선택합니다. <strong>Cloud Shell</strong>에서 명령어를 실행합니다.</p>
<p>⭕  Q.  <strong>Windows 10</strong>을 실행하는 컴퓨터에서 <strong>Azure CLI</strong>를 설치합니다. <strong>명령 프롬프트</strong>에서 Azure에 로그인한 다음 명령을 실행합니다.</p>
<p>⭕ Q. <strong>MacOS</strong>를 실행하고 <strong>PoweShell Core 6.0이</strong> 설치된 컴퓨터에서 스크립트를 실행합니다.</p>
<p>⭕ Q. Chrome OS를 실행하고 Azure Cloud Shell을 사용하는 컴퓨터에서 스크립트를 실행합니다.</p>
<p>Q. Android <strong>랩톱</strong>에서 새 Azure <strong>가상 머신</strong>을 만들어야 합니다.</p>
<p>솔루션 : <strong>Azure Portal을 사용</strong>합니다.</p>
<p>A. Yes</p>
<p> ❌ Azure Cloud Shell에서 Bash를 사용합니다.</p>
<h3 id="cost">Cost</h3>
<p>운영비용 = OpEx</p>
<p>ex) 종량제 가격</p>
<p>자본비용 = CapEx</p>
<p>ex) 자체 데이터 센터</p>
<p>비용을 줄일 수 있는 경우</p>
<p>→ 10개의 공개 IP</p>
<p>Q. 서비스 중단으로 인해 리소스를 장기간 사용할 수 없게 됨</p>
<p>A. Microsoft가 Azure 계정에 크레딧을 제공, 자동으로 Azure 계정에 크레딧 제공</p>
<p>Q. 비용 관리가 필요한 것은?</p>
<p>A. 기업계약 (EA)</p>
<h3 id="문제"><strong>문제</strong></h3>
<p>Q. Azrue에 20TB의 데이터를 저장할 계획입니다. 데이터에 자주 엑세스 하지 않고 <strong>Microsoft PowerBI</strong> 를 사용하여 시각화합니다. 데이터에 대한 스토리지 솔루션 추천</p>
<p>A. <strong>Azure Data Lake, Azure SQL Data Warehouse</strong></p>
<p>Q. Azure 서비스에 대한 엑세스를 보호하기 위해 <strong>Azure 가용성 영역</strong>을 사용할 수 있는 오류 식별</p>
<p>A. <strong>Azure 데이터 센터 장애</strong></p>
<p>Q. <strong>온-프레미스 네트워크의 클라이언트 컴퓨터가 Azure 가상 머신과 통신</strong>할 수 있도록 하는 솔루션 구현할 계획입니다. 계획된 솔루션에 대해 생성해야 하는  Azure 리소스를 권장해햐 합니다. 권장 사항에 포함해야 하는 두 가지 Azure 리소스</p>
<p>A. <strong>가상 네트워크 게이트웨이, 게이트웨이 서브넷</strong></p>
<p>Q. 회사에서 여러 서버를  Azure로 이동할 계획, <strong>Finserver라는 서버가 별도의 네트워크 세그먼트에 있어야 한다</strong>고 명시, 어떤 솔루션 추천?</p>
<p><strong>A. FinServer를 위한 가상 네트워크와 다른 모든 서버를 위한 또 다른 가상 네트워크</strong></p>
<p>Q. Data thart is stored in the Archive access tier of an Azure Sotrage account__________.</p>
<p>A. <strong>must be rehydrated before the data can be accessed</strong></p>
<p>Q. Microsoft에서 Azure 구독에 배포된 리소스에 영향을 줄 수 있는 유지 관리를 수행할 계획인 경우 알림을 받아야 합니다.</p>
<p>A.  <strong>Azure Service Health</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CICD] Github ]]></title>
            <link>https://velog.io/@luna_0917/Github</link>
            <guid>https://velog.io/@luna_0917/Github</guid>
            <pubDate>Tue, 31 May 2022 03:11:53 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-git">✔️ Git</h3>
<p><strong>저장소 만들기</strong></p>
<p>버전관리를 하지 않는 로컬 디렉토리</p>
<pre><code class="language-shell">$ mkdir mygit
$ cd mygit</code></pre>
<pre><code class="language-shell">$ git init</code></pre>
<p><strong>기존 Git 저장소 클론</strong></p>
<pre><code class="language-shell">$ git clone &lt;URL&gt;</code></pre>
<h3 id="✔️-git-프로젝트의-세-가지-상태">✔️ Git 프로젝트의 세 가지 상태</h3>
<p><img src="https://git-scm.com/book/en/v2/images/areas.png" alt=""></p>
<h3 id="✔️-파일의-생명주기">✔️ 파일의 생명주기</h3>
<p><img src="https://git-scm.com/book/en/v2/images/lifecycle.png" alt=""></p>
<p><strong>상태 확인</strong></p>
<pre><code class="language-shell">$ git status</code></pre>
<p><strong>스테이징</strong></p>
<pre><code class="language-shell">$ git add &lt;FILE&gt;
$ git add .</code></pre>
<p><strong>.gitignore 파일</strong></p>
<ul>
<li>아무것도 없는 라인이나, <code>#</code>로 시작하는 라인은 무시한다.</li>
<li>표준 Glob 패턴을 사용한다. 이는 프로젝트 전체에 적용된다.</li>
<li>슬래시(/)로 시작하면 하위 디렉토리에 적용되지(Recursivity) 않는다.</li>
<li>디렉토리는 슬래시(/)를 끝에 사용하는 것으로 표현한다.</li>
<li>느낌표(!)로 시작하는 패턴의 파일은 무시하지 않는다.</li>
</ul>
<p><strong>Staged와 Unstaged 상태 변경 내용 보기</strong>
staged 상태가 아닌 파일 비교</p>
<pre><code class="language-shell">$ git diff</code></pre>
<p>커밋과 staged 상태 비교</p>
<pre><code class="language-shell">$ git diff --staged</code></pre>
<p><strong>변경사항 커밋(버저닝, 스냅샷)</strong></p>
<pre><code class="language-shell">$ git commit</code></pre>
<blockquote>
<p>기본 에디터 변경
<code>git config --global core.editor &lt;EDITOR&gt;</code></p>
</blockquote>
<p><strong>인라인 메시지</strong></p>
<pre><code class="language-shell">$ git commit -m &lt;MESSAGE&gt;</code></pre>
<p><strong>스테이징 및 인라인 메시지</strong></p>
<pre><code class="language-shell">$ git commit -a -m &lt;MESSAGE&gt;</code></pre>
<p><strong>좋은 Commit 메시지</strong></p>
<blockquote>
<p><a href="https://gist.github.com/robertpainsi/b632364184e70900af4ab688decf6f53">https://gist.github.com/robertpainsi/b632364184e70900af4ab688decf6f53</a></p>
</blockquote>
<p><strong>파일 삭제</strong></p>
<pre><code class="language-shell">$ rm &lt;FILE&gt;</code></pre>
<p><strong>삭제한 파일 Staged 상태</strong></p>
<pre><code class="language-shell">$ git rm &lt;FILE&gt;</code></pre>
<p><strong>파일명 변경</strong></p>
<pre><code class="language-shell">$ git mv &lt;ORGION&gt; &lt;NEWFILE&gt;</code></pre>
<p><strong>커밋 히스토리/로그</strong></p>
<pre><code class="language-shell">$ git log</code></pre>
<blockquote>
<p>로그 출력 변경
<code>git config --global core.pager &#39;less&#39;</code>
<code>git config --global core.pager &#39;&#39;</code></p>
</blockquote>
<pre><code class="language-shell">$ git log --oneline</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloude] AWS EKS]]></title>
            <link>https://velog.io/@luna_0917/Cloude-AWS-EKS</link>
            <guid>https://velog.io/@luna_0917/Cloude-AWS-EKS</guid>
            <pubDate>Mon, 30 May 2022 12:22:30 GMT</pubDate>
            <description><![CDATA[<h2 id="✔️-aws-eks">✔️ AWS EKS</h2>
<ul>
<li>Amazon Elastic Kubernetes Service(Amazon EKS)</li>
<li>EKS는 Kubernetes를 실행하는 데 사용할 수 있는 <strong>관리형 서비스</strong>이다.</li>
<li>노드를 설치, 작동 및 유지 관리할 필요가 없다는 장점</li>
</ul>
<p><img src="https://velog.velcdn.com/images/luna_0917/post/9929f5a3-805c-4b7d-894c-8fd97eca70a4/image.png" alt=""></p>
<blockquote>
<p><a href="https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/what-is-eks.html">https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/what-is-eks.html</a></p>
</blockquote>
<h3 id="✔️-aws-eks-사용해보기">✔️ AWS EKS 사용해보기</h3>
<pre><code class="language-shell">$ choco install awscli aws-iam-authenticator eksctl kubernetes-helm</code></pre>
<p>aws 계정 등록</p>
<pre><code class="language-shell">$ aws configure</code></pre>
<pre><code class="language-shell">$ eksctl create cluster --name myeks --nodes=3 --region=ap-northeast-2</code></pre>
<p>⭐ Load Balancer Service ❌ = class lb로생성되기 때문에 nlb로 변경해주어야함
⭐ Ingress: ❌</p>
<h3 id="✔️-yaml-파일을-이용해서-eks-배포하기">✔️ YAML 파일을 이용해서 EKS 배포하기</h3>
<pre><code class="language-shell">$ mkdir aws-eks
$ cd aws-eks</code></pre>
<p><code>myeks.yaml</code></p>
<pre><code class="language-yaml">apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: myeks-custom  # 이름은 같을 수 없다
  region: ap-northeast-2
  version: &quot;1.22&quot;</code></pre>
<p>가용영역 지정
    - 필수는 아니나 일반적으로 지정하는 편</p>
<pre><code class="language-yaml"># AZ
availabilityZones: [&quot;ap-northeast-2a&quot;, &quot;ap-northeast-2b&quot;,  &quot;ap-northeast-2c&quot;]</code></pre>
<p>eks와 AWS iam계정을 연결 해 주는 부분
wellKnownPolicies : 계정에 해당되는 기본적인 권한 설정</p>
<pre><code class="language-yaml"># IAM OIDC &amp; Service Account
iam:
  withOIDC: true
  serviceAccounts:
    - metadata:
        name: aws-load-balancer-controller # Addon 추가할 때 필요
        namespace: kube-system
      wellKnownPolicies:
        awsLoadBalancerController: true
    - metadata:
        name: ebs-csi-controller-sa
        namespace: kube-system
      wellKnownPolicies:
        ebsCSIController: true
    - metadata:
        name: cluster-autoscaler
        namespace: kube-system
      wellKnownPolicies:
        autoScaler: true</code></pre>
<p>Worker노드의 그룹</p>
<pre><code class="language-yaml"># Managed Node Groups
managedNodeGroups:
  # On-Demand Instance
  - name: myeks-ng1
    instanceType: t3.medium
    minSize: 2
    desiredCapacity: 3
    maxSize: 4
    privateNetworking: true
    ssh:
      allow: true
      publicKeyPath: ./keypair/myeks.pub
    availabilityZones: [&quot;ap-northeast-2a&quot;, &quot;ap-northeast-2b&quot;, &quot;ap-northeast-2c&quot;]
    iam:
      withAddonPolicies:
        autoScaler: true
        albIngress: true
        cloudWatch: true
        ebs: true</code></pre>
<pre><code class="language-yaml"># Fargate Profiles
fargateProfiles:
  - name: fg-1
    selectors:
    - namespace: dev
      labels:
        env: fargate
</code></pre>
<pre><code class="language-yaml"># CloudWatch Logging
cloudWatch:
  clusterLogging:
    enableTypes: [&quot;*&quot;]
</code></pre>
<p>키 생성</p>
<pre><code class="language-shell">$ mkdir keypair
$ ssh-keygen -f keypair/myssh</code></pre>
<pre><code class="language-shell">$ eksctl create cluster -f myeks.yaml</code></pre>
<h2 id="✔️-nlb-for-loadbalancer-service">✔️ NLB for LoadBalancer Service</h2>
<h3 id="✔️-aws-load-balancer-controller-설치">✔️ AWS Load Balancer Controller 설치</h3>
<pre><code class="language-shell">$ helm repo add eks https://aws.github.io/eks-charts
$ helm repo update</code></pre>
<p>Account 확인</p>
<pre><code class="language-shell">$ aws sts get-caller-identity
{
    &quot;UserId&quot;: &quot;AIxxx&quot;,
    &quot;Account&quot;: &quot;4xxx&quot;,
    &quot;Arn&quot;: &quot;arn:aws:iam::4xxx&quot;
}</code></pre>
<pre><code class="language-shell">$ helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=myeks-lunaris --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller --set image.repository=[account]412059376128.dkr.ecr.ap-northeast-2.amazonaws.com/amazon/aws-load-balancer-controller

NAME: aws-load-balancer-controller
LAST DEPLOYED: Mon May 30 20:56:35 2022
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
AWS Load Balancer controller installed!</code></pre>
<p>샘플 코드
<code>myapp.yaml</code></p>
<pre><code class="language-yaml">apiVersion: apps/v1
kind: Deployment
metadata:
  name: myweb-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: myweb
          image: ghcr.io/c1t1d0s7/go-myweb
          ports:
            - containerPort: 8080</code></pre>
<p>`mysvc.yaml</p>
<pre><code class="language-yaml">apiVersion: v1
kind: Service
metadata:
  name: myweb-svc-lb
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: &quot;external&quot;
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: &quot;instance&quot;
    service.beta.kubernetes.io/aws-load-balancer-scheme: &quot;internet-facing&quot;
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8080</code></pre>
<h2 id="✔️-ingress-for-alb">✔️ Ingress for ALB</h2>
<pre><code class="language-yaml">apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myweb-ing
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/target-type: instance
    alb.ingress.kubernetes.io/scheme: internet-facing
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: myweb-svc-lb
                port:
                  number: 80</code></pre>
<ul>
<li>alb.ingress.kubernetes.io/target-type<ul>
<li>instance: EC2 타겟</li>
<li>ip: Pod 타겟(Fargate)</li>
</ul>
</li>
<li>alb.ingress.kubernetes.io/scheme<ul>
<li>internal: 내부</li>
<li>internet-facing: 외부</li>
</ul>
</li>
</ul>
<h2 id="✔️-ebs-for-csi">✔️ EBS for CSI</h2>
<p>EBS 스냅샷
EBS 크기 변경</p>
<pre><code class="language-shell">$ eksctl get iamserviceaccount --cluster myeks-custom

NAMESPACE       NAME                            ROLE ARN
kube-system     aws-load-balancer-controller    arn:aws:iam::xxxxx:role/eksctl-myeks-custom-addon-iamserviceaccount-Role1-11N0OKMVG2DYY
kube-system     aws-node                        arn:aws:iam::xxxx:role/eksctl-myeks-custom-addon-iamserviceaccount-Role1-CLMK7A6K5NL3
kube-system     cluster-autoscaler              arn:aws:iam::xxxx:role/eksctl-myeks-custom-addon-iamserviceaccount-Role1-1S02W28MZOSL4
kube-system     ebs-csi-controller-sa           arn:aws:iam::xxxx:role/eksctl-myeks-custom-addon-iamserviceaccount-Role1-15HLE8HBOD9CN</code></pre>
<pre><code class="language-shell">$ eksctl create addon --name aws-ebs-csi-driver --cluster myeks-lunaris--service-account-role-arn  arn:aws:iam::xxxx:role/eksctl-myeks-lunaris-addon-iamserviceaccount-Role1-15HLE8HBOD9CN --force</code></pre>
<h2 id="✔️-metrics-server">✔️ Metrics Server</h2>
<pre><code class="language-shell">$ kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml</code></pre>
<h2 id="✔️-cluster-autoscaler">✔️ Cluster Autoscaler</h2>
<h5 id="✔️-수동-스케일링">✔️ 수동 스케일링</h5>
<pre><code class="language-shell">$ eksctl scale nodegroup --name myeks-ng1 --cluster myeks-lunaris --nodes 2</code></pre>
<h5 id="✔️자동-스케일링">✔️자동 스케일링</h5>
<pre><code class="language-shell">$ curl -o cluster-autoscaler-autodiscover.yaml https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml</code></pre>
<p><code>cluster-autoscaler-autodiscover.yaml</code></p>
<pre><code class="language-yaml">...
163: - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/myeks-lunaris
...</code></pre>
<pre><code class="language-shell">$ kubectl apply -f cluster-autoscaler-autodiscover.yaml</code></pre>
<pre><code class="language-shell">$ kubectl patch deployment cluster-autoscaler -n kube-system -p &#39;{&quot;spec&quot;:{&quot;template&quot;:{&quot;metadata&quot;:{&quot;annotations&quot;:{&quot;cluster-autoscaler.kubernetes.io/safe-to-evict&quot;: &quot;false&quot;}}}}}&#39;</code></pre>
<pre><code class="language-shell">$ kubectl -n kube-system edit deployment.apps/cluster-autoscaler</code></pre>
<pre><code class="language-shell">      - command:
        - ./cluster-autoscaler
        - --v=4
        - --stderrthreshold=info
        - --cloud-provider=aws
        - --skip-nodes-with-local-storage=false
        - --expander=least-waste
        - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/myeks-custom
        - --balance-similar-node-groups
        - --skip-nodes-with-system-pods=false
        image: k8s.gcr.io/autoscaling/cluster-autoscaler:v1.22.6</code></pre>
<p>수정</p>
<ul>
<li>--node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/myeks-custom</li>
<li>--balance-similar-node-groups</li>
<li>--skip-nodes-with-system-pods=false</li>
<li>image: k8s.gcr.io/autoscaling/cluster-autoscaler:v1.22.2</li>
</ul>
<pre><code class="language-shell">$ kubectl set image deployment cluster-autoscaler -n kube-system cluster-autoscaler=k8s.gcr.io/autoscaling/cluster-autoscaler:v1.22.2</code></pre>
<p>샘플 코드</p>
<pre><code class="language-yaml">apiVersion: apps/v1
kind: Deployment
metadata:
  name: myweb-deploy
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: myweb
          image: ghcr.io/c1t1d0s7/go-myweb:alpine
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: 200m
              memory: 200M
            limits:
              cpu: 200m
              memory: 200M</code></pre>
<h2 id="✔️cloudwatch-container-insight">✔️CloudWatch Container Insight</h2>
<pre><code class="language-shell">ClusterName=myeks-custom
RegionName=ap-northeast-2
FluentBitHttpPort=&#39;2020&#39;
FluentBitReadFromHead=&#39;Off&#39;
[[ ${FluentBitReadFromHead} = &#39;On&#39; ]] &amp;&amp; FluentBitReadFromTail=&#39;Off&#39;|| FluentBitReadFromTail=&#39;On&#39;
[[ -z ${FluentBitHttpPort} ]] &amp;&amp; FluentBitHttpServer=&#39;Off&#39; || FluentBitHttpServer=&#39;On&#39;
curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/quickstart/cwagent-fluent-bit-quickstart.yaml | sed &#39;s/{{cluster_name}}/&#39;${ClusterName}&#39;/;s/{{region_name}}/&#39;${RegionName}&#39;/;s/{{http_server_toggle}}/&quot;&#39;${FluentBitHttpServer}&#39;&quot;/;s/{{http_server_port}}/&quot;&#39;${FluentBitHttpPort}&#39;&quot;/;s/{{read_from_head}}/&quot;&#39;${FluentBitReadFromHead}&#39;&quot;/;s/{{read_from_tail}}/&quot;&#39;${FluentBitReadFromTail}&#39;&quot;/&#39; | kubectl apply -f - </code></pre>
<h2 id="✔️-클러스터-삭제">✔️ 클러스터 삭제</h2>
<pre><code>eksctl delete cluster -f .\myeks.yaml --force --disable-nodegroup-eviction</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloude] Window10에서 minikube 사용]]></title>
            <link>https://velog.io/@luna_0917/Cloude-Window10%EC%97%90%EC%84%9C-minikube-%EC%82%AC%EC%9A%A9</link>
            <guid>https://velog.io/@luna_0917/Cloude-Window10%EC%97%90%EC%84%9C-minikube-%EC%82%AC%EC%9A%A9</guid>
            <pubDate>Mon, 30 May 2022 10:21:30 GMT</pubDate>
            <description><![CDATA[<h2 id="✔️-minikube">✔️ Minikube</h2>
<p><strong>minikube란?</strong>
minikube는 로컬에서 Kubernetes를 실행하는데 사용할 수 있는 유틸리티이다.
이 클러스터를 쿠버네티스를 설치하는 시간과 리소스 소모를 절약할수 있다. </p>
<h3 id="✔️-minikube-기본-활용">✔️ Minikube 기본 활용</h3>
<p>⭐ Window powershell에서 실행한 것이다. </p>
<p><strong>minikube 설치</strong></p>
<pre><code class="language-shell">$ choco install minikube</code></pre>
<pre><code class="language-shell">$ choco install kubernetes-cli --version=1.22.4</code></pre>
<p><strong>클러스터 생성 및 실행</strong></p>
<pre><code class="language-shell">$ minikube start</code></pre>
<p><strong>클러스터 중지</strong></p>
<pre><code class="language-shell">$ minikube stop</code></pre>
<p><strong>클러스터 상태</strong></p>
<pre><code class="language-shell">$ minikube status</code></pre>
<p><strong>VM 접속</strong></p>
<pre><code class="language-shell">$ minikube ssh</code></pre>
<h4 id="⭐-minikube-가-생성한-vm--docker-명령⭕-패키지-관리자❌-kubectl-명령❌">⭐ minikube 가 생성한 vm : docker 명령⭕ 패키지 관리자❌ kubectl 명령❌</h4>
<h3 id="✔️-vm-내의-docker-engine-사용하기">✔️ VM 내의 Docker Engine 사용하기</h3>
<p><strong>윈도우에 도커 명령어 설치</strong>
    - 서버 설치 아님</p>
<pre><code class="language-shell">$ choco install docker-cli</code></pre>
<p>powershell에서의 적용 시켜야 할 환경 변수</p>
<pre><code class="language-shell"> minikube docker-env
$Env:DOCKER_TLS_VERIFY = &quot;1&quot;
$Env:DOCKER_HOST = &quot;tcp://192.168.59.103:2376&quot;
$Env:DOCKER_CERT_PATH = &quot;C:\Users\kiki1\.minikube\certs&quot;
$Env:MINIKUBE_ACTIVE_DOCKERD = &quot;minikube&quot;
# To point your shell to minikube&#39;s docker-daemon, run:
# &amp; minikube -p minikube docker-env --shell powershell | Invoke-Expression</code></pre>
<p>*<em>환경 변수 적용 *</em></p>
<pre><code class="language-shell">$ minikube -p minikube docker-env --shell powershell | Invoke-Expression</code></pre>
<blockquote>
<p>터미널 닫으면  다시 적용 시켜주어야 한다</p>
</blockquote>
<p><strong>추가 옵션을 적용한 클러스터 생성/시작</strong></p>
<pre><code class="language-shell">$ minikube start --cpus 4 --memory 4G --disk-size 30G --driver virtualbox --kubernetes-version v1.22.9</code></pre>
<p><strong>노드 추가</strong></p>
<pre><code class="language-shell">$ minikube node list
$ minikube node add</code></pre>
<p><strong>서비스 목록 확인</strong></p>
<pre><code class="language-shell">$ minikube service list</code></pre>
<p><strong>애드온</strong></p>
<pre><code class="language-shell">$ minikube addons list</code></pre>
<pre><code class="language-shell">$ minikube addons enable metrics-server
$ minikube addons enable ingress</code></pre>
<pre><code class="language-shell">$ minikube addons configure metallb

-- Enter Load Balancer Start IP: 192.168.X.200
-- Enter Load Balancer End IP: 192.168.X.209</code></pre>
<p><strong>클러스터 기본 옵션 지정</strong></p>
<pre><code class="language-shell">$ minikube config set cpus 2
$ minikube config set memory 4G
$ minikube config set driver virtualbox
$ minikube config set kubernetes-version v1.22.9
$ minikube config view</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloude] Monitoring & Logging]]></title>
            <link>https://velog.io/@luna_0917/Cloude-Monitoring-Logging</link>
            <guid>https://velog.io/@luna_0917/Cloude-Monitoring-Logging</guid>
            <pubDate>Fri, 27 May 2022 12:22:03 GMT</pubDate>
            <description><![CDATA[<h2 id="✔️-monitoring--logging">✔️ Monitoring &amp; Logging</h2>
<h3 id="✔️-prometheus-monitoring">✔️ Prometheus Monitoring</h3>
<p><img src="https://prometheus.io/assets/architecture.png" alt=""></p>
<pre><code class="language-shell">$ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
$ helm update</code></pre>
<p><code>prom-value.yaml</code></p>
<pre><code class="language-yaml">grafana:
  service:
    type: LoadBalancer</code></pre>
<pre><code class="language-shell">$ kubectl create ns monitor</code></pre>
<pre><code class="language-shell">$ helm install prom prometheus-community/kube-prometheus-stack -f prom-value.yaml -n monitor</code></pre>
<h3 id="✔️efk-logging">✔️EFK Logging</h3>
<p>ELK Stack: Elasticsearch + Logstash + Kibana 
<strong>EFK Stack</strong>: Elasticsearch + Fluentd + Kibana
    Elasticsearch +  Fluent Bit + Kibana
Elastic Stack: Elasticsearch + Beat + Kibana</p>
<h3 id="✔️-elasticsearch">✔️ Elasticsearch</h3>
<pre><code class="language-shell">$ helm repo add elastic https://helm.elastic.co
$ helm repo update</code></pre>
<pre><code class="language-shell">$ helm show values elastic/elasticsearch &gt; es-value.yaml</code></pre>
<p><code>es-value.yaml</code></p>
<pre><code> 18 replicas: 1
 19 minimumMasterNodes: 1

 80 resources:
 81   requests:
 82     cpu: &quot;500m&quot;
 83     memory: &quot;1Gi&quot;
 84   limits:
 85     cpu: &quot;500m&quot;
 86     memory: &quot;1Gi&quot;</code></pre><pre><code class="language-shell">$ kubectl create ns logging</code></pre>
<pre><code class="language-shell">$ helm install elastic elastic/elasticsearch -f es-value.yaml -n logging</code></pre>
<h3 id="✔️-fluent-bit">✔️ Fluent Bit</h3>
<blockquote>
<p><a href="https://github.com/fluent/fluent-bit-kubernetes-logging">https://github.com/fluent/fluent-bit-kubernetes-logging</a></p>
</blockquote>
<pre><code class="language-shell">$ git clone https://github.com/fluent/fluent-bit-kubernetes-logging.git</code></pre>
<pre><code class="language-shell">$ cd  fluent-bit-kubernetes-logging</code></pre>
<pre><code class="language-shell">$ kubectl create -f fluent-bit-service-account.yaml
$ kubectl create -f fluent-bit-role-1.22.yaml
$ kubectl create -f fluent-bit-role-binding-1.22.yaml</code></pre>
<pre><code class="language-shell">$ kubectl create -f output/elasticsearch/fluent-bit-configmap.yaml</code></pre>
<p><code>output/elasticsearch/fluent-bit-ds.yaml</code></p>
<pre><code class="language-yaml"> 32         - name: FLUENT_ELASTICSEARCH_HOST
 33           value: &quot;elasticsearch-master&quot;</code></pre>
<pre><code class="language-shell">$ kubectl create -f output/elasticsearch/fluent-bit-ds.yaml</code></pre>
<h3 id="✔️-kibana">✔️ Kibana</h3>
<pre><code class="language-shell">$ helm show values elastic/kibana &gt; kibana-value.yaml</code></pre>
<p><code>kibana-value.yaml</code></p>
<pre><code class="language-yaml"> 49 resources:
 50   requests:
 51     cpu: &quot;500m&quot;
 52     memory: &quot;1Gi&quot;
 53   limits:
 54     cpu: &quot;500m&quot;
 55     memory: &quot;1Gi&quot;

119 service:
120   type: LoadBalancer</code></pre>
<pre><code class="language-shell">$ helm install kibana elastic/kibana -f kibana-value.yaml -n logging</code></pre>
<p><a href="http://192.168.100.X:5601">http://192.168.100.X:5601</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloude] Helm]]></title>
            <link>https://velog.io/@luna_0917/Cloude-Helm</link>
            <guid>https://velog.io/@luna_0917/Cloude-Helm</guid>
            <pubDate>Fri, 27 May 2022 11:24:36 GMT</pubDate>
            <description><![CDATA[<h2 id="✔️-helm">✔️ Helm</h2>
<p>Version 3사용</p>
<h3 id="✔️-helm-설치하기">✔️ Helm 설치하기</h3>
<pre><code class="language-shell">$ curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg &gt; /dev/null</code></pre>
<pre><code class="language-shell">$ sudo apt-get install apt-transport-https --yes</code></pre>
<pre><code class="language-shell">$ echo &quot;deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main&quot; | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list</code></pre>
<pre><code class="language-shell">$ sudo apt-get update
$ sudo apt-get install helm</code></pre>
<p><code>~/.zshrc</code>
자동완성 기능 추가</p>
<pre><code>...
plugins=
        (git
        zsh-autosuggestions
        zsh-completions
        kubectl
        helm
        )
...</code></pre><blockquote>
<p>Helm Chart 검색
<a href="https://artifacthub.io/">https://artifacthub.io/</a></p>
</blockquote>
<p><strong>차트 구조</strong></p>
<pre><code>&lt;Chart Name&gt;/
  Chart.yaml
  values.yaml
  templates/</code></pre><ul>
<li>Chart.yaml: 차트의 메타데이타</li>
<li>values.yaml: 패키지를 커스터마이즈/사용자화</li>
<li>templates: YAML 오브젝트 파일</li>
</ul>
<h3 id="✔️-helm-사용법">✔️ helm 사용법</h3>
<p>aritifacthub 검색</p>
<pre><code class="language-shell">$  helm search hub &lt;PATTERN&gt;</code></pre>
<p><strong>저장소 추가하기</strong></p>
<pre><code class="language-shell">$ helm repo add worepress https://charts.bitnami.com/bitnami</code></pre>
<pre><code class="language-shell">$ helm repo list
NAME            URL
worepress       https://charts.bitnami.com/bitnami</code></pre>
<p><strong>저장소 검색하기</strong></p>
<pre><code class="language-shell">$ helm search repo wordpress</code></pre>
<p><strong>차트 설치하기</strong></p>
<pre><code class="language-shell">$ helm install [NAME] [CHART] [flags] </code></pre>
<p><strong>릴리즈 확인</strong></p>
<pre><code class="language-shell">$ helm list</code></pre>
<p><strong>릴리즈 삭제</strong></p>
<pre><code class="language-shell">$ helm uninstall mywordpress</code></pre>
<p><strong>차트 정보 확인</strong></p>
<pre><code class="language-shell">$ helm show readme [Chart]/wordpress
$ helm show chart [Chart]/wordpress
$ helm show values [Chart]/wordpress</code></pre>
<p><strong>차트 사용자화</strong></p>
<pre><code class="language-shell">$ helm install mywp [Chart]/wordpress --set replicaCount=2
$ helm install mywp [Chart]/wordpress --set replicaCount=2 --set service.type=NodePort</code></pre>
<p><strong>릴리즈 업그레이드</strong></p>
<pre><code class="language-shell">$ helm show value [Chart]/wordpress &gt; wp-value.yaml
파일 수정</code></pre>
<pre><code class="language-shell">$ helm upgrade mywp [Chart]/wordpress -f wp-value.yaml</code></pre>
<p><strong>릴리즈 업그레이드 히스토리</strong></p>
<pre><code class="language-shell">$ helm history mywp</code></pre>
<p><strong>릴리즈 롤백</strong></p>
<pre><code class="language-shell">$ helm rollback mywp 1</code></pre>
<p><code>wp-value2.yaml</code></p>
<pre><code class="language-yaml">replicaCount: 1

service:
  type: LoadBalancer</code></pre>
<pre><code class="language-shell">$ helm upgrade mywp bitnami/wordpress -f wp-value2.yaml</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Clolude] Powerlevel10k와 kubectx & kubens]]></title>
            <link>https://velog.io/@luna_0917/Clolude-Powerlevel10k%EC%99%80-kubectx-kubens</link>
            <guid>https://velog.io/@luna_0917/Clolude-Powerlevel10k%EC%99%80-kubectx-kubens</guid>
            <pubDate>Fri, 27 May 2022 10:43:16 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-powerlevel10k">✔️ Powerlevel10k</h3>
<pre><code class="language-shell">git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k</code></pre>
<p><code>~/.zshrc</code></p>
<pre><code>ZSH_THEME=&quot;powerlevel10k/powerlevel10k&quot;</code></pre><pre><code>exec zsh</code></pre><pre><code>p10k configure</code></pre><h2 id="✔️-kubectx--kubens">✔️ kubectx &amp; kubens</h2>
<p>거의 필수처럼 사용하는 프로그램</p>
<p><strong>kubectx</strong>
다중 클러스터를 사용할 때 클러스터 전환을 쉽게 해주는 툴</p>
<p><strong>kubens</strong>
k8s 클러스터 내에서 namespace를 쉽게 전환해주는 툴</p>
<blockquote>
<p><a href="https://github.com/ahmetb/kubectx">https://github.com/ahmetb/kubectx</a></p>
</blockquote>
<pre><code class="language-shell">wget https://github.com/ahmetb/kubectx/releases/download/v0.9.4/kubectx</code></pre>
<pre><code class="language-shell">wget https://github.com/ahmetb/kubectx/releases/download/v0.9.4/kubens</code></pre>
<p>install 명령어</p>
<ul>
<li>기본 설치 파일 지정<pre><code class="language-shell">sudo install kubectx /usr/local/bin
sudo install kubens /usr/local/bin</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloude] k8s- workload Resource = Controller]]></title>
            <link>https://velog.io/@luna_0917/Cloude-k8s-workload</link>
            <guid>https://velog.io/@luna_0917/Cloude-k8s-workload</guid>
            <pubDate>Wed, 18 May 2022 03:55:45 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-workload-resource--controller">✔️ Workload Resource = Controller</h3>
<p>파드의 집합</p>
<h3 id="✔️-replicationcontroller">✔️ ReplicationController</h3>
<ul>
<li>파드의 복제본 개수 관리</li>
<li>컨트롤러에 의해서 관리되는 파드는 <strong>label</strong>이 붙어있어야함</li>
</ul>
<p><code>myweb-rc.yaml</code></p>
<pre><code class="language-yaml">apiVersion: v1
kind: ReplicationController
metadata:
  name: myweb-rc
spec:
  replicas: 3
  selector:
    app: web
# Pod Configure
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: myweb
          image: ghcr.io/c1t1d0s7/go-myweb
          ports:
            - containerPort: 8080
              protocol: TCP</code></pre>
<pre><code class="language-shell">$ kubectl create -f myweb-rc.yaml</code></pre>
<pre><code class="language-shell">$ watch kubectl get rc,pods --show-labels -o wide

NAME                 READY   STATUS    RESTARTS   AGE   LABELS
pod/myweb-rc-7m4v7   1/1     Running   0          29m   app=web
pod/myweb-rc-7s4vp   1/1     Running   0          78m   app=web
pod/myweb-rc-jtq7d   1/1     Running   0          78m   app=web</code></pre>
<pre><code class="language-shell">$ kubectl label pod myweb-rc-jtq7d app=db --overwrite</code></pre>
<pre><code class="language-shell">$ kubectl label pod myweb-rc-jtq7d app=web --overwrite</code></pre>
<h3 id="✔️-rc-스케일링">✔️ RC 스케일링</h3>
<p>명령형 커맨드</p>
<pre><code class="language-shell">$ kubectl scale rc myweb-rc --replicas=5</code></pre>
<p>명령형 오브젝트 구성</p>
<pre><code class="language-shell">$ kubectl replace -f myweb-rc.yaml</code></pre>
<pre><code class="language-shell">$ kubectl patch -f myweb-rc.yaml -p &#39;{&quot;spec&quot;: {&quot;replicas&quot;: 3}}&#39;
$ kubectl patch rc myweb-rc.yaml --patch-file replicas.json</code></pre>
<p><code>replicas.json</code></p>
<pre><code class="language-json">{&quot;spec&quot;: {&quot;replicas&quot;: 3}}</code></pre>
<pre><code class="language-shell">$ kubectl edit -f myweb-rc.yaml
$ kubectl edit rc myweb-rc
$ kubectl edit rc/myweb-rc</code></pre>
<p>선언형 오브젝트 구성</p>
<pre><code class="language-shell">$ kubectl apply -f myweb-rc.yaml</code></pre>
<h3 id="✔️-replicasets">✔️ ReplicaSets</h3>
<p>ReplicationController -&gt; ReplicaSets</p>
<pre><code class="language-yaml">apiVersion: apps/v1
kind: ReplicaSets
metadata:
  name: myweb-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
      env: dev
  template:
    metadata:
      labels:
        app: web
        env: dev
    spec:
      containers:
        - name: myweb
          image: ghcr.io/c1t1d0s7/go-myweb
          ports:
            - containerPort: 8080
              protocol: TCP
</code></pre>
<pre><code class="language-yaml">apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myweb-rs-set
spec:
  replicas: 3
  selector:
    matchExpressions:
      - key: app
        operator: In
        values: 
          - web
      - key: env
        operator: Exists
  template:
    metadata:
      labels:
        app: web
        env: dev
    spec:
      containers:
        - name: myweb
          image: ghcr.io/c1t1d0s7/go-myweb
          ports:
            - containerPort: 8080
              protocol: TCP
</code></pre>
<pre><code class="language-shell">$ cd ~/kubespray</code></pre>
<h3 id="✔️-job">✔️ Job</h3>
<p>파드가 성공적으로 종료될 때까지 계속해서 파드를 실행한다
<strong>안전한 종료를 보장</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloude] k8s - Pod Lifecycle/Lifetime]]></title>
            <link>https://velog.io/@luna_0917/Cloude-k8s-Pod-LifecycleLifetime</link>
            <guid>https://velog.io/@luna_0917/Cloude-k8s-Pod-LifecycleLifetime</guid>
            <pubDate>Wed, 18 May 2022 03:08:14 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-pod-상태">✔️ pod 상태</h3>
<p><strong>Pending</strong>
스케줄링 되기 전, 이미지 받기 전, 컨테이너가 준비 되기 전
<strong>Running</strong>
컨테이너가 실행 중, 실행 전, 재시작 중
<strong>Succeed</strong>
정상 종료(0)
<strong>Failed</strong>
비정상 종류(!0)
<strong>Unknown</strong>
노드의 통신 문제로 상태 알 수 없음</p>
<h3 id="✔️-container-상태">✔️ Container 상태</h3>
<p>Waiting : 이미지 받기 전, 볼륨 연결 되기 전
Running : 실행 중
Terminated :  종료</p>
<h3 id="✔️-재시작-정책">✔️ 재시작 정책</h3>
<p><strong>pod.spec.restartPolicy</strong>
Always(기본)
OnFailure
Never</p>
<p><strong>지수 백오프</strong>
파드 실패시 재시작 정책에 의해 재시작
재시작 시간 10,20,40, ...300 초까지 유예기간</p>
<h3 id="✔️-컨테이너-프로브">✔️ 컨테이너 프로브</h3>
<p><strong>프로브 종류</strong></p>
<ul>
<li>liveness<ul>
<li>애플리케이션 실행, 작동 여부</li>
</ul>
</li>
<li>readiness</li>
<li>startup<ul>
<li>애플리케이션이 시작 되었는지를 나타냄</li>
<li>성공할 때까지 나머지 프로브는 <strong>비활성화</strong></li>
</ul>
</li>
</ul>
<p><strong>프로브 매커니즘</strong></p>
<ul>
<li>httpGet<ul>
<li>Web, WepApp</li>
<li>응답 코드 2XX, 3XX</li>
</ul>
</li>
<li>tcpSocket<ul>
<li>해당 포트 TCP 연결</li>
</ul>
</li>
<li>grpc<ul>
<li>grpc 프로토콜 연결 </li>
</ul>
</li>
<li>exec<ul>
<li>명령 실행</li>
<li>종료 코드 0@</li>
</ul>
</li>
</ul>
<p><strong>프로브 결과</strong>
success
failuer
unknown</p>
<p><code>pods.spec.containers.livenessProbe</code></p>
<ul>
<li>exec</li>
<li>httpGet</li>
<li>tcpSocket</li>
<li>periodSeconds: 프로브 주기</li>
<li>failureThreshold: 실패 임계값</li>
<li>successThreshold: 성공 임계값</li>
<li>initialDelaySecond: 프로브 유예 기간</li>
<li>timeoutSeconds: 프로브 타임아웃</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloude] k8s - Label & LabelSelector ]]></title>
            <link>https://velog.io/@luna_0917/Cloude-k8s-Label-LabelSelector</link>
            <guid>https://velog.io/@luna_0917/Cloude-k8s-Label-LabelSelector</guid>
            <pubDate>Tue, 17 May 2022 13:15:36 GMT</pubDate>
            <description><![CDATA[<h2 id="✔️-label">✔️ Label</h2>
<p>레이블 확인</p>
<pre><code>$ kubectl get pods --show-labels</code></pre><pre><code>$ kubectl get pods X -o yaml</code></pre><pre><code>$ kubectl describe pods X</code></pre><p>레이블 관리</p>
<pre><code>$ kubectl label pods myweb APP=apache</code></pre><pre><code>$ kubectl label pods myweb ENV=developments</code></pre><pre><code>$ kubectl label pods myweb ENV=staging</code></pre><pre><code>$ kubectl label pods myweb ENV=staging --overwirte</code></pre><pre><code>$ kubectl label pods myweb ENV-</code></pre><h2 id="✔️-labelselector">✔️ LabelSelector</h2>
<h2 id="labelselector">LabelSelector</h2>
<ul>
<li><strong>검색</strong></li>
<li>리소스 간 연결</li>
</ul>
<p><strong>일치성(equality base)</strong></p>
<ul>
<li><code>=</code></li>
<li><code>==</code></li>
<li><code>!=</code></li>
</ul>
<pre><code>$ kubectl get pods -l APP=nginx
$ kubectl get pods -l APP==nginx</code></pre><pre><code>$ kubectl get pods -l &#39;APP!=nginx&#39;</code></pre><p><strong>집합성(set base)</strong></p>
<ul>
<li><code>in</code></li>
<li><code>notin</code></li>
<li><code>exists</code>: 키만 매칭<ul>
<li><code>kubectl get pods -l &#39;APP&#39;</code></li>
</ul>
</li>
<li><code>doesnotexists</code>: 키 제외 매칭<ul>
<li><code>kubectl get pods -l &#39;!APP&#39;</code></li>
</ul>
</li>
</ul>
<h2 id="✔️-annotations">✔️ Annotations</h2>
<p>레이블과 비슷
<strong>비 식별 메타데이타</strong></p>
<p>명령형 커맨드</p>
<pre><code>$ kubectl annotate pods myweb created-by=luna</code></pre><pre><code>$ kubectl annotate pods myweb created-by=Kim --overwrite</code></pre><pre><code>$ kubectl annotate pods myweb created-by-</code></pre><p>YAML</p>
<pre><code class="language-yaml">apiVersion: v1
kind: Pod
metadata:
  name: myweb-label-anno
  labels:
    APP: apache
    ENV: staging
  annotations:
    Created-by: Jang
spec:
  containers:
    - name: myweb
      image: httpd
      ports:
        - containerPort: 80
          protocol: TCP</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloude] k8s - Namespace]]></title>
            <link>https://velog.io/@luna_0917/Cloude-k8s-Namespace</link>
            <guid>https://velog.io/@luna_0917/Cloude-k8s-Namespace</guid>
            <pubDate>Tue, 17 May 2022 13:11:33 GMT</pubDate>
            <description><![CDATA[<h2 id="✔️-namespace">✔️ Namespace</h2>
<p>리소스를 분리</p>
<ul>
<li>서비스 별</li>
<li>사용자 별</li>
<li>환경: 개발, 스테이징, 프로덕션</li>
</ul>
<p><strong>네임스페이스 확인</strong></p>
<pre><code class="language-shell">$ kubectl get namespaces
$ kubectl get ns</code></pre>
<p><strong>kube-system</strong>
Kubernetes의 핵심 컴포넌트</p>
<p><strong>kube-public</strong>
모든 사용자가 읽기 권한</p>
<p><strong>kube-node-lease</strong>
노드의 HeartBeat 체크를 위한 Lease 리소스가 존재</p>
<ul>
<li>default: 기본 작업 공간</li>
</ul>
<pre><code>$ kubectl create ns developments</code></pre><pre><code>$ kubectl delete ns developments</code></pre><pre><code>$ kubectl get pods -A | --all-namespaces</code></pre><pre><code>$ kubectl get pods -n kube-system</code></pre><p><code>ns-dev.yaml</code></p>
<pre><code class="language-yaml">apiVersion: v1
kind: Namespace
metadata:
  name: dev</code></pre>
<pre><code>$ kubectl create -f ns-dev.yaml</code></pre><p><code>myweb-dev.yaml</code></p>
<pre><code class="language-yaml">apiVersion: v1
kind: Pod
metadata:
  name: myweb
  namespace: dev
spec:
  containers:
    - name: myweb
      image: httpd
      ports:
        - containerPort: 80
          protocol: TCP          </code></pre>
<pre><code>$ kubectl create -f myweb-dev.yaml</code></pre><pre><code>$ kubectl delete -f myweb-dev.yaml</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloude] k8s Objects]]></title>
            <link>https://velog.io/@luna_0917/Cloude-k8s-Objects</link>
            <guid>https://velog.io/@luna_0917/Cloude-k8s-Objects</guid>
            <pubDate>Tue, 17 May 2022 11:16:09 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-오브젝트-종류">✔️ 오브젝트 종류</h3>
<pre><code class="language-shell">$ kubectl api-resouces</code></pre>
<h3 id="✔️-오브젝트-정의">✔️ 오브젝트 정의</h3>
<p>기본 형식</p>
<pre><code class="language-yaml">apiVersion:
kind:
metdata:
spec:</code></pre>
<ul>
<li>apiVersion: 지원하는 오브젝트의 버전</li>
<li>kind: 오브젝트의 종류</li>
<li>metadata: 데이터를 설명하기 위한 데이터<ul>
<li>이름, 네임스페이스, Label, 주석(annoatation) ==파일에 대한 메타데이터</li>
</ul>
</li>
<li>spec: 오브젝트에 대해 어떤 상태를 의도하는지 (선언? 절차?)</li>
</ul>
<pre><code class="language-shell">$ kubectl explain pods
$ kubectl explain pods.metadata
$ kubectl explain pods.spec
$ kubectl explain pods.spec.containers
$ kubectl explain pods.spec.containers.images
$ kubectl explain pods.spec --recursive</code></pre>
<h3 id="✔️-오브젝트-관리">✔️ 오브젝트 관리</h3>
<p><strong>명령형 커멘드</strong></p>
<ul>
<li>yaml 파일을 작성하지 않고  kubectl 명령어로만 구성<ul>
<li><code>$ kubectl create</code></li>
<li><code>$ kubectl run</code></li>
<li><code>$ kubectl expose</code></li>
</ul>
</li>
</ul>
<p><strong>명령형 오브젝트 구성</strong></p>
<ul>
<li>YAML 파일을 순서대로 하나씩 실행<ul>
<li><code>$ kubectl create -f a.yaml</code></li>
<li><code>$ kubectl replace -f a.yaml</code></li>
<li><code>$ kubectl patch -f a.yaml</code></li>
<li><code>$ kubectl delete -f a.yaml</code></li>
</ul>
</li>
</ul>
<p><strong>선언형 오브젝트 구성</strong></p>
<ul>
<li>YAML 파일의 모음을 한번에 실행<ul>
<li><code>$ kubectl apply -f resources/</code></li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloude] k8s - Pods]]></title>
            <link>https://velog.io/@luna_0917/Cloude-k8s-Workload</link>
            <guid>https://velog.io/@luna_0917/Cloude-k8s-Workload</guid>
            <pubDate>Tue, 17 May 2022 08:17:27 GMT</pubDate>
            <description><![CDATA[<h2 id="✔️-pod">✔️ Pod</h2>
<p>관리할 수 있는 가장 작은 워크로드</p>
<h2 id="✔️-파드-생성-및-관리">✔️ 파드 생성 및 관리</h2>
<p><strong>명령형 커맨드로 파드 생성</strong></p>
<pre><code>$ kubectl run myweb --image httpd</code></pre><p><strong>파드 목록 확인</strong></p>
<pre><code>$ kubectl get pods</code></pre><p><strong>특정 파드 확인</strong></p>
<pre><code>$ kubectl get pods myweb</code></pre><p><strong>파드 상세 정보</strong></p>
<pre><code>$ kubectl get pods -o wide</code></pre><pre><code>$ kubectl get pods -o yaml</code></pre><pre><code>$ kubectl get pods -o json</code></pre><pre><code>$ kubectl describe pods myweb</code></pre><p><strong>애플리케이션 로그</strong></p>
<pre><code>$ kubectl logs myweb</code></pre><p><strong>파드 삭제</strong></p>
<pre><code class="language-shell">$ kubectl delete pods myweb</code></pre>
<h2 id="✔️-yaml-파일로-파드-정의">✔️ YAML 파일로 파드 정의</h2>
<p><code>myweb.yaml</code></p>
<pre><code class="language-yaml">apiVersion: v1
kind: Pod 
metadata:
  name: myweb
spec:
  containers:
    - name: myweb
      image: httpd
      ports:
        - containerPort: 80
          protocol: TCP</code></pre>
<blockquote>
<p>kubectl explain pods</p>
</blockquote>
<pre><code class="language-shell">$ kubectl create -f myweb.yaml</code></pre>
<pre><code>$ kubectl get -f myweb.yaml</code></pre><pre><code>$ kubectl describe -f myweb.yaml</code></pre><pre><code>$ kubectl delete -f myweb.yaml</code></pre><h2 id="✔️-kubectl-명령의-서브-명령">✔️ kubectl 명령의 서브 명령</h2>
<ul>
<li>create</li>
<li>get</li>
<li>describe</li>
<li>logs</li>
<li>delete</li>
<li>replace</li>
<li>patch</li>
<li>apply</li>
<li>diff</li>
</ul>
<h2 id="✔️-파드-디자인">✔️ 파드 디자인</h2>
<p><img src="https://d33wubrfki0l68.cloudfront.net/aecab1f649bc640ebef1f05581bfcc91a48038c4/728d6/images/docs/pod.svg" alt=""></p>
<ul>
<li>단일 컨테이너: 일반 적인 형태</li>
<li>멀티 컨테이너: 메인 애플리케이션이 존재 메인 애플리케이션 기능을 확장 하기 위한 컨테이너를 배치</li>
</ul>
<ul>
<li>sidecar: 기능의 확장</li>
<li>ambassador: 프록시/LB</li>
<li>adpator: 출력의 표준</li>
</ul>
<h2 id="✔️-포트-및-포트-포워딩">✔️ 포트 및 포트 포워딩</h2>
<p>테스트 &amp; 디버깅 목적</p>
<pre><code>$ kubectl port-forward pods/myweb 8080:80</code></pre><h2 id="✔️-이름--uid">✔️ 이름 &amp; UID</h2>
<p><strong>이름</strong>
네임스페이스 유일</p>
<p><strong>UID</strong>
클러스터에서 유일</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloude] k8s 클러스터 업데이트]]></title>
            <link>https://velog.io/@luna_0917/Cloude-k8s-%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0-%EC%97%85%EB%8D%B0%EC%9D%B4%ED%8A%B8</link>
            <guid>https://velog.io/@luna_0917/Cloude-k8s-%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0-%EC%97%85%EB%8D%B0%EC%9D%B4%ED%8A%B8</guid>
            <pubDate>Mon, 16 May 2022 13:25:49 GMT</pubDate>
            <description><![CDATA[<p><strong>작업 순서</strong></p>
<ol>
<li>kube-apiserver</li>
<li>kube-controller-manager, kube-cloud-controller-manage, kube-scheduler</li>
<li>kubelet(Control Plane -&gt; Worker Node)</li>
<li>kube-proxy(Control Plane -&gt; Worker Node)</li>
</ol>
<h2 id="✔️-kubeadm-클러스터-업그레이드">✔️ Kubeadm 클러스터 업그레이드</h2>
<p>1.22.9 --&gt; 1.22.9</p>
<ol>
<li>Control Plane의 kubeadm 업그레이드</li>
<li>Control Plane의 kubeadm으로 api, cm, sched 업그레이드</li>
<li>Control Plane의 kubelet, kubectl 업그레이드</li>
<li>Work Node의 kubeadm 업그레이드</li>
<li>Work Node의 kubeadm으로 업그레이드</li>
<li>Work Node의 kubelet, kubectl 업그레이드</li>
</ol>
<p>Control Plane</p>
<p>업그레이드 하기 위해 잠금 해제</p>
<pre><code class="language-shell">$ sudo apt-mark unhold kubeadm</code></pre>
<pre><code class="language-shell">$ sudo apt update</code></pre>
<pre><code class="language-shell">$ sudo apt upgrade kubeadm=1.22.9-00 -y</code></pre>
<pre><code class="language-shell">$ kubeadm version</code></pre>
<pre><code class="language-shell">$ sudo apt-mark hold kubeadm</code></pre>
<pre><code class="language-shell">$ sudo kubeadm upgrade plan</code></pre>
<pre><code class="language-shell">$ sudo kubeadm upgrade apply v1.22.9</code></pre>
<pre><code class="language-shell">$ sudo apt-mark unhold kubelet kubectl</code></pre>
<pre><code class="language-shell">$ sudo apt upgrade kubectl=1.22.9-00 kubelet=1.22.9-00 -y</code></pre>
<pre><code class="language-shell">$ sudo apt-mark hold kubelet kubectl</code></pre>
<pre><code class="language-shell">$ kubelet --version
$ kubectl version</code></pre>
<p>drain 작업 이후</p>
<pre><code class="language-shell">$ sudo systemctl daemon-reload
$ sudo systemctl restart kubelet</code></pre>
<p>uncordon 작업</p>
<pre><code class="language-shell">$ systemctl status kubelet</code></pre>
<p><strong>Work Node</strong></p>
<pre><code class="language-shell">$ sudo apt-mark unhold kubeadm</code></pre>
<pre><code class="language-shell">$ sudo apt update</code></pre>
<pre><code class="language-shell">$ sudo apt upgrade kubeadm=1.22.9-00 -y</code></pre>
<pre><code class="language-shell">$ kubeadm version</code></pre>
<pre><code class="language-shell">$ sudo apt-mark hold kubeadm</code></pre>
<pre><code class="language-shell">$ sudo kubeadm upgrade node</code></pre>
<blockquote>
<p>drain 작업</p>
</blockquote>
<pre><code class="language-shell">$ sudo apt-mark unhold kubelet kubectl</code></pre>
<pre><code class="language-shell">$ sudo apt upgrade kubectl=1.22.9-00 kubelet=1.22.9-00 -y</code></pre>
<pre><code class="language-shell">$ sudo apt-mark hold kubelet kubectl</code></pre>
<pre><code class="language-shell">$ kubelet --version
$ kubectl version</code></pre>
<pre><code class="language-shell">$ sudo systemctl daemon-reload
$ sudo systemctl restart kubelet</code></pre>
<blockquote>
<p>uncordon 작업</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloud] k8s Work Node 추가]]></title>
            <link>https://velog.io/@luna_0917/Cloud-k8s-Work-Node-%EC%B6%94%EA%B0%80</link>
            <guid>https://velog.io/@luna_0917/Cloud-k8s-Work-Node-%EC%B6%94%EA%B0%80</guid>
            <pubDate>Mon, 16 May 2022 12:37:48 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-docker-설치">✔️ Docker 설치</h3>
<pre><code class="language-shell">$ sudo apt-get update</code></pre>
<pre><code class="language-shell">$ sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
</code></pre>
<p>GPG 키 추가</p>
<pre><code class="language-shell">$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg</code></pre>
<p>저장소 추가</p>
<pre><code class="language-shell">$ echo \
  &quot;deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable&quot; | sudo tee /etc/apt/sources.list.d/docker.list &gt; /dev/null</code></pre>
<p>인덱스 정보 재업데이트</p>
<pre><code class="language-shell">$ sudo apt-get update</code></pre>
<p>도커 최신 버전 설치</p>
<pre><code class="language-shell">$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin</code></pre>
<pre><code class="language-shell">$ sudo usermod -aG docker vagrant</code></pre>
<h3 id="✔️-kubeadm-kubelet-kubectl-설치">✔️ kubeadm, kubelet, kubectl 설치</h3>
<pre><code class="language-shell">sudo apt-get install -y apt-transport-https ca-certificates curl</code></pre>
<pre><code class="language-shell">$ sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg</code></pre>
<pre><code class="language-shell">$ echo &quot;deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main&quot; | sudo tee /etc/apt/sources.list.d/kubernetes.list</code></pre>
<pre><code class="language-shell">$ sudo apt-get update</code></pre>
<pre><code class="language-shell">$ sudo apt-get install kubeadm=1.22.8-00 kubelet=1.22.8-00 kubectl=1.22.8-00 -y</code></pre>
<h3 id="✔️-k8s-cluster-join">✔️ K8s Cluster Join</h3>
<pre><code> sudo kubeadm join --token 97p4pn.xkm447t9vz39b6y9 192.168.100.100:6443 --discovery-token-ca-cert-h
ash sha256:86747560fdfeb86646a588ffe5a250ac93f14e95305c09f61d4250ee11e998e2</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloud] k8s 개요 및 설치]]></title>
            <link>https://velog.io/@luna_0917/CLoud-Kubernetes-install</link>
            <guid>https://velog.io/@luna_0917/CLoud-Kubernetes-install</guid>
            <pubDate>Fri, 13 May 2022 03:52:33 GMT</pubDate>
            <description><![CDATA[<h2 id="✔️-쿠버네티스란">✔️ 쿠버네티스란?</h2>
<p><img src="https://velog.velcdn.com/images/luna_0917/post/3b6ac26b-7fb3-42da-8006-6fc7e7366502/image.png" alt=""></p>
<p><strong>Control Plane</strong></p>
<ul>
<li>Node를 관리</li>
<li>일반적으로 최소 3개로 구성한다</li>
<li>절대 짝수로 구성하지 않는다<ul>
<li>5:5 Split Brain이 발생 할 수 있다</li>
</ul>
</li>
</ul>
<p><strong>API server</strong></p>
<ul>
<li>모든 시스템은 API server을 통한다</li>
</ul>
<p><strong>c-m (Controller-manager)</strong></p>
<ul>
<li>클러스터  전체를 컨트롤</li>
<li>종류<ul>
<li>노드 컨트롤러</li>
<li>레플리케이션 컨트롤러 = pod들의 복제를 관리</li>
<li>엔드포인트 컨트롤러</li>
<li>서비스 어카운트 &amp; 토크 컨트롤러</li>
</ul>
</li>
</ul>
<p><strong>Sched</strong></p>
<ul>
<li>스케쥴러</li>
<li>pod를 어디에 어떻게 배치할지 관리</li>
</ul>
<p><strong>etcd (etc daemon)</strong></p>
<ul>
<li>key value 스토리지</li>
</ul>
<p><strong>k-proxy (kube-proxy)</strong></p>
<ul>
<li>노드의 네트워크 규칙을 유지 관리</li>
</ul>
<h3 id="애드온">애드온</h3>
<p><strong>DNS (kube-dns)</strong></p>
<ul>
<li>애드온이지만 거의 필수</li>
<li>Service Discovery = 어떠한 서비스를 찾는 것을 의미</li>
<li>쿠버네티스</li>
</ul>
<p><strong>컨테이너 리소스 모니터링</strong></p>
<ul>
<li>중앙 데이터베이스 내의 컨테이너들에 대한 포괄적인 시계열 매트릭스를 기록하고 그 데이터를 열람하기 위한 UI를 제공</li>
</ul>
<p><strong>클러스터-레벨 로깅</strong></p>
<ul>
<li>메커니즘은 검색/열람 인터페이스와 함께 중앙 로그 저장소에 컨테이너 로그를 저장</li>
</ul>
<h2 id="✔️-쿠버네티스-설치">✔️ 쿠버네티스 설치</h2>
<p>Kubeadm = 쿠버네티스를 설치하기 위한 도구
Kubespray(Kubeadm+Ansible) = 실제로 많이 쓰임</p>
<p><strong>설치</strong>
Kubeadm 1.22.8
쿠버네티스 apt 리포지터리를 사용하는 데 필요한 패키지를 설치</p>
<pre><code class="language-shell">$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https ca-certificates curl</code></pre>
<p>서명 키 복사</p>
<pre><code class="language-shell">$ sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg</code></pre>
<p>저장소 추가</p>
<pre><code class="language-shell">$ echo &quot;deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main&quot; | sudo tee /etc/apt/sources.list.d/kubernetes.list
$ sudo apt-get update # 저장소 추가 했으니 한번 더 실행</code></pre>
<p>설치 버전 확인</p>
<pre><code class="language-shell">$  apt-cache madison kubeadm | grep 1.22.8
   kubeadm |  1.22.8-00 | https://apt.kubernetes.io kubernetes-xenial/main amd64 Packages</code></pre>
<pre><code class="language-shell">$ sudo apt-get install kubeadm=1.22.8-00 kubelet=1.22.8-00 kubectl=1.22.8-00 -y</code></pre>
<p>패키지 업데이트시 자동업데이트를 막기위한 hold</p>
<pre><code class="language-shell">$ sudo apt-mark hold kubelet kubeadm kubectl</code></pre>
<p><strong>클러스터 생성</strong></p>
<pre><code class="language-shell">$ kubeadm init --control-plane-endpoint 192.168.100.100 --pod-network-cidr 172.16.0.0/16 --apiserver-advertise-address 192.168.100.100</code></pre>
<blockquote>
<p>사용하고 있는 네트워크와 충돌을 방지하기 위해 172.16.0.0/16 사용</p>
</blockquote>
<p><strong>Cgroup driver 오류</strong></p>
<ul>
<li>kubelet이 실행이 되지 않아 발생</li>
</ul>
<pre><code class="language-shell">docker info | grep &#39;Cgroup Driver&#39;

 Cgroup Driver: cgroupfs # 버전이 바뀌면서 cgroupfs 지원 하지 않음</code></pre>
<p><code>/etc/docker/daemon.json</code></p>
<pre><code class="language-shell">{
  &quot;exec-opts&quot;: [&quot;native.cgroupdriver=systemd&quot;]
}</code></pre>
<p>재실행</p>
<pre><code class="language-shell">sudo systemctl restart docker</code></pre>
<pre><code class="language-shell">$ docker info | grep &#39;Cgroup Driver&#39;

 Cgroup Driver: systemd</code></pre>
<pre><code class="language-shell">$ sudo systemctl daemon-reload &amp;&amp; sudo systemctl restart kubelet</code></pre>
<p>kubeadm init 실패 시 실행</p>
<pre><code class="language-shell">$ sudo kubeadm reset</code></pre>
<pre><code class="language-shell">$ sudo kubeadm init --control-plane-endpoint 192.168.100.100 --pod-network-cidr 172.16.0.0/16 --apiserver-advertise-address 192.168.100.100</code></pre>
<pre><code class="language-shell"> $ mkdir -p $HOME/.kube
 $ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
 $ sudo chown $(id -u):$(id -g) $HOME/.kube/config</code></pre>
<p><strong>k8s 인증파일 생성 됨</strong>
    - 노출 되면 안됨</p>
<pre><code class="language-shell"> $ cd .kube
 $ ls
 config
 $ ls -l
 total 8
 -rw------- 1 vagrant vagrant 5639 May 13 08:08 config</code></pre>
<pre><code class="language-shell">$ kubectl get nodes
NAME     STATUS     ROLES                  AGE     VERSION
docker   NotReady   control-plane,master   9m20s   v1.22.8</code></pre>
<h2 id="✔️-callico-network-add-on">✔️ Callico Network Add-on</h2>
<pre><code class="language-shell">$ kubectl create -f https://projectcalico.docs.tigera.io/manifests/tigera-operator.yaml</code></pre>
<pre><code class="language-shell">$ curl https://projectcalico.docs.tigera.io/manifests/custom-resources.yaml -O</code></pre>
<p><code>costoum-resources.yaml</code></p>
<pre><code class="language-yaml">...
    cidr: 172.16.0.0/16
...</code></pre>
<pre><code class="language-shell">$ kubectl create -f custom-resources.yaml</code></pre>
<p><strong>클러스트 상태 확인</strong></p>
<pre><code class="language-shell">$ kubectl get pods -A   

NAMESPACE          NAME                                       ...
calico-apiserver   calico-apiserver-c9565f67b-2p29k           ...
calico-apiserver   calico-apiserver-c9565f67b-slthl           ...
calico-system      calico-kube-controllers-5d74cd74bc-sg7dn   ...
calico-system      calico-node-tgxks                          ...
calico-system      calico-typha-7447fdc844-txrdb              ...
kube-system        coredns-78fcd69978-4ztkq                   ...
kube-system        coredns-78fcd69978-jpwxx                   ...
kube-system        etcd-docker                                ...
kube-system        kube-apiserver-docker                      ...
kube-system        kube-controller-manager-docker             ...
kube-system        kube-proxy-5st98                           ...
kube-system        kube-scheduler-docker                      ...
tigera-operator    tigera-operator-7cf4df8fc7-kx87z           ...</code></pre>
<pre><code class="language-shell">$ kubectl get nodes

NAME     STATUS   ROLES                  AGE   VERSION
docker   Ready    control-plane,master   30m   v1.22.8</code></pre>
<p>isolation 해제</p>
<pre><code class="language-shell">$ kubectl taint node docker node-role.kubernetes.io/master-</code></pre>
<h3 id="예제">예제</h3>
<pre><code class="language-shell">$ kubectl create deployment myweb --image=ghcr.io/c1t1d0s7/go-myweb</code></pre>
<pre><code class="language-shell">$ kubectl get deployments,replicasets,pods

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/myweb   1/1     1            1           4m40s

NAME                              DESIRED   CURRENT   READY   AGE
replicaset.apps/myweb-97dbf5749   1         1         1       4m40s

NAME                        READY   STATUS    RESTARTS   AGE
pod/myweb-97dbf5749-8tq2l   1/1     **Running**   0          4m40s</code></pre>
<p><strong>Pod 외부 노출</strong></p>
<ul>
<li>쿠버네티스는 기본적으로 포트포워딩을 지원하지 않기 때문에 외부로 노출 시켜주어야 한다.<pre><code class="language-shell">$ kubectl expose deployment myweb --port=80 --protocol=TCP --target-port=8080 --name myweb-svc --type=NodePort</code></pre>
</li>
</ul>
<pre><code class="language-shell">$ kubectl get services

NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       &lt;none&gt;        443/TCP        33m
myweb-svc    NodePort    10.103.90.115   &lt;none&gt;        80:32338/TCP   10s</code></pre>
<p><img src="https://velog.velcdn.com/images/luna_0917/post/109348ab-f7db-452b-a524-ed31953ec40c/image.png" alt=""></p>
<pre><code class="language-shell">$ curl 192.168.100.100:32338

Hello World!
myweb-97dbf5749-qb8tm</code></pre>
<p><strong>복제본 생성</strong></p>
<pre><code class="language-shell">$ kubectl scale deployment myweb --replicas=3</code></pre>
<pre><code class="language-shell">$ kubectl get pods

NAME                      STATUS                 AGE
myweb-97dbf5749-4krhf     ContainerCreatin       5s
myweb-97dbf5749-c5s7h     ContainerCreating      5s
myweb-97dbf5749-qb8tm     Running               9m18s</code></pre>
<p><strong>서비스 삭제 &amp; deployment 삭제</strong></p>
<pre><code class="language-shell">$ kubectl delete service myweb-svc
$ kubectl delete deployment myweb</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloud] Docker]]></title>
            <link>https://velog.io/@luna_0917/Cloud-DockerGolang</link>
            <guid>https://velog.io/@luna_0917/Cloud-DockerGolang</guid>
            <pubDate>Thu, 12 May 2022 14:20:03 GMT</pubDate>
            <description><![CDATA[<h2 id="⭐️-go">⭐️ Go</h2>
<pre><code class="language-shell">mkdir -p ~/golang/hello
cd ~/golang/hello</code></pre>
<p>Golang 설치</p>
<pre><code class="language-shell">sudo apt install golang</code></pre>
<pre><code class="language-shell">go mod init hello</code></pre>
<p><code>hello.go</code></p>
<pre><code class="language-go">package main

import &quot;fmt&quot;

func main() {
        fmt.Println(&quot;hello go world&quot;)
}</code></pre>
<p>실행</p>
<ul>
<li>빌드 후 실행 됨
```shell
$ go run .  # go mod 파일 있어야 사용 가능</li>
<li>OR-
$ go run 파일명<pre><code></code></pre></li>
</ul>
<pre><code class="language-shell">$ go build . # go mod 파일 있어야 사용 가능
-OR-
$ go build -o [실행파일명] [소스코드 파일명]</code></pre>
<p><code>Dockerfile</code></p>
<pre><code>FROM golang:1.18-buster AS gobuilder
COPY . /app
WORKDIR /app
RUN go build .

FROM scratch
COPY --from=gobuilder /app/hello /
CMD [&quot;/hello&quot;]</code></pre><pre><code>docker build -t gohello .</code></pre><pre><code>docker run gohello</code></pre><hr>
<h2 id="⭐️-http-web">⭐️ Http Web</h2>
<pre><code>mkdir ~/golang/goweb
cd ~/golang/goweb</code></pre><pre><code>go mod init goweb</code></pre><p><code>goweb.go</code></p>
<pre><code class="language-go">package main

import (
        &quot;fmt&quot;
        &quot;log&quot;
        &quot;net/http&quot;
)

func handler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, &quot;Hi there, I love %s!&quot;, r.URL.Path[1:])
}

func main() {
        http.HandleFunc(&quot;/&quot;, handler)
        log.Fatal(http.ListenAndServe(&quot;:8080&quot;, nil))
}</code></pre>
<pre><code>go run .</code></pre><p><img src="https://velog.velcdn.com/images/luna_0917/post/e5a48c01-849a-4da1-926a-621c4112e7c2/image.png" alt=""></p>
<pre><code>curl 192.168.100.100:8080
curl 192.168.100.100:8080/encore</code></pre><pre><code>go build .</code></pre><p><code>.dockerignore</code></p>
<pre><code>goweb
Dockerfile
.dockerignore</code></pre><p><code>Dockerfile</code></p>
<pre><code>FROM golang:1.18-buster AS gobuilder
ENV CGO_ENABLED 0
COPY . /app
WORKDIR /app
RUN go build -o goweb .

FROM scratch
COPY --from=gobuilder /app/goweb /
CMD [&quot;/goweb&quot;]
EXPOSE 8080</code></pre><pre><code>docker build -t goweb .</code></pre><pre><code>docker run -d -p 80:8080 goweb</code></pre><h2 id="⭐️-gin">⭐️ Gin</h2>
<pre><code class="language-shell">$ mkdir ~/golang/gogin
$ cd ~/golang/gogin</code></pre>
<pre><code class="language-shell">$ go mod init gogin</code></pre>
<p><code>gogin.go</code></p>
<pre><code class="language-go">package main

import &quot;github.com/gin-gonic/gin&quot;

func main() {
    r := gin.Default()
    r.GET(&quot;/ping&quot;, func(c *gin.Context) {
        c.JSON(200, gin.H{
            &quot;message&quot;: &quot;pong&quot;,
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080 (for windows &quot;localhost:8080&quot;)
}</code></pre>
<pre><code class="language-shell">$ go mod tidy</code></pre>
<pre><code class="language-shell">$ cat go.sum</code></pre>
<p><code>Dockerfile</code></p>
<pre><code class="language-shell">FROM golang:1.18-buster AS gobuilder
ENV CGO_ENABLED 0
COPY . /app
WORKDIR /app
RUN go build -o gogin .

FROM scratch
COPY --from=gobuilder /app/gogin /
CMD [&quot;/gogin&quot;]
EXPOSE 8080</code></pre>
<pre><code class="language-shell">$ docker build -t gogin .</code></pre>
<pre><code class="language-shell">$ docker run -d -p 80:8080 gogin</code></pre>
<pre><code class="language-shell">$ curl 192.168.100.100/ping</code></pre>
<h2 id="⭐️-nodejs">⭐️ Node.js</h2>
<pre><code class="language-shell">$ mkdir ~/nodejs/web
$ cd ~/nodejs/web</code></pre>
<p><code>app.js</code></p>
<pre><code class="language-js">const http = require(&#39;http&#39;);

const hostname = &#39;0.0.0.0&#39;;
const port = 3000;

const server = http.createServer((req, res) =&gt; {
  res.statusCode = 200;
  res.setHeader(&#39;Content-Type&#39;, &#39;text/plain&#39;);
  res.end(&#39;Hello World&#39;);
});

server.listen(port, hostname, () =&gt; {
  console.log(`Server running at http://${hostname}:${port}/`);
});</code></pre>
<pre><code class="language-shell">$ node app.js
Server running at http://0.0.0.0:3000/</code></pre>
<p><img src="https://velog.velcdn.com/images/luna_0917/post/35d443dd-4716-4e03-9fa1-efc4f766c57f/image.png" alt=""></p>
<h4 id="예제">예제</h4>
<blockquote>
<p><a href="https://nodejs.org/en/docs/guides/nodejs-docker-webapp/">https://nodejs.org/en/docs/guides/nodejs-docker-webapp/</a></p>
</blockquote>
<p><code>package.json</code></p>
<pre><code class="language-json">{
  &quot;name&quot;: &quot;docker_web_app&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;description&quot;: &quot;Node.js on Docker&quot;,
  &quot;author&quot;: &quot;First Last &lt;first.last@example.com&gt;&quot;,
  &quot;main&quot;: &quot;server.js&quot;,
  &quot;scripts&quot;: {
    &quot;start&quot;: &quot;node server.js&quot;
  },
  &quot;dependencies&quot;: {
    &quot;express&quot;: &quot;^4.16.1&quot;
  }
}</code></pre>
<p><code>server.js</code></p>
<pre><code class="language-js">&#39;use strict&#39;;

const express = require(&#39;express&#39;);

// Constants
const PORT = 8080;
const HOST = &#39;0.0.0.0&#39;;

// App
const app = express();
app.get(&#39;/&#39;, (req, res) =&gt; {
  res.send(&#39;Hello World&#39;);
});

app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);</code></pre>
<p><strong>실행</strong></p>
<pre><code class="language-shell">$ npm install

added 57 packages, and audited 58 packages in 7s

7 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
npm notice
npm notice New minor version of npm available! 8.5.5 -&gt; 8.10.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v8.10.0
npm notice Run npm install -g npm@8.10.0 to update!
npm notice</code></pre>
<pre><code class="language-shell">$ ls
node_modules  package-lock.json  package.json  server.js</code></pre>
<blockquote>
<p>nodejs는 패키지를 node_moduels에 저장 == 도커 이미지에 넣으면 안됨
package-lock.json : 패키지 목록 == 도커 이미지에 넣어주어야함</p>
</blockquote>
<p><code>.dockerignore</code></p>
<pre><code class="language-shell">node_moduels/
Dockerfile
.dockerignore        </code></pre>
<p><code>Docerfile</code></p>
<pre><code>FROM node:16

WORKDIR /usr/src/app
COPY . .
RUN npm install # package-lock.json파일 보고 패키지 설치
EXPOSE 8080
CMD [ &quot;node&quot;, &quot;server.js&quot; ]
</code></pre><pre><code class="language-shell">$ docker build -t mynode .</code></pre>
<pre><code class="language-shell">$ docker run -d -p 80:8080 mynode</code></pre>
<p><img src="https://velog.velcdn.com/images/luna_0917/post/814771d2-f996-4f11-9bf0-5014a69d207e/image.png" alt=""></p>
<h2 id="⭐️-docer-hub">⭐️ Docer hub</h2>
<hr>
<pre><code class="language-shell">$ docker login</code></pre>
<p>로그인되면  ./docker/config.json에 인증 정보 저장
image 빌드 시 <strong>홈 디렉토리</strong>, <strong>루트</strong> 에서는 절대 안됨</p>
<pre><code class="language-shell">$ docker push pyhello:v1
The push refers to repository [docker.io/library/pyhello]
7201388967b8: Preparing
673874d26a0c: Preparing
003d829fbdc9: Preparing
c624266426ab: Preparing
ca6c84023067: Preparing
8272ebc3fc9d: Waiting
74f08751ac3f: Waiting
58b24c6222e3: Waiting
7ae08394a32a: Waiting
f70b727d55c3: Waiting
denied: requested access to the resource is denied</code></pre>
<p>-&gt; 이미지 형식이 맞지 않아서 denied 가 뜬다</p>
<p><strong>기존 이미지에 태그 달아주기</strong></p>
<pre><code>$ docker tag 기존이미지명:태그명 도커계정명/새로운이미지명:태그명
$ docker tag pyhello:v1 사용자계정/pyhello:v1</code></pre><p>-&gt; 이미지이름이 바뀌는 것이 아니라 뒤에 태그가 더 추가 되는 것</p>
<p><img src="https://velog.velcdn.com/images/luna_0917/post/574a225d-5b9d-4bb3-944c-43d77a947c8c/image.png" alt=""></p>
<h2 id="⭐️-docer-compose">⭐️ Docer Compose</h2>
<p>Docker IaC</p>
<p><code>docker-compose</code> -&gt; <code>docker compose</code></p>
<p><code>docker-compose.yaml</code> 또는 <code>docker-compose.yml</code>
-&gt; 파일명은 정해져 있음</p>
<h3 id="예제1">예제1</h3>
<p><code>docker-compose.yaml</code></p>
<pre><code class="language-yaml">version: &#39;3&#39; # 3버전에서 사용할 수 있는 최신 버전 사용

services: # 컨테이너를 서비스란 개념으로 사용
  web:    # 컨테이너 이름
    image: httpd  # 이미지 지정</code></pre>
<p><strong>실행</strong></p>
<pre><code class="language-shell">$ docker compose up -d</code></pre>
<p><strong>프로젝트 목록 확인</strong></p>
<pre><code class="language-shell">$ docker compose ls</code></pre>
<p><strong>서비스 목록(컨테이너)</strong></p>
<pre><code class="language-shell">$ docker compose ps</code></pre>
<p><strong>삭제</strong></p>
<pre><code>docker compose down</code></pre><h3 id="예제2">예제2</h3>
<pre><code class="language-yaml">version: &#39;3&#39;

services:
  web:   # 서비스 1
    image: httpd   # 이미지
    restart: always  # 재시작 정책
    ports:
      - 80:80
    environment:    #환경변수
    MSG: hello world 
    volumes:
      - web-contents:/var/www/  # 볼륨을 컨테이너 내부에 실행
    networks:
      - web-net
  web2:     # 서비스 2
    image: nginx
    networks:  # 네트워크
      - web-net

volumes:
  web-contents:

networks:
  web-net:</code></pre>
<pre><code>docker compose up -d</code></pre><pre><code>docker compose exec web bash

&gt; apt update; apt install curl
&gt; curl web2</code></pre><blockquote>
<p>도커 컴포즈로 배포한 컨테이너는 서로 이름으로 통신가능</p>
</blockquote>
<h3 id="예제3">예제3</h3>
<pre><code class="language-yaml">version: &#39;3&#39;

services:

  myflask:
    build: ./hello-flask

  mydjango:
    build: ./hello-django</code></pre>
<pre><code>cp -r ~/python/hello-django .
cp -r ~/python/hello-flask .</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloud] Docker-이미지_2]]></title>
            <link>https://velog.io/@luna_0917/Cloud-Docker-%EC%9D%B4%EB%AF%B8%EC%A7%802</link>
            <guid>https://velog.io/@luna_0917/Cloud-Docker-%EC%9D%B4%EB%AF%B8%EC%A7%802</guid>
            <pubDate>Wed, 11 May 2022 15:27:35 GMT</pubDate>
            <description><![CDATA[<h2 id="⭐️-쉘-변수">⭐️ 쉘 변수</h2>
<p><code>a.sh</code></p>
<pre><code class="language-shell">#!/bin/sh

echo &quot;\$MSG = $MSG&quot;
echo &quot;\$@ = $@&quot;
echo &quot;\$0 = $0&quot;
echo &quot;\$1 = $1&quot;
echo &quot;\$2 = $2&quot;
echo &quot;\$3 = $3&quot;</code></pre>
<pre><code class="language-shell">MSG=&quot;Hello World&quot; ./a.sh 1 2 3 4 5 6</code></pre>
<ul>
<li>$0: 명령어</li>
<li>$1: 첫번째 argument</li>
<li>$2: 두번째 argument</li>
<li>$@: 모든 argument</li>
</ul>
<hr>
<h2 id="⭐️alpine-linux">⭐️Alpine Linux</h2>
<p>Busybox + APK(패키지 관리자)</p>
<p>패키지 인덱스</p>
<pre><code class="language-shell">apk update</code></pre>
<p>패키지 검색</p>
<pre><code class="language-shell">apk search &lt;PKG&gt;</code></pre>
<p>패키지 추가</p>
<pre><code class="language-shell">apk add &lt;PKG&gt;</code></pre>
<p>패키지 제거</p>
<pre><code class="language-shell">apk del &lt;PKG&gt;</code></pre>
<h2 id="dockerfile-명이-다른-경우">Dockerfile 명이 다른 경우</h2>
<p><code>Dockerfile-alpine</code></p>
<pre><code>docker build -f Dockerfile-alpine -t pyhello:v1 .</code></pre><h2 id="⭐️-flask">⭐️ Flask</h2>
<ul>
<li>python3</li>
<li>python3-pip</li>
<li>python3-venv</li>
</ul>
<pre><code class="language-shell">sudo apt install python3-pip python3-venv</code></pre>
<pre><code class="language-shell">mkdir ~/python/hello-flask
cd ~/python/hello-flask</code></pre>
<p>가상환경/프로젝트 생성</p>
<pre><code class="language-shell">python3 -m venv 가상환경이름</code></pre>
<p>가상환경 활성화</p>
<pre><code class="language-script">. venv/bin/activate</code></pre>
<p>가상환경 비활성화</p>
<pre><code class="language-shell">deactivate</code></pre>
<pre><code class="language-shell">pip3 install Flask</code></pre>
<p><code>hello.py</code></p>
<pre><code class="language-py">from flask import Flask

app = Flask(__name__)

@app.route(&quot;/&quot;)
def hello_world():
    return &quot;&lt;p&gt;Hello, World!&lt;/p&gt;&quot;</code></pre>
<ul>
<li>실행<pre><code class="language-shell">export FLASK_APP=hello
flask run
flask run --host=&#39;0.0.0.0&#39; [--port=&#39;8080&#39;]</code></pre>
<blockquote>
<p>기본 포트 : 5000</p>
</blockquote>
</li>
</ul>
<ul>
<li>freeze
  -현재 설치한 패키지들을 txt파일로 저장</li>
</ul>
<pre><code class="language-shell">pip3 freeze &gt; requirements.txt</code></pre>
<ul>
<li>가상 환경 구성 후 txt파일에 저장되어 있는 패키지 설치 <pre><code class="language-shell">pip3 install -r requirements.txt</code></pre>
</li>
</ul>
<h2 id="⭐️-django">⭐️ Django</h2>
<p>Django : 풀스택 프레임 워크</p>
<pre><code class="language-shell">mkdir ~/python/hello-django
cd ~/python/hello-django</code></pre>
<ul>
<li>가상환경을 사용하기 위한 설치<pre><code class="language-shell">python3 -m venv [가상환경이름]</code></pre>
</li>
</ul>
<pre><code class="language-shell">pip3 install Django # $ python -m pip install Django와 동일</code></pre>
<pre><code class="language-shell">pip3 freeze &gt; requirements.txt</code></pre>
<p><code>mysite/settings.py</code></p>
<pre><code class="language-shell">...
ALLOWED_HOSTS = [&#39;*&#39;]
...</code></pre>
<pre><code>cd mysite
python3 manage.py runserver 0.0.0.0:8000</code></pre><h2 id="⭐️-c">⭐️ C</h2>
<p>Language</p>
<ul>
<li>컴파일: C, C++, Golang, Rust -&gt; 실행파일<ul>
<li>Java, .NET(C#) -&gt; Bytecode</li>
</ul>
</li>
<li>스크립트: Shell, Perl, Python, Ruby, Javascript<ul>
<li>인터프리터/런타임</li>
</ul>
</li>
</ul>
<pre><code class="language-shell">sudo apt install gcc</code></pre>
<pre><code class="language-shell">mkdir ~/clang
cd ~/clang</code></pre>
<p><code>hello.c</code></p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int main() {
        printf(&quot;Hello C World\n&quot;);
        return 0;
}</code></pre>
<h3 id="동적-바이너리">동적 바이너리</h3>
<pre><code class="language-shell">gcc hello.c -o hello</code></pre>
<pre><code class="language-shell">file hello

... dynamically linked ...</code></pre>
<pre><code>ldd hello

    linux-vdso.so.1 (0x00007ffcd014b000)
    libc.so.6 =&gt; /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe1a8ed2000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fe1a90d2000)</code></pre><blockquote>
<p>so : c 라이브러리를 의미</p>
</blockquote>
<pre><code class="language-shell">mkdir -p lib/x86_64-linux-gnu
mkdir lib64</code></pre>
<pre><code class="language-shell">cp /lib/x86_64-linux-gnu/libc.so.6 lib/x86_64-linux-gnu/
cp /lib64/ld-linux-x86-64.so.2 lib64/</code></pre>
<p><code>Dockerfile</code></p>
<pre><code class="language-shell">FROM scratch
COPY lib /lib
COPY lib64 /lib64
COPY hello /
CMD [&quot;/hello&quot;]</code></pre>
<pre><code class="language-shell">docker build -t hello:dynamic .</code></pre>
<pre><code class="language-shell">docker run hello:dynamic</code></pre>
<h3 id="정적-바이너리">정적 바이너리</h3>
<pre><code class="language-shell">gcc hello.c -static -o helloc</code></pre>
<p><code>Dockerfile-static</code></p>
<pre><code class="language-shell">FROM scratch
COPY helloc /
CMD [&quot;/helloc&quot;]</code></pre>
<pre><code class="language-shell">docker build -f Dockerfile-static -t hello:static .</code></pre>
<pre><code class="language-shell">docker run hello:static</code></pre>
<h3 id="멀티-빌드">멀티 빌드</h3>
<p><code>Dockerfile-multi</code></p>
<pre><code class="language-shell">FROM gcc AS cbuilder
WORKDIR /root
ADD hello.c .
RUN gcc hello.c -static -o hello

FROM scratch
COPY --from=cbuilder /root/hello /
CMD [&quot;/hello&quot;]</code></pre>
<pre><code class="language-shell">docker build -f Dockerfile-multi -t hello:multi .</code></pre>
<pre><code class="language-shell">docker run hello:multi</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AWS] 연습문제 ch6]]></title>
            <link>https://velog.io/@luna_0917/AWS-%EC%97%B0%EC%8A%B5%EB%AC%B8%EC%A0%9C-ch6</link>
            <guid>https://velog.io/@luna_0917/AWS-%EC%97%B0%EC%8A%B5%EB%AC%B8%EC%A0%9C-ch6</guid>
            <pubDate>Tue, 10 May 2022 12:20:02 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-기술">📌 기술</h2>
<hr>
<h3 id="라우팅-정책">라우팅 정책</h3>
<h4 id="1-단순-라우팅-정책">1) 단순 라우팅 정책</h4>
<p>도메인에 대해 특정 기능을 수행하는 하나의 리소스만 있는 경우에 사용</p>
<h4 id="2-장애-조치-라우팅-정책">2) 장애 조치 라우팅 정책</h4>
<p> Active-Passive 장애 조치를 구성하려는 경우에 사용</p>
<h4 id="3-지리-위치-라우팅-정책">3) 지리 위치 라우팅 정책</h4>
<p>사용자의 위치에 기반하여 트래픽 라우팅하려는 경우에 사용</p>
<h4 id="4-지리-근접-라우팅-정책">4) 지리 근접 라우팅 정책</h4>
<p>리소스의 위치를 기반으로 트래픽을 라우팅하고 필요에 따라 한 위치의 리소스에서 다른 위치의 리소스로 트래픽을 보내려는 경우 사용</p>
<h4 id="5-지연-시간-라우팅-정책">5) 지연 시간 라우팅 정책</h4>
<p>여러 AWS 리전에 리소스가 있고, 최상의 지연시간을 제공하는 리전으로 트래픽을 라우팅하려는 경우에 사용</p>
<h4 id="6-다중-응답-라우팅-정책">6) 다중 응답 라우팅 정책</h4>
<p>Route 53이 DNS 쿼리에 무작위로 선택된 최대 8개의 정상 레코드로 응답하게 하려는 경우에 사용</p>
<h4 id="7-가중치-기반-라우팅-정책">7) 가중치 기반 라우팅 정책</h4>
<p>사용자가 지정하는 비율에 따라 여러 리소스로 트래픽을 라우팅하려는 경우 사용</p>
<h3 id="amazon-route-53">Amazon Route 53</h3>
<ul>
<li>높은 가용성, 확장성이 뛰어난 클라우드 DNS 웹 서비스</li>
<li>최종 사용자를 인터넷 애플리케이션으로 라우팅 할 수 있는 매우 안정적이고 비용 효율적인 방법을 개발자와 기업에 제공하기 위해 설계</li>
</ul>
<h3 id="amazon-s3">Amazon S3</h3>
<ul>
<li>Amazon Simple Storage Service</li>
<li>최고의 확장성과 데이터 가용성 및 보안과 성능을 제공하는 <strong>객체 스토리지 서비스</strong></li>
<li>원하는 만큼의 데이터를 저장하고 보호가능</li>
<li>사용하기 쉬운 관리 기능을 제공 하여 데이터를 조직화하고 세부적인 액세스 제어 구성 가능</li>
</ul>
<h3 id="amazon-efs">Amazon EFS</h3>
<ul>
<li>Amazon Elastic File System</li>
<li>AWS 클라우드 서비스와 온프레미스 리소스에서 사용할 수 있는 <strong>간단</strong>하고 <strong>확장</strong> 가능하며, <strong>탄력</strong>적인 완전 관리형 NFS 파일 시스템 제공</li>
<li>애플리케이션을 중단 없이 온디맨드 방식으로 확장하도록 구축되어, 파일을 추가하고 제거할 때 <strong>자동으로 확장 및 축소</strong></li>
<li>확장 규모에 맞게 용량을 프로비저닝 및 관리 할 필요 X</li>
</ul>
<h3 id="amazon-ec2-스팟-인스턴스">Amazon EC2 스팟 인스턴스</h3>
<ul>
<li><strong>중단</strong>될 수 있는 EC2로 컨테이너화 된 워크로드에 적합</li>
<li>온디맨드 가격보다 저렴한 비용으로 사용할수 있는 미사용 EC2 인스턴스</li>
<li>용량이 가용 상태이고, 요청에 대한 시간당 최고 가격이 스팟가격보다 높을때마다 실행</li>
<li>애플리케이션이 실행되는 <strong>시간을 유연하게 조정</strong>할 수 있고, <strong><em>애플리케이션을 중단</em></strong>할 수 있는 경우에 선택하는 비용 효율적인 방법</li>
<li>ex) 데이터 분석, 배치 작업, 백그라운드 프로세싱 및 선택적 작업에 적합</li>
</ul>
<h3 id="aws-iam">AWS IAM</h3>
<ul>
<li>AWS 리소스에 대한 개별 액세스 및 그룹 액세스를 안전하게 제어 가능</li>
<li>사용자 자격 증명을 생성 및 관리</li>
<li>사용자에게 리소스에 액세스 할 수 있는 권한 부여 가능</li>
<li>외부의 사용자에게 권한 부여 가능</li>
</ul>
<h4 id="✔️-iam-사용자-및-액세스-관리">✔️ IAM 사용자 및 액세스 관리</h4>
<ul>
<li>사용자를 생성하거나, 사용자에게 개별 보안 자격증명 할당 가능</li>
<li>AWS 서비스 및 리소스에 대한 액세스를 제공할 수 있도록** 임시 보안 자격 증명** 요청 가능</li>
<li>사용자가 수행할 수 있는 작업을 제어하는 권한 지정 가능<h4 id="✔️-연동-사용자의-액세스-관리">✔️ 연동 사용자의 액세스 관리</h4>
</li>
<li>기업 디렉터리에서 관리하는 사용자에 대해 만료를 구성할 수 있는 보안자격증명을 요청하여, IAM 사용자 계정을 생성하지 않고도 리소스에 대한 보안 액세스 제공 가능</li>
<li>보안 자격 증명에 권한을 지정하여 사용자가 수행할 수 있는 작업 제어</li>
</ul>
<h3 id="aws-codedeploy">AWS CodeDeploy</h3>
<ul>
<li>EC2. Fargate, Lambda 및 온프레미스 서버와 같은 다양한 서비스에 대한 소프트웨어 <strong>배포를 자동화</strong>하는 완전관리형 배포 서비스</li>
<li>새로운 기능을 더 쉽고 빠르게 출시 가능</li>
<li>애플리케이션을 배포하는 동안 가동 중지 시간을 줄이는데 도움</li>
<li>복잡한 애플리케이션 업데이트 작업을 처리 가능</li>
<li>소프트웨어 배포를 자동화함으로써 오류가 발생하기 쉬운 수동 작업을 제거 가능</li>
<li>배포 요구 사항에 맞게 서비스 확장 가능</li>
</ul>
<hr>
<h2 id="📌-클라우드-개념">📌 클라우드 개념</h2>
<hr>
<h3 id="aws-마이그레이션-이점">AWS 마이그레이션 이점</h3>
<ul>
<li>낮은 가변 비용 및 낮은 초기비용
1) 자본 비용을 가변 비용으로 교환</li>
<li>데이터 센터와 서버에 대해 막연한 투자대신 컴퓨팅 리소스 사용시에만 비용 지불</li>
</ul>
<p>2) 대규모 경제의 이점</p>
<ul>
<li>클라우드 컴퓨팅 사용시, 스스로 얻는것 보다 더 낮은 가변 비용을 달성 가능</li>
</ul>
<p>3) 용량 추측 중지</p>
<ul>
<li>인프라 용량 요구에 대한 추측 제거</li>
<li>필요한 만큼의 용량에 액세스 가능</li>
</ul>
<p>4) 속도 및 민첩성 향상</p>
<ul>
<li>새로운 IT 리소스는 클릭 한번으로 가능</li>
<li>개발가가 리소스를 사용할 수 있도록 하는데 걸리는 시간을 단축할수 있음</li>
<li>실험 및 개발에 소요되는 비용과 시간이 현저히 낮기 때문에 민첩성 향상</li>
</ul>
<p>5) 데이터 센터 운영 및 유지 비용 지출 중단</p>
<ul>
<li>인프라가 아닌 비즈니스에 집중 가능</li>
<li>서버 랙, 스태킹 및 전원 공급의 부담이 X</li>
</ul>
<h3 id="클라우딩-컴퓨팅의-주요-모델">클라우딩 컴퓨팅의 주요 모델</h3>
<h4 id="✔️-iaas-서비스로서의-인프라">✔️ IaaS 서비스로서의 인프라</h4>
<ul>
<li>네트워킹 기능, 컴퓨터(가상 또는 전용 HW) 및 데이터 스토리지 공간 제공</li>
<li>IT리소스에 대해 가장 높은 수준의 유연성과 관리 제어를 제공</li>
</ul>
<h4 id="✔️-paas-서비스로서의-플랫폼">✔️ PaaS 서비스로서의 플랫폼</h4>
<ul>
<li>기본 인프라(HW, OS 등)를 관리할 필요 X , 애플리케이션 개발과 관리에 집중 가능</li>
<li>애플리케이션 실행과 관련된 리소스구매, 용량 계획, SW 유지 관리, 패치 또는 다른 모든 획일적인 작업에 부담 감소</li>
</ul>
<h4 id="✔️-saas-서비스로서의-소프트웨어">✔️ SaaS 서비스로서의 소프트웨어</h4>
<ul>
<li>서비스 제공자에 의해 실행되고 관리되는 완전한 제품을 고객에게 제공</li>
<li>서비스가 어떻게 유지 관리되는지, 기본 인프라의 관리 여부를 생각할 필요 X</li>
<li>ex) 웹 기반 이메일</li>
</ul>
<h3 id="aws-transit-gateway">AWS Transit Gateway</h3>
<ul>
<li>중앙 허브를 통해 VPC와 온프레미스 네트워크 연결</li>
<li>네트워크가 간소화되고 확장성 개선</li>
<li>단일 위치에서 모든 트래픽을 관리하고 모니터링 가능</li>
</ul>
<p><img src="https://velog.velcdn.com/images/luna_0917/post/a74be35c-48e8-4692-999e-931bb45e43aa/image.png" alt=""></p>
<hr>
<h2 id="📌-보안-및-준수">📌 보안 및 준수</h2>
<hr>
<h3 id="amazon-macie">Amazon Macie</h3>
<ul>
<li>완전 관리형의 데이터 보안 및 데이터 프라이버시 서비스</li>
<li>기계학습 및 패턴 매칭을 활용하여 AWS에서 민감한 데이터 검색 및 보호</li>
</ul>
<h3 id="aws-web-application-firewall-waf">AWS Web Application Firewall (WAF)</h3>
<ul>
<li>가용성에 영향, 보안 위협, 리소스 과사용을 발생시키는 일반적인 웹 공격에 대한 보호 제공</li>
<li>공격패턴 차단하는 보안규칙 및 사용자가 정의한 특정 트래픽 패턴을 필터링 하는 규칙 생성 가능</li>
</ul>
<h3 id="ddos">DDoS</h3>
<ul>
<li>분산 서비스 거부</li>
<li>여러개의 손상된 시스템이 많은 양의 트래픽으로 대상에 서비스 장애를 발생시키기 위한 공격</li>
<li>합법적 사용자의 서비스 액세스 방해, 시스템 충돌 발생</li>
<li>AWS는 AWS Shield Standard 및 AWS Shield Advanced 2개의 보호 제공</li>
</ul>
<h3 id="aws-cloudhsm">AWS CloudHSM</h3>
<ul>
<li>클라우드에서 자체 암호화 키를 손쉽게 생성 및 사용하게 지원하는 클라우드 기반 하드웨어 보안 모듈(HSM)</li>
<li>사용자를 위해 하드웨어 프로비저닝, 소프트웨어 패치, 고가용성, 백업 등 시간 소모적인 관리 작업을 자동화하는 완전 관리형 서비스</li>
</ul>
<hr>
<h2 id="📌-결제-및-요금">📌 결제 및 요금</h2>
<hr>
<h3 id="aws-billing-비용-할당-태그">AWS Billing 비용 할당 태그</h3>
<ul>
<li>태그 : 사용자 또는 AWS가 AWS 리소스에 할당하는 레이블, _<strong>키+값</strong>_으로 구성</li>
<li>각 리소스에 대해 <strong>고유한 태그 키</strong>를 가져야 하며, 각 태그 키는 <strong>하나의 값</strong>만 가질수 있음</li>
<li>AWS에서 생성한 태그와 사용자 정의 태그를 별도로 활성화 해야, 비용 탐색기 똔느 비용할당 보고서에 표시 될수 있음</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Cloud] Docker 이미지]]></title>
            <link>https://velog.io/@luna_0917/Cloud-Docker-%EC%9D%B4%EB%AF%B8%EC%A7%80</link>
            <guid>https://velog.io/@luna_0917/Cloud-Docker-%EC%9D%B4%EB%AF%B8%EC%A7%80</guid>
            <pubDate>Tue, 10 May 2022 10:59:28 GMT</pubDate>
            <description><![CDATA[<h2 id="⭐️-docker-이미지-빌드">⭐️ Docker 이미지 빌드</h2>
<p>방법</p>
<ul>
<li><code>docker commit</code> 명령</li>
<li>Dockerfile</li>
</ul>
<h3 id="명령으로-이미지-생성">명령으로 이미지 생성</h3>
<h3 id="docker-diff"><code>docker diff</code></h3>
<pre><code>docker diff &lt;CONTAINER&gt;</code></pre><p>기준 이미지 &lt;-&gt; 컨테이너 차이</p>
<ul>
<li>A: Add</li>
<li>C: Change</li>
<li>D: Delete</li>
</ul>
<h3 id="docker-commit"><code>docker commit</code></h3>
<pre><code class="language-shell">$ docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]</code></pre>
<p>CMD 변경</p>
<pre><code class="language-shell">$ docker commit -c &quot;CMD XXX&quot; CONTAINER [REPOSITORY[:TAG]]</code></pre>
<p>ExposedPort 변경</p>
<pre><code class="language-shell">$ docker commit -c &quot;EXPOSE PORT/PROTOCOL&quot; CONTAINER [REPOSITORY[:TAG]]</code></pre>
<blockquote>
<p>ExposedPort는 실제 작동여부와 상관 X
CMD /usr/sbin/apache2ctl -D FOREGROUND
/bin/sh -c /usr/sbin/apache2ctl -D FOREGROUND</p>
</blockquote>
<h3 id="docker-cp"><code>docker cp</code></h3>
<p>컨테이너 -&gt; 도커 호스트</p>
<pre><code class="language-shell">$ docker cp CONTAINER:SRC_PATH DEST_PATH</code></pre>
<p>도커 호스트 -&gt; 컨테이너</p>
<pre><code class="language-shell">$ docker cp SRC_PATH CONTAINER:DEST_PATH</code></pre>
<p>/bin/sh -c /usr/sbin/apache2ctl -DFOREGROUND</p>
<h3 id="이미지-레이어">이미지 레이어</h3>
<p>레이어를 가지는 이유 == 저장소 및 네트워크 전송 효율성 높임</p>
<p>httpd:latest</p>
<pre><code class="language-bash">sha256:9c1b6dd6c1e6be9fdd2b1987783824670d3b0dd7ae8ad6f57dc3cea5739ac71e
sha256:1d1a2486e901871ad1257512d588eebb30ae0605d8353abb6635e2d313b2187c
sha256:ec02eb7f3cf4dd78bc518d3a8ccf57f57336ceacb9638303891787ff2ec2e96f
sha256:67bb571b5bd2b65cbdf2c93c6f9dc8e89414055dd7444df617b23466996f3be7
sha256:e83f42350a11889083536c5af330dcf15fd3624f8e956f4086e1f0cfb07ff246</code></pre>
<p>myhttpd:latest</p>
<pre><code class="language-shell">sha256:9c1b6dd6c1e6be9fdd2b1987783824670d3b0dd7ae8ad6f57dc3cea5739ac71e
sha256:1d1a2486e901871ad1257512d588eebb30ae0605d8353abb6635e2d313b2187c
sha256:ec02eb7f3cf4dd78bc518d3a8ccf57f57336ceacb9638303891787ff2ec2e96f
sha256:67bb571b5bd2b65cbdf2c93c6f9dc8e89414055dd7444df617b23466996f3be7
sha256:e83f42350a11889083536c5af330dcf15fd3624f8e956f4086e1f0cfb07ff246
sha256:4b8c655a2e61d6f017f3a5cc103fe6bbb6f71bba663085fdae697861dd57695</code></pre>
<p>myhttpd:p8080</p>
<pre><code class="language-shell">sha256:9c1b6dd6c1e6be9fdd2b1987783824670d3b0dd7ae8ad6f57dc3cea5739ac71e
sha256:1d1a2486e901871ad1257512d588eebb30ae0605d8353abb6635e2d313b2187c
sha256:ec02eb7f3cf4dd78bc518d3a8ccf57f57336ceacb9638303891787ff2ec2e96f
sha256:67bb571b5bd2b65cbdf2c93c6f9dc8e89414055dd7444df617b23466996f3be7
sha256:e83f42350a11889083536c5af330dcf15fd3624f8e956f4086e1f0cfb07ff246
sha256:4b8c655a2e61d6f017f3a5cc103fe6bbb6f71bba663085fdae697861dd57695a
sha256:fffe7ea283ae8867d740e17f619c4db845cb0d75fc655809185e582601786521</code></pre>
<h3 id="docker-history"><code>docker history</code></h3>
<p>이미지 생성 로그 확인</p>
<pre><code class="language-shell">$ docker history &lt;IMAGE&gt;</code></pre>
<h3 id="docker-export"><code>docker export</code></h3>
<p>컨테이너 -&gt; 아카이브</p>
<pre><code class="language-shell">$ docker export &lt;CONTAINER&gt; -o &lt;TARFILE&gt;</code></pre>
<h3 id="docker-import"><code>docker import</code></h3>
<p>아카이브 -&gt; 이미지</p>
<pre><code class="language-shell">$ docker import &lt;TARFILE&gt; &lt;IMAGE&gt;:&lt;TAG&gt;</code></pre>
<blockquote>
<p>1개의 레이어로 가져오기</p>
</blockquote>
<h2 id="⭐️-dockerfile-이미지-생성">⭐️ Dockerfile 이미지 생성</h2>
<h3 id="from">FROM</h3>
<p>Base Image</p>
<pre><code class="language-shell">$ FROM &lt;image&gt;
$ FROM &lt;image&gt;[:&lt;tag&gt;]
$ FROM &lt;image&gt;[@&lt;digest&gt;]</code></pre>
<h3 id="run">RUN</h3>
<p>빌드시 실행할 명령</p>
<p>Shell Form</p>
<pre><code class="language-shell">RUN yum install httpd</code></pre>
<p>=&gt; <code>/bin/sh -c yum install httpd</code></p>
<p>Exec Form</p>
<pre><code class="language-shell">RUN [&quot;yum&quot;, &quot;install&quot;, &quot;httpd&quot;]</code></pre>
<p>=&gt; <code>exec yum install httpd</code></p>
<blockquote>
<p>exec는 명령 X</p>
</blockquote>
<h3 id="cmd">CMD</h3>
<p>기본 실행 어플리케이션</p>
<p>Shell Form</p>
<pre><code class="language-shell">CMD /usr/sbin/httpd -DFOREGROUND</code></pre>
<p>=&gt; <code>/bin/sh -c yum install httpd</code></p>
<p>Exec Form(선호)</p>
<pre><code class="language-shell">CMD [&quot;/usr/sbin/httpd&quot;, &quot;-DFOREGROUND&quot;]</code></pre>
<h3 id="expose">EXPOSE</h3>
<p>외부에 노출할 포트 및 프로토콜</p>
<pre><code class="language-shell">$ EXPOSE &lt;PORT&gt;/&lt;PROTOCOL&gt;</code></pre>
<h3 id="env">ENV</h3>
<p>쉘 환경 변수</p>
<pre><code class="language-shell">ENV MY_NAME=&quot;John Doe&quot;
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy</code></pre>
<h3 id="addcopy">ADD/COPY</h3>
<p>도커 호스트 -&gt; 컨테이너 파일 복사</p>
<pre><code class="language-shell">ADD &lt;SRC&gt; &lt;DEST&gt;
COPY &lt;SRC&gt; &lt;DEST&gt;</code></pre>
<blockquote>
<p>ADD는 SRC로 URL 지정 가능</p>
</blockquote>
<h3 id="entrypoint">ENTRYPOINT</h3>
<p>CMD의 명령으로 사용</p>
<table>
<thead>
<tr>
<th align="center">ENTRYPOINT</th>
<th align="center">CMD</th>
<th align="center">Result</th>
</tr>
</thead>
<tbody><tr>
<td align="center">X</td>
<td align="center">X</td>
<td align="center">허용X</td>
</tr>
<tr>
<td align="center">X</td>
<td align="center">abc</td>
<td align="center">abc</td>
</tr>
<tr>
<td align="center">xyz</td>
<td align="center">X</td>
<td align="center">xyz</td>
</tr>
<tr>
<td align="center">xyz</td>
<td align="center">abc</td>
<td align="center">xyz abc</td>
</tr>
</tbody></table>
<h3 id="volume">VOLUME</h3>
<p>자동으로 마운트할 볼륨 마운트 포인트 지정</p>
<pre><code class="language-shell">VOLUME /myvol</code></pre>
<h3 id="workdir">WORKDIR</h3>
<p>작업 디렉토리
<code>RUN</code>, <code>CMD</code>, <code>ENTRYPOINT</code>, <code>ADD</code>, <code>COPY</code>에 영향을 미침</p>
<pre><code class="language-shell">WORKDIR /usr/local</code></pre>
<h3 id="레이어">레이어</h3>
<p><code>RUN</code>, <code>ADD</code>, <code>COPY</code> 레이어를 만듦</p>
<h2 id="예제">예제</h2>
<pre><code class="language-shell">mkdir -p ~/image-build/myweb
cd ~/image-build/myweb</code></pre>
<p><code>Dockerfile</code></p>
<pre><code class="language-shell">FROM centos:7
RUN yum install -y httpd
ADD index.html /var/www/html/index.html
CMD [&quot;/usr/sbin/httpd&quot;, &quot;-DFOREGROUND&quot; ]
EXPOSE 80/tcp</code></pre>
<p><code>index.html</code></p>
<pre><code class="language-shell">hello dockerfile</code></pre>
<pre><code class="language-shell">docker build -t myweb:centos .</code></pre>
<hr>
<h2 id="linux-timezone-설정">Linux Timezone 설정</h2>
<p><code>/etc/localtime</code> 파일이 가리키고 있는 파일이 시간대</p>
<p>시간대
<code>/usr/share/zoneinfo/*</code></p>
<pre><code class="language-shell">$ sudo ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime</code></pre>
<pre><code class="language-shell">$ sudo timedatectl</code></pre>
<blockquote>
<p>ubuntu 20.04/focal 이미지 부터 시간대가 설정되어 있지 않음
우회: ENV DEBIAN_FRONTEND=noninteractive</p>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>