<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>IT 공부 블로그</title>
    <link>https://study-it-all.tistory.com/</link>
    <description>학교수업, 개인공부 기록용</description>
    <language>ko</language>
    <pubDate>Wed, 17 Jun 2026 12:41:00 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>JJong_H</managingEditor>
    <image>
      <title>IT 공부 블로그</title>
      <url>https://tistory1.daumcdn.net/tistory/5368145/attach/fc74d6e8ffac4bc3b7fbe8a5efb458aa</url>
      <link>https://study-it-all.tistory.com</link>
    </image>
    <item>
      <title>[클라우드 프로그래밍] 컨피그맵과 비밀값</title>
      <link>https://study-it-all.tistory.com/268</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;배경&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너에서 애플리케이션을 실행했을 때의 장점은 다양한 환경의 차이를 원천적으로 없앨 수 있다는 점입니다. 테스트 환경부터 운영 환경까지 전체 배포 절차가 컨테이너 하나의 이미지로 진행될 수도 있습니다. 그러면 테스트 서버에서 수동으로 설치하고 문서에 기재하는 것을 잊은 의존 모듈 때문에 운영 환경에서만 배포가 실패하는 일이 방지됩니다. 하지만 단일 이미지가 아닌 여러 이미지를 함께 운용하는 일이 더 많기 때문에 &lt;u&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;컨테이너 환경 별로 설정 값을 주입&lt;/b&gt;&lt;/span&gt;&lt;/u&gt;할 필요가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스에서 컨테이너에 설정값이 주입하는 데 쓰는 리소스는 &lt;b&gt;컨피그맵(ConfigMap)&lt;/b&gt;과 &lt;b&gt;비밀값(Secret)&lt;/b&gt; 두가지가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨피그맵과 비밀값 역시 kubectl의 create 명령을 사용하거나 YAML 포맷으로 기재된 정의를 읽어 들여 생성 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨피그맵과 비밀값은 스스로 어떤 기능을 하지 않고, 단지 데이터를 저장하는 것이 목적입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드로 전달되어 컨테이너 환경의 일부가 되는데, 이 상태에서 컨테이너가 저장된 데이터를 읽을 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;환경 변수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;:&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;설정 값을 전달하는 일반적인 수단으로 리눅스, 윈도우 등 운영체제가 제공하는 핵심 기능이다&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1781626246035&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 예제 디렉터리 이동
cd ch04

# 설정값 없이 sleep 이미지로 파드 실행
kubectl apply -f sleep/sleep.yaml

# 파드가 준비될 때까지 대기
kubectl wait --for=condition=Ready pod -l app=sleep

# 파드 속 컨테이너에 설정된 몇 가지 환경 변수의 값을 확인
kubectl exec deploy/sleep -- printenv HOSTNAME KIAMOL_CHAPTER&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;103&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpfZud/dJMcahx2WFr/oZFyVPEByraqercx4MfbEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpfZud/dJMcahx2WFr/oZFyVPEByraqercx4MfbEk/img.png&quot; data-alt=&quot;상자 테두리에 가렸지만, 오류 발생하며 종료됨(command terminated with exit code 1)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpfZud/dJMcahx2WFr/oZFyVPEByraqercx4MfbEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpfZud%2FdJMcahx2WFr%2FoZFyVPEByraqercx4MfbEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;730&quot; height=&quot;103&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;103&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;상자 테두리에 가렸지만, 오류 발생하며 종료됨(command terminated with exit code 1)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스가 기본적으로 파드의 이름만 출력되고(HOSTNAME: sleep-568fb49bb7-btsqk), KIAMOL_CHAPTER 환경변수는 출력되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;printenv는 환경 변수의 값을 출력하는 리눅스 명령어입니다. HOSTNAME 환경 변수는 쿠버네티스가 파드 이름을 값으로 모든 컨테이너에 설정합니다. 하지만 KIAMOL_CHAPTER 환경 변수는 정의되지 않은 상태이기 때문에 명령어가 오류 코드와 함께 종료됐습니다.&lt;/p&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;환경 변수가 추가된 파드 정의&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;환경 변수는 파드의 생애 주기 내내 변하지 않는다.&lt;/li&gt;
&lt;li&gt;파드가 실행되는 중에는 환경 변수의 값을 수정할 수 없다.&lt;/li&gt;
&lt;li&gt;파드의 정의를 수정하고 파드를 수정한 버전으로 대체해야 한다.&lt;/li&gt;
&lt;li&gt;&lt;u&gt;&lt;b&gt;.yaml&lt;/b&gt;&lt;/u&gt; 파일의 환경 변수 설정값을 바꾸고 패치 적용.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1781626656364&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 환경 변수가 추가된 파드 정의 업데이트
kubectl apply -f sleep/sleep-with-env.yaml

# 환경 변수의 값 확인
kubectl exec deploy/sleep -- printenv HOSTNAME KIAMOL_CHAPTER&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;* sleep-with-env.yaml 에는 기존(sleep.yaml) 설정에 환경변수 값(KIAMOL_CHAPTER value: &quot;04&quot;)을 추가했습니다.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;62&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwNHwW/dJMcafG1qig/Orafx1FcEVFnfjE1p1eKb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwNHwW/dJMcafG1qig/Orafx1FcEVFnfjE1p1eKb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwNHwW/dJMcafG1qig/Orafx1FcEVFnfjE1p1eKb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwNHwW%2FdJMcafG1qig%2FOrafx1FcEVFnfjE1p1eKb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;731&quot; height=&quot;62&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;62&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 설정이라면 파드 정의에 환경 변수를 포함시켜도 나쁘지 않을 수 있습니다. 그러나 언제나 대규모의 개발을 생각하면 포함시키면 안 됩니다. 실제 애플리케이션의 설정값은 이보다 훨씬 복잡하기 때문입니다. 이럴 땐 컨피그맵을 이용할 수 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;비밀값(Secret)&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;패스워드, API 토큰, SSH 키와 같이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;민감한 정보를 포함하는 설정 정보를 저장하는 리소스&lt;/span&gt;입니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;보안이 필수적인 데이터가 외부로 쉽게 노출되지 않도록 클러스터 내에 안전하게 보관할 수 있는 기능을 제공합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;데이터베이스 로그인 비밀번호, 외부 유료 API 라이센스 키, 암호화 키 등&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;무단으로 노출되면 안 되는 보안 데이터&lt;/span&gt;입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 인코딩: 비밀값에 저장되는 모든 데이터는 눈으로 바로 읽을 수 없도록 Base64 형태로 인코딩되어 저장된다.&lt;/li&gt;
&lt;li&gt;파드에 파일 형태로 비밀값을 마운트하면, 이 파일들은 물리 디스크가 아닌&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;메모리(tmpfs)에만 존재한다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;파드가 삭제되면 사라지므로 데이터 유출을 방지한다.&lt;/li&gt;
&lt;li&gt;해당 비밀값을 필요로 하는 파드가 유효한 노드에 배포될 때만 그 노드로 비밀값이 전송된다. (최소 권한의 원칙)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;컨피그맵(ConfigMap)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션의 &lt;span style=&quot;color: #ee2323;&quot;&gt;일반적인 구성 정보를 저장할 수 있는 리소스입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장된 설정 정보는 컨테이너 환경의 일부처럼 컨테이너 내부로 제공되어 애플리케이션이 이를 읽어 들여 사용할 수 있도록 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 접속 주소, 환경 설정 파일, 애플리케이션의 작동 모드(개발/운영) 등 &lt;span style=&quot;color: #ee2323;&quot;&gt;유출되어도 시스템에 치명적이지 않은 일반 텍스트 데이터&lt;/span&gt;가 대부분입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 형태: 한 개 이상의 키-값 쌍, 텍스트, 바이너리 파일까지 다양합니다.&lt;/li&gt;
&lt;li&gt;파드 하나에 여러 개의 컨피그맵을 전달할 수 있고, 하나의 컨피그맵을 여러 파드에 전달할 수도 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;573&quot; data-origin-height=&quot;563&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBOzfg/dJMcaasaDOk/Wpgy6i2kA7JfkbjOgK0dE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBOzfg/dJMcaasaDOk/Wpgy6i2kA7JfkbjOgK0dE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBOzfg/dJMcaasaDOk/Wpgy6i2kA7JfkbjOgK0dE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBOzfg%2FdJMcaasaDOk%2FWpgy6i2kA7JfkbjOgK0dE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;573&quot; height=&quot;563&quot; data-origin-width=&quot;573&quot; data-origin-height=&quot;563&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;파드 정의에서 컨피그맵 읽어 들이기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정의에서 컨피그맵을 참조한 파드는 해당 컨피그맵이 있어야 클러스터에 배치할 수 있습니다.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt; sleep-with-configMap-env.yaml &lt;/span&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;apiVersion:&amp;nbsp;apps/v1 &lt;br /&gt;kind:&amp;nbsp;Deployment &lt;br /&gt;metadata: &lt;br /&gt;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;sleep &lt;br /&gt;spec: &lt;br /&gt;&amp;nbsp;&amp;nbsp;selector: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;matchLabels: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app:&amp;nbsp;sleep &lt;br /&gt;&amp;nbsp;&amp;nbsp;template: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;metadata: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;labels: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app:&amp;nbsp;sleep &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;spec: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;containers: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;name:&amp;nbsp;sleep &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;image:&amp;nbsp;kiamol/ch03-sleep &lt;br /&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;env:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;컨테이너&amp;nbsp;정의의&amp;nbsp;환경&amp;nbsp;변수&amp;nbsp;부분 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;name:&amp;nbsp;KIAMOL_CHAPTER &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:&amp;nbsp;&quot;04&quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;환경&amp;nbsp;변수의&amp;nbsp;값 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;name:&amp;nbsp;KIAMOL_SECTION &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;valueFrom: &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configMapKeyRef:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;이&amp;nbsp;값은&amp;nbsp;컨피그맵에서&amp;nbsp;읽어&amp;nbsp;들이라는&amp;nbsp;의미 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;sleep-config-literal&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;컨피그맵&amp;nbsp;이름 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key:&amp;nbsp;kiamol.section&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;컨피그맵에서&amp;nbsp;읽어&amp;nbsp;들일&amp;nbsp;항목&amp;nbsp;이름&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키-값 쌍을 데이터로 가진 sleep-config-literal 이라는 이름의 컨피그맵을 만들어 해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;CLI로 데이터 입력하여 컨피그맵 생성&lt;/h3&gt;
&lt;pre id=&quot;code_1781627269180&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 명령행 도구를 사용하여 컨피그맵 생성
kubectl create configmap sleep-config-literal --from-literal=kiamol.section='4.1'

# 컨피그맵에 들어 있는 데이터 확인
kubectl get cm sleep-config-literal

# 컨피그맵의 상세 정보를 보기 좋게 출력
kubectl describe cm sleep-config-literal

# 예제 4-2와 같이 정의가 수정된 파드 배치
kubectl apply -f sleep/sleep-with-configMap-env.yaml

# 파드 속 환경 변수가 적용되었는지 확인
kubectl exec deploy/sleep -- sh -c 'printenv | grep &quot;^KIAMOL&quot;'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;733&quot; data-origin-height=&quot;54&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CYay7/dJMcagMIg8d/PoYopQgQ6EkbB592QOKPKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CYay7/dJMcagMIg8d/PoYopQgQ6EkbB592QOKPKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CYay7/dJMcagMIg8d/PoYopQgQ6EkbB592QOKPKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCYay7%2FdJMcagMIg8d%2FPoYopQgQ6EkbB592QOKPKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;733&quot; height=&quot;54&quot; data-origin-width=&quot;733&quot; data-origin-height=&quot;54&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;컨피그맵에 지정한 설정 파일 사용하기&lt;/h3&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;컨피그맵을 생성하고 만드는 방법&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이전 실습의 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;u&gt;kubectl create configmap &amp;hellip;&lt;/u&gt;&lt;/span&gt; 명령어로 직접 데이터 입력&lt;/li&gt;
&lt;li&gt;환경 변수가 정의된 환경 파일 사용 (ch04.env)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1781627368851&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 한 줄에 하나씩 환경 변수 정의
KIAMOL_CHAPTER=ch04
KIAMOL_SECTION=ch04-4.1
KIAMOL_EXERCISE=try it now&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;쿠버네티스는 이 파일의 내용으로 컨피그맵을 만들어 파드 속 컨테이너에 전달할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1781627395151&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 환경 파일의 내용으로 컨피그맵 생성
kubectl create configmap sleep-config-env-file --from-env-file=sleep/ch04.env

# 컨피그맵의 상세 정보 확인
kubectl get cm sleep-config-env-file

# 새로운 컨피그맵의 설정을 적용하여 파드 업데이트
kubectl apply -f sleep/sleep-with-configMap-env-file.yaml

# 컨테이너에 적용된 환경 변수의 값 확인
kubectl exec deploy/sleep -- sh -c 'printenv | grep &quot;^KIAMOL&quot;'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;147&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nwyRv/dJMcahkyAeN/K6PMH7a8a1vsyyE98jzaJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nwyRv/dJMcahkyAeN/K6PMH7a8a1vsyyE98jzaJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nwyRv/dJMcahkyAeN/K6PMH7a8a1vsyyE98jzaJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnwyRv%2FdJMcahkyAeN%2FK6PMH7a8a1vsyyE98jzaJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;761&quot; height=&quot;147&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;147&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;환경 변수는 생성되었지만, 그 값이 파일에 기재한 값과는 다릅니다. (&quot;ch04&quot;를 기대했음) 배치에 사용된 YAML 파일을 한 번 살펴보겠습니다.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#&lt;u&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;&amp;nbsp;sleep-with-configMap-env-file.yaml&lt;/b&gt;&lt;/span&gt;&lt;/u&gt;, &lt;br /&gt;#&amp;nbsp;여러&amp;nbsp;개의&amp;nbsp;컨피그맵에서&amp;nbsp;설정을&amp;nbsp;읽어&amp;nbsp;들이는&amp;nbsp;파드&amp;nbsp;정의 &lt;br /&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;env&lt;/span&gt;:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;기존&amp;nbsp;env&amp;nbsp;항목 &lt;br /&gt;-&amp;nbsp;name:&amp;nbsp;KIAMOL_CHAPTER &lt;br /&gt;&amp;nbsp;&amp;nbsp;value:&amp;nbsp;&quot;04&quot; &lt;br /&gt;-&amp;nbsp;name:&amp;nbsp;KIAMOL_SECTION &lt;br /&gt;valueFrom: &lt;br /&gt;configMapKeyRef: &lt;br /&gt;name:&amp;nbsp;sleep-config-literal &lt;br /&gt;key:&amp;nbsp;kiamol.section &lt;br /&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;envFrom&lt;/span&gt;:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;envFrom&amp;nbsp;항목에서&amp;nbsp;컨피그맵에서&amp;nbsp;읽어&amp;nbsp;올 &lt;br /&gt;-&amp;nbsp;configMapRef:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;환경&amp;nbsp;변수를&amp;nbsp;정의한다 &lt;br /&gt;name:&amp;nbsp;sleep-config-env-file&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과를 살펴보니 KIAMOL_SECTION, KIAMOL_CHAPTER의 값이 컨피그맵에서 정의한 값과 다릅니다. 분명 ch04로 설정했었는데 말입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드는 컨피그맵에서 모든 환경 변수를 읽어들이는데, 같은 이름의 환경 변수의 값이 직접 설정된 것도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;환경 변수 이름이 중복되는 경우 env 항목에서 정의된 값이 envFrom 항목에서 정의된 값 보다 우선순위가 높은 것입니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 우선순위의 존재로 컨테이너 이미지나 컨피그맵에서 정의된 환경 변수의 값을 파드 정의에서 간단히 수정할 수 있어 편리하고, 환경 변수의 값을 바꾸어 가며 문제가 발생한 위치를 특정할 수도 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;다양한 우선순위를 가진 설정값&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;u&gt;todo-web.yaml&lt;/u&gt;&lt;/span&gt;, 구조화된 설정값을 읽어 들이는 애플리케이션&lt;/span&gt; &lt;/h4&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;spec: &lt;br /&gt;&amp;nbsp; &amp;nbsp; containers: &lt;br /&gt;&lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; -&amp;nbsp;name:&amp;nbsp;web &lt;br /&gt;&lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&amp;nbsp; &amp;nbsp;image: kiamol/ch04-todo-list &lt;br /&gt;&lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; env:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;로그에&amp;nbsp;'Warning'이상의&amp;nbsp;메시지만&amp;nbsp;골라서&amp;nbsp;기록하라는&amp;nbsp;환경&amp;nbsp;설정 &lt;br /&gt;&lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt; -&amp;nbsp;name:&amp;nbsp;Logging__LogLevel__Default &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt; &lt;span style=&quot;background-color: #fafafa; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp;value: Warning&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;todo-web.yaml 파일로 애플리케이션을 실행하면 정의에서 환경 변수로 새로 설정한 로그 수준을 제외한 모든 설정에 이미지에 포함된 JSON 설정 파일의 값이 적용된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1781627710004&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 서비스와 함께 애플리케이션 배치
kubectl apply -f todo-list/todo-web.yaml

# 파드가 준비 상태가 될 때까지 대기
kubectl wait --for=condition=Ready pod -l app=todo-web

# 애플리케이션에 접근하기 위한 주소를 파일로 출력
kubectl get svc todo-web -o jsonpath='http://{.status.loadBalancer.ingress[0].*}:8080'
# External-ip가 안나오면, kubectl port-forward --address 0.0.0.0 svc/todo-web 8080:8080

# 웹 브라우저에서 애플리케이션에 접근한 후 기능 점검
# 그다음 경로 /config에 접근&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1043&quot; data-origin-height=&quot;457&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9thDY/dJMcaiXWnFo/Vxjd2AMthpeLsLiKsiQBmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9thDY/dJMcaiXWnFo/Vxjd2AMthpeLsLiKsiQBmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9thDY/dJMcaiXWnFo/Vxjd2AMthpeLsLiKsiQBmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9thDY%2FdJMcaiXWnFo%2FVxjd2AMthpeLsLiKsiQBmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1043&quot; height=&quot;457&quot; data-origin-width=&quot;1043&quot; data-origin-height=&quot;457&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;98&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lG2s1/dJMcaiDIkPB/XixR6sHakPHjNtCc3JY3bK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lG2s1/dJMcaiDIkPB/XixR6sHakPHjNtCc3JY3bK/img.png&quot; data-alt=&quot;하지만 /config 로 접속은 불가하다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lG2s1/dJMcaiDIkPB/XixR6sHakPHjNtCc3JY3bK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlG2s1%2FdJMcaiDIkPB%2FXixR6sHakPHjNtCc3JY3bK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;478&quot; height=&quot;98&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;98&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;하지만 /config 로 접속은 불가하다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션의 현재 설정값을 확인할 수 있어야 하지만 지금은 404 오류를 일으키고 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1781628986458&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 애플리케이션 로그 확인
kubectl logs -l app=todo-web&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;483&quot; data-origin-height=&quot;87&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cg6DzZ/dJMcaaZXUVD/AnIQW04z6CK9QjfEIKKkSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cg6DzZ/dJMcaaZXUVD/AnIQW04z6CK9QjfEIKKkSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cg6DzZ/dJMcaaZXUVD/AnIQW04z6CK9QjfEIKKkSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcg6DzZ%2FdJMcaaZXUVD%2FAnIQW04z6CK9QjfEIKKkSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;483&quot; height=&quot;87&quot; data-origin-width=&quot;483&quot; data-origin-height=&quot;87&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정값 확인 페이지에 접근 시도가 있었다는 경고 메시지가 출력됐습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;/config 페이지에서는 애플리케이션의 모든 설정값을 보여 주는 기능을 제공한다.&lt;/li&gt;
&lt;li&gt;/config기능이 기본 설정값으로 꺼져 있어(&quot;ConfigController&quot;: { &quot;Enabled&quot;: false }) 404 오류가 발생한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;span style=&quot;background-color: #ffffff; color: #ef5369; text-align: start;&quot;&gt; todo-web-config-dev.yaml&lt;/span&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;apiVersion:&amp;nbsp;v1 &lt;br /&gt;kind:&amp;nbsp;ConfigMap&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;리소스&amp;nbsp;유형은&amp;nbsp;컨피그맵이다 &lt;br /&gt;metadata: &lt;br /&gt;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;todo-web-config-dev&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;컨피그맵&amp;nbsp;이름을&amp;nbsp;지정한다 &lt;br /&gt;data: &lt;br /&gt;&amp;nbsp;&amp;nbsp;config.json:&amp;nbsp;|-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;키-값&amp;nbsp;쌍의&amp;nbsp;키&amp;nbsp;이름이&amp;nbsp;파일&amp;nbsp;이름이&amp;nbsp;된다 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;파일&amp;nbsp;내용은&amp;nbsp;어떤&amp;nbsp;포맷이라도&amp;nbsp;가능하다 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;ConfigController&quot;:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Enabled&quot;&amp;nbsp;:&amp;nbsp;true &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;우선순위&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;&lt;b&gt;파드 정의를 통해 외부에서 주입해 준 설정(컨피그맵)&lt;/b&gt; &amp;gt; 컨테이너 이미지 내부의 기본 설정파일&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1781627848225&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# JSON이 담긴 컨피그맵 생성
kubectl apply -f todo-list/configMaps/todo-web-config-dev.yaml

# 컨피그맵을 참조하도록 애플리케이션 업데이트
kubectl apply -f todo-list/todo-web-dev.yaml

# 애플리케이션에 접근하기 위한 주소를 파일로 출력
kubectl get svc todo-web -o jsonpath='http://{.status.loadBalancer.ingress[0].*}:8080'
# External-ip가 안나오면, kubectl port-forward --address 0.0.0.0 svc/todo-web 8080:8080

# 웹 브라우저에서 /config 페이지 새로 고침&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;149&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/63bYr/dJMcagFWGt3/3Rik8lY4wJYyLyb7bt4Rjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/63bYr/dJMcagFWGt3/3Rik8lY4wJYyLyb7bt4Rjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/63bYr/dJMcagFWGt3/3Rik8lY4wJYyLyb7bt4Rjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F63bYr%2FdJMcagFWGt3%2F3Rik8lY4wJYyLyb7bt4Rjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;768&quot; height=&quot;149&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;149&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정할 데이터가 담긴 컨피그맵을 생성한 후 디플로이먼트를 컨피그맵을 참조하도록 업데이트했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;696&quot; data-origin-height=&quot;541&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2w71S/dJMcajiiSDf/AJHWEezePNwP73ktaUdHy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2w71S/dJMcajiiSDf/AJHWEezePNwP73ktaUdHy0/img.png&quot; data-alt=&quot;성공&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2w71S/dJMcajiiSDf/AJHWEezePNwP73ktaUdHy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2w71S%2FdJMcajiiSDf%2FAJHWEezePNwP73ktaUdHy0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;696&quot; height=&quot;541&quot; data-origin-width=&quot;696&quot; data-origin-height=&quot;541&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;성공&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스는 변경되지 않았으나 기존 외부 IP 주소가 새로 생성된 파드를 가리킵니다. 이 파드에는 컨피그맵으로 주입된 설정값이 적용되어 설정값 페이지를 볼 수 있는 것입니다.&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;컨피그맵에 담긴 설정값 데이터 주입하기&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;환경 변수 외에 설정값을 전달하는 또 다른 방법은 컨테이너 파일 시스템 속 파일로 설정값을 주입하는 것입니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너 파일 시스템은 컨테이너 이미지와 그 외 출처에서 온 파일로 구성되는 가상 구조입니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;컨피그맵은 디렉터리, 각 항목은 파일 형태로 컨테이너 파일 시스템에 추가 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;642&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdsBNS/dJMcaicHcD0/hsA8I1FW60udEBxoX25FKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdsBNS/dJMcaicHcD0/hsA8I1FW60udEBxoX25FKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdsBNS/dJMcaicHcD0/hsA8I1FW60udEBxoX25FKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdsBNS%2FdJMcaicHcD0%2FhsA8I1FW60udEBxoX25FKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;642&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;642&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정값 주입 과정에 파드 정의의 두 가지 항목과 관련된 기능이 관여합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컨피그맵에 담긴 데이터를 파드로 전달하는 &lt;u&gt;&lt;b&gt;볼륨(volume)&lt;/b&gt;&lt;/u&gt;&lt;/li&gt;
&lt;li&gt;컨피그맵을 읽어 들인 볼륨을 파드 컨테이너의 특정 경로에 위치시키는 &lt;u&gt;&lt;b&gt;볼륨 마운트(volume mount)&lt;/b&gt;&lt;/u&gt;&lt;u&gt;&lt;b&gt;&lt;/b&gt;&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1781628130833&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; spec:
  containers:
    - name: web
      image: kiamol/ch04-todo-list
      volumeMounts:                   # 컨테이너에 볼륨을 마운트한다
        - name: config                # 마운트할 볼륨 이름
          mountPath: &quot;/app/config&quot;    # 볼륨이 마운트될 경로
          readOnly: true              # 볼륨을 읽기 전용으로
  volumes:                            # 볼륨은 파드 수준에서 정의된다
    - name: config                    # 이 이름이 볼륨 마운트의 이름과 일치해야 한다
      configMap:                      # 볼륨의 원본은 컨피그맵이다
        name: todo-web-config-dev     # 내용을 읽어 올 컨피그맵 이름&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;위 예제의 애플리케이션은 /app/appsettings.json 파일에서 기본 설정을 읽어 오며, 그 다음으로 /app/config/config.json 파일을 찾아 설정값을 우선 적용한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1781628163090&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 기본 설정값이 담긴 설정 파일 확인
kubectl exec deploy/todo-web -- sh -c 'ls -l /app/app*.json'

# 볼륨 마운트로 주입된 설정 파일 확인
kubectl exec deploy/todo-web -- sh -c 'ls -l /app/config/*.json'

# 볼륨 마운트가 실제로 읽기 전용인지 확인
kubectl exec deploy/todo-web -- sh -c 'echo ch04 &amp;gt;&amp;gt; /app/config/config.json'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;177&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEw4ht/dJMcaayWdSv/KVOO8wFnoXWH77V4AqO1kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEw4ht/dJMcaayWdSv/KVOO8wFnoXWH77V4AqO1kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEw4ht/dJMcaayWdSv/KVOO8wFnoXWH77V4AqO1kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEw4ht%2FdJMcaayWdSv%2FKVOO8wFnoXWH77V4AqO1kk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;764&quot; height=&quot;177&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;177&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;컨테이너 이미지에서 온 기본 설정 파일입니다. 이 파일의 권한(-rw-r--r--&amp;nbsp;)은 이미지에서 설정됐습니다.&lt;/li&gt;
&lt;li&gt;이 파일은 컨피그맵의 데이터를 읽어 들인 환경 설정 파일입니다.&lt;/li&gt;
&lt;li&gt;이 파일의 권한은 읽기 쓰기가 가능하다고 나오지만, 읽기 전용 파일을 가리키는 링크이므로 실행 결과에서보듯 파일을 수정할 수 없습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주입된 컨피그맵 /app/config/config.json 파일이 읽기 전용(readOnly: true)이기 때문에 덮어쓰기(ehco ch04 &amp;gt;&amp;gt;) 명령이 실패한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;컨피그맵을 디렉터리 형태로 읽어들여 다양한 애플리케이션 설정 방법을 적용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1781628190135&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# todo-web-config-dev-with-logging.yaml, 두 개의 설정 파일을 담은 컨피그맵
data:
  config.json: |-              # 기존 설정 파일
    {
      &quot;ConfigController&quot;: {
            &quot;Enabled&quot; : true
      }
    }
  logging.json: |-             # 볼륨 마운트로 전달될 두 번째 설정 파일
    {
      &quot;Logging&quot;: {
        &quot;LogLevel&quot;: {
          &quot;ToDoList.Pages&quot; : &quot;Debug&quot;
        }
      }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;컨피그맵을 업데이트하여 애플리케이션 설정 수정&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1781628209379&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 애플리케이션 로그 확인
kubectl logs -l app=todo-web

# 컨피그맵 업데이트
kubectl apply -f todo-list/configMaps/todo-web-config-dev-with-logging.yaml

# 업데이트된 컨피그맵이 파드에 반영될 때까지 대기
sleep 120

# 설정 파일에 반영되었는지 확인
kubectl exec deploy/todo-web -- sh -c 'ls -l /app/config/*.json'

# 애플리케이션에 접근하여 로그 출력이 변화했는지 확인
# kubectl port-forward --address 0.0.0.0 svc/todo-web 8080:8080
kubectl logs -l app=todo-web&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;볼륨은 설정 파일을 다루는 강력한 수단이 됩니다. 실습 to-do 애플리케이션처럼 설정 파일의 변경에 곧바로 반응하는 앱이라면 더욱 효과가 클 것입니다..&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;애플리케이션을 재시작하지 않아도 로그 수준을 변경할 수 있다면 문제가 발생한 지점을 특정하는 데 큰 도움을 줍니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;환경 변수 방식(env, envFrom)은 컨테이너가 켜질 때 값을 주입받기 때문에, 중간에 컨피그맵을 바꿔도 이미 실행 중인 프로그램에는 반영되지 않습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;볼륨 마운트가 의도한 대로 동작하지 않을 수 도 있기 때문에 설정에 주의가 필요하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;볼륨의 마운트 경로&lt;/b&gt;가 &lt;b&gt;이미 컨테이너 이미지에 있는 경로&lt;/b&gt;라면, 컨피그맵 디렉터리가 원래 디렉터리를 덮어쓰고 디렉터리의 모든 내용이 교체된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;515&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dSiwaa/dJMcaiDIk5h/1YtmBFUu3wv1xjRl0olUs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dSiwaa/dJMcaiDIk5h/1YtmBFUu3wv1xjRl0olUs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dSiwaa/dJMcaiDIk5h/1YtmBFUu3wv1xjRl0olUs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdSiwaa%2FdJMcaiDIk5h%2F1YtmBFUu3wv1xjRl0olUs0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;680&quot; height=&quot;515&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;515&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;비교하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 가지 리소스 &lt;span style=&quot;color: #ef5369;&quot;&gt;모두 포맷 제한 없이&lt;/span&gt; 데이터를 보유할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터는 클러스터 속에서 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;다른 리소스와 독립적인 장소에 보관됩니다.&lt;/b&gt;&lt;/span&gt; (마스터노드의 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;etcd&lt;/b&gt;&lt;/span&gt;라는 독립된 공간)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드 정의에서 컨피그맵과 비밀값의 데이터를 읽어 오도록 할 수 있습니다. (YAML 파일에 정의 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 파드에 데이터가 전달되는 과정에도 다양한 설정이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>클라우드/AWS</category>
      <author>JJong_H</author>
      <guid isPermaLink="true">https://study-it-all.tistory.com/268</guid>
      <comments>https://study-it-all.tistory.com/268#entry268comment</comments>
      <pubDate>Wed, 17 Jun 2026 02:09:21 +0900</pubDate>
    </item>
    <item>
      <title>[클라우드 프로그래밍] 9주차 쿠버네티스 서비스의 해소 과정</title>
      <link>https://study-it-all.tistory.com/267</link>
      <description>&lt;div style=&quot;color: #333333; text-align: start;&quot; data-block-id=&quot;35f29c42-6f46-80b2-8110-f2841d838152&quot;&gt;
&lt;div&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f;&quot;&gt;쿠버네티스 서비스의 해소 과정&lt;/span&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;쿠버네티스는 서비스 리소스를 사용할 때 필요할 법한 대부분의 네트워크 설정을 제공한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;파드에서 동작하며 다른 파드와 통신하는 애플리케이션 컴포넌트도 표준 전송 프로토콜과 DNS 네임을 사용하여 서로를 찾아낸다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;특별한 코드나 라이브러리는 필요 없으며 애플리케이션을 물리 서버나 가상 서버에 배포했을 때와 다를 것이 없다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/egnMkS/dJMcacDxyEO/T5RolYucuWEphckLT0wrVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/egnMkS/dJMcacDxyEO/T5RolYucuWEphckLT0wrVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/egnMkS/dJMcacDxyEO/T5RolYucuWEphckLT0wrVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FegnMkS%2FdJMcacDxyEO%2FT5RolYucuWEphckLT0wrVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;645&quot; height=&quot;410&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;클러스터IP&lt;/b&gt;는 네트워크상에 실재하지 않는 &lt;b&gt;가상 IP 주소&lt;/b&gt;이다. &lt;br /&gt;&amp;rarr; 물리적으로 할당된 주소가 아니고, SW에서 정의한 논리적 주소&lt;/li&gt;
&lt;li&gt;파드가 밖으로 데이터를 보낼 때, 파드는 각 노드마다 동작하는 &lt;b&gt;네트워크 프록시&lt;/b&gt;를 경유하여 네트워크에 접근한다.&lt;/li&gt;
&lt;li&gt;그리고 이 프록시는 패킷 필터링을 적용하여 가상 IP 주소를 실제 엔드포인트로 연결한다.&lt;/li&gt;
&lt;li&gt;서비스 리소스는 삭제될 때까지 IP 주소가 바뀌지 않으며 애플리케이션의 다른 부분과 무관하게 오래 지속될 수 있다.&lt;/li&gt;
&lt;li&gt;서비스에도 컨트롤러가 있어 파드가 변경될 때마다 엔드포인트의 목록을 최신으로 업데이트한다.&lt;/li&gt;
&lt;li&gt;따라서 클라이언트는 가상 정적 IP와 네트워크 프록시만 있으면 항상 최신 상태의 엔드포인트 목록을 적용받는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;678&quot; data-origin-height=&quot;486&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oLQv0/dJMcadPRZ4I/6jbNFDEIycCM5dtCk5OXzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oLQv0/dJMcadPRZ4I/6jbNFDEIycCM5dtCk5OXzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oLQv0/dJMcadPRZ4I/6jbNFDEIycCM5dtCk5OXzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoLQv0%2FdJMcadPRZ4I%2F6jbNFDEIycCM5dtCk5OXzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;678&quot; height=&quot;486&quot; data-origin-width=&quot;678&quot; data-origin-height=&quot;486&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;엔드포인트 목록 출력&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;엔드포인트(Endpoint)란&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;서비스에 연결된 모든 파드의 IP와 포트 정보를 가진 객체로, 실시간으로 파드가 생성되거나 삭제되면, 쿠버네티스가 이를 감지하여 엔드포이트 목록에서 해당 IP를 수정한다.&lt;/p&gt;
&lt;pre id=&quot;code_1781624628264&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# sleep-2 서비스의 엔드포인트 목록 출력
kubectl get endpoints sleep-2

# 파드 삭제
kubectl delete pods -l app=sleep-2

# 엔드포인트가 새로운 파드의 주소로 업데이트되었는지 확인
kubectl get endpoints sleep-2

# 디플로이먼트 채로 삭제
kubectl delete deploy sleep-2

# 엔드포인트는 여전히 있지만, 가리키는 IP 주소가 없음
kubectl get endpoints sleep-2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;509&quot; data-origin-height=&quot;293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMiWdD/dJMcacpZxWO/8T8jRqie3rLuFSevsIofD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMiWdD/dJMcacpZxWO/8T8jRqie3rLuFSevsIofD1/img.png&quot; data-alt=&quot;ENDPOINT 주소가 변화하는 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMiWdD/dJMcacpZxWO/8T8jRqie3rLuFSevsIofD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMiWdD%2FdJMcacpZxWO%2F8T8jRqie3rLuFSevsIofD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;509&quot; height=&quot;293&quot; data-origin-width=&quot;509&quot; data-origin-height=&quot;293&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ENDPOINT 주소가 변화하는 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;모든 쿠버네티스 리소스는 네임스페이스 안에 존재한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;네임스페이스는 쉽게 말해 다른 리소스를 하나로 묶기 위한 리소스다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;쿠버네티스에서 네임스페이스는 하나의 물리적인 클러스터를 여러 개의 논리적인 가상 클러스터로 나누는 방법이다. (하나의 컴퓨터 안에 여러 개의 폴더를 만들어 파일을 정리하는 것)&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;네임스페이스 조회&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1781624676716&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# default 네임스페이스의 서비스 리소스 목록 확인
kubectl get svc --namespace default

# 쿠버네티스 시스템 네임스페이스의 서비스 리소스 목록 확인
kubectl get svc -n kube-system

# 완전한 도메인 네임으로 DNS 조회하기
kubectl exec deploy/sleep-1 -- sh -c 'nslookup numbers-api.default.svc.cluster.local | grep &quot;^[^*]&quot;'

# 쿠버네티스 시스템 네임스페이스의 완전한 도메인 네임으로 DNS 조회하기
kubectl exec deploy/sleep-1 -- sh -c 'nslookup kube-dns.kube-system.svc.cluster.local | grep &quot;^[^*]&quot;'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/372Q4/dJMcajvQKls/WDzk4ElsT90MsitF2Qaeb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/372Q4/dJMcajvQKls/WDzk4ElsT90MsitF2Qaeb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/372Q4/dJMcajvQKls/WDzk4ElsT90MsitF2Qaeb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F372Q4%2FdJMcajvQKls%2FWDzk4ElsT90MsitF2Qaeb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;766&quot; height=&quot;380&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kubectl의 namespace 파라미터로 대상 네임스페이스를 지정할 수 있습니다. 이 출력 결과는 default 네임스페이스에 속한 서비스 목록입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 2번째 박스 안의 목록은 kube-system 네임스페이스의 서비스 목록입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sleep-1 파드에서 요청한 DNS 조회에 서비스의 완전한 이름이 반환되었습니다. 이때 DNS 서버의 주소(10.96.0.10)도 함께 출력되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kube-system 네임스페이스에 있는 kube-dns 서비스에 대한 DNS 조회 결과입니다. 앞서 본 DNS 서버 주소와 일치하는 모습입니다. &lt;b&gt;kube-dns 서비스가 바로 클러스터의 내부 DNS 서버였던 것입니다&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;디플로이먼트 삭제&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1781624689283&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 모든 디플로이먼트 삭제
kubectl delete deploy --all

# 모든 서비스 삭제
kubectl delete svc --all

# 남아 있는 리소스 확인
kubectl get all&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;239&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHIZ79/dJMcagZ82Qi/BmpEyqIKAKRvsqtkVQCsQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHIZ79/dJMcagZ82Qi/BmpEyqIKAKRvsqtkVQCsQK/img.png&quot; data-alt=&quot;깔끔하게 모두 지워진 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHIZ79/dJMcagZ82Qi/BmpEyqIKAKRvsqtkVQCsQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHIZ79%2FdJMcagZ82Qi%2FBmpEyqIKAKRvsqtkVQCsQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;452&quot; height=&quot;239&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;239&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;깔끔하게 모두 지워진 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>클라우드/AWS</category>
      <category>K8s</category>
      <category>쿠버네티스</category>
      <author>JJong_H</author>
      <guid isPermaLink="true">https://study-it-all.tistory.com/267</guid>
      <comments>https://study-it-all.tistory.com/267#entry267comment</comments>
      <pubDate>Wed, 17 Jun 2026 00:59:02 +0900</pubDate>
    </item>
    <item>
      <title>[클라우드 프로그래밍] 9주차 헤드리스 서비스</title>
      <link>https://study-it-all.tistory.com/266</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 헤드리스(Headless) 서비스란&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적인 서비스(클러스터IP)는 앞단에 가상IP를 하나 두고, 외부 요청이 들어오면 뒤에 있는 파드들에게 트래픽을 골고루 나눠줍니다(로드밸런싱).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 &lt;b&gt;헤드리스(Headless) 서비스&lt;/b&gt;는 이름 그대로 '&lt;b&gt;머리(대표IP)'가 없는 서비스&lt;/b&gt;입니다. YAML 설정 파일에 &lt;u&gt;clusterIP: None&lt;/u&gt; 이라고 선언해서 만듭니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;6,0,0&quot;&gt;어떻게 동작하나요?&lt;/b&gt; 클라이언트가 쿠버네티스 DNS에 헤드리스 서비스의 이름을 물어보면, 대표 IP를 알려주는 대신 &lt;b data-index-in-node=&quot;64&quot; data-path-to-node=&quot;6,0,0&quot;&gt;서비스와 연결된 모든 파드들의 '실제 IP 목록'을 통째로 반환&lt;/b&gt;해 줍니다. (DNS A 레코드 반환)&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;6,1,0&quot;&gt;왜 쓸까요?&lt;/b&gt; 쿠버네티스가 해주는 멍청한(단순 라운드로빈) 로드밸런싱을 거치지 않고, &lt;b data-index-in-node=&quot;47&quot; data-path-to-node=&quot;6,1,0&quot;&gt;클라이언트가 직접 파드의 IP를 골라서 통신하고 싶을 때&lt;/b&gt; 사용합니다. 주로 마스터-슬레이브 구조가 있는 데이터베이스(StatefulSet)처럼, 각각의 파드가 서로 다른 역할을 가져서 콕 집어서 통신해야 할 때 필수적으로 쓰입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-path-to-node=&quot;7&quot; data-ke-size=&quot;size23&quot;&gt;2. 익스터널네임(ExternalName) 서비스란?&lt;/h3&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;익스터널네임 서비스는 파드들을 묶어주는 용도가 아니라, 쿠버네티스 클러스터 '외부'에 있는 주소를 클러스터 '내부'의 별명으로 연결해 주는 일종의 '단축 링크'입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;9&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,0,0&quot;&gt;어떻게 동작하나요?&lt;/b&gt; 클라이언트가 DNS에 이 서비스 이름을 물어보면, &quot;어, 그 이름은 사실 저기 바깥에 있는 웹사이트 주소야!&quot;라며 &lt;b data-index-in-node=&quot;75&quot; data-path-to-node=&quot;9,0,0&quot;&gt;외부 URL(CNAME 레코드)을 그대로 반환&lt;/b&gt;합니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,1,0&quot;&gt;왜 쓸까요?&lt;/b&gt; 만약 클러스터 안의 파드가 외부의 AWS RDS 데이터베이스(my-db.ap-northeast-2.rds.amazonaws.com)에 접속해야 한다고 가정해 보겠습니다. 이 긴 주소를 파드 코드에 직접 하드코딩하면 나중에 주소가 바뀌었을 때 파드를 전부 다시 빌드해야 합니다. 대신 클러스터 안에 dev-database라는 이름으로 ExternalName 서비스를 만들어 두면, 파드는 그저 dev-database로만 접속을 시도하고 쿠버네티스 DNS가 알아서 외부 주소로 토스해 주어 관리가 훨씬 편해집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;차이점 요약&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-path-to-node=&quot;13&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.5581%;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 47.093%;&quot;&gt;&lt;b&gt;헤드리스 (Headless)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.2326%;&quot;&gt;&lt;b&gt;익스터널네임 (ExternalName)&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.5581%;&quot;&gt;&lt;span data-path-to-node=&quot;13,1,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;13,1,0,0&quot;&gt;목적지&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 47.093%;&quot;&gt;&lt;span data-path-to-node=&quot;13,1,1,0&quot;&gt;클러스터 &lt;b data-index-in-node=&quot;5&quot; data-path-to-node=&quot;13,1,1,0&quot;&gt;내부&lt;/b&gt;의 개별 파드들&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.2326%;&quot;&gt;&lt;span data-path-to-node=&quot;13,1,2,0&quot;&gt;클러스터 &lt;b data-index-in-node=&quot;5&quot; data-path-to-node=&quot;13,1,2,0&quot;&gt;외부&lt;/b&gt;의 도메인/서비스&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.5581%;&quot;&gt;&lt;span data-path-to-node=&quot;13,2,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;13,2,0,0&quot;&gt;ClusterIP&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 47.093%;&quot;&gt;&lt;span data-path-to-node=&quot;13,2,1,0&quot;&gt;없음 (None)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.2326%;&quot;&gt;&lt;span data-path-to-node=&quot;13,2,2,0&quot;&gt;사용 안 함 (개념이 다름)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.5581%;&quot;&gt;&lt;span data-path-to-node=&quot;13,3,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;13,3,0,0&quot;&gt;DNS 반환 값&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 47.093%;&quot;&gt;&lt;span data-path-to-node=&quot;13,3,1,0&quot;&gt;연결된 &lt;b data-index-in-node=&quot;4&quot; data-path-to-node=&quot;13,3,1,0&quot;&gt;파드들의 개별 사설 IP 목록&lt;/b&gt; (A 레코드)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.2326%;&quot;&gt;&lt;span data-path-to-node=&quot;13,3,2,0&quot;&gt;설정해 둔 &lt;b data-index-in-node=&quot;6&quot; data-path-to-node=&quot;13,3,2,0&quot;&gt;외부 도메인 이름&lt;/b&gt; (CNAME 레코드)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.5581%;&quot;&gt;&lt;span data-path-to-node=&quot;13,4,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;13,4,0,0&quot;&gt;주요 용도&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 47.093%;&quot;&gt;&lt;span data-path-to-node=&quot;13,4,1,0&quot;&gt;DB 클러스터링 (StatefulSet), 클라이언트 측 직접 라우팅&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.2326%;&quot;&gt;&lt;span data-path-to-node=&quot;13,4,2,0&quot;&gt;외부 클라우드 DB 연동, 레거시 시스템 연결&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1781624353778&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 기존 서비스를 제거한다
kubectl delete svc numbers-api

# 헤드리스 서비스를 배포한다
kubectl apply -f numbers-services/api-service-headless.yaml

# 서비스의 상세 정보를 확인한다
kubectl get svc numbers-api

# 엔드포인트의 상세 정보를 확인한다
kubectl get endpoints numbers-api

# DNS 조회 결과를 확인한다
kubectl exec deploy/sleep-1 -- sh -c 'nslookup numbers-api | grep &quot;^[^*]&quot;'

# 웹 브라우저에서 웹 페이지를 확인한다
# 새로운 무작위 숫자를 생성하면 오류가 발생한다&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;53&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yY5dS/dJMcabR4DDx/mLkVCAa1fWyJfuYvoYjLFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yY5dS/dJMcabR4DDx/mLkVCAa1fWyJfuYvoYjLFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yY5dS/dJMcabR4DDx/mLkVCAa1fWyJfuYvoYjLFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyY5dS%2FdJMcabR4DDx%2FmLkVCAa1fWyJfuYvoYjLFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;53&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;53&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스가 가진 엔드포인트에서 클러스터IP가 실제 연결하는 주소(하지만 실재하지 않는)를 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;771&quot; data-origin-height=&quot;99&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuG4T1/dJMcaiKqeI5/FuE8EtGwkWlQW3BajO0QB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuG4T1/dJMcaiKqeI5/FuE8EtGwkWlQW3BajO0QB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuG4T1/dJMcaiKqeI5/FuE8EtGwkWlQW3BajO0QB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuG4T1%2FdJMcaiKqeI5%2FFuE8EtGwkWlQW3BajO0QB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;771&quot; height=&quot;99&quot; data-origin-width=&quot;771&quot; data-origin-height=&quot;99&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>클라우드/AWS</category>
      <category>K8s</category>
      <category>쿠버네티스</category>
      <author>JJong_H</author>
      <guid isPermaLink="true">https://study-it-all.tistory.com/266</guid>
      <comments>https://study-it-all.tistory.com/266#entry266comment</comments>
      <pubDate>Wed, 17 Jun 2026 00:42:42 +0900</pubDate>
    </item>
    <item>
      <title>[클라우드 프로그래밍] 9주차 외부 트래픽을 파드로 전달 / 노드포트</title>
      <link>https://study-it-all.tistory.com/265</link>
      <description>&lt;h3 data-path-to-node=&quot;2&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;2&quot;&gt;로드밸런서(LoadBalancer) 서비스 유형&lt;/b&gt;&lt;/h3&gt;
&lt;p id=&quot;p-rc_8053bf7d7a371352-120&quot; data-path-to-node=&quot;3&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span data-path-to-node=&quot;3,0&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;3,1&quot;&gt;&lt;span&gt;앞서 살펴본 클러스터IP(ClusterIP)는 클러스터 내부에 있는 리소스들끼리 안전하게 통신할 때 사용됩니다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;3,2&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;3,3&quot;&gt;. &lt;/span&gt;&lt;span data-path-to-node=&quot;3,4&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;3,5&quot;&gt;&lt;span&gt;하지만 실제 서비스를 운영하려면 클러스터 외부에서 들어오는 사용자의 트래픽을 파드로 전달해 줄 수 있어야 합니다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;3,6&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;3,7&quot;&gt;. &lt;/span&gt;&lt;span data-path-to-node=&quot;3,8&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;3,9&quot;&gt;&lt;span&gt;이를 가장 간단하고 유연하게 해결해 주는 방법이 바로 &lt;/span&gt;&lt;b data-index-in-node=&quot;30&quot; data-path-to-node=&quot;3,9&quot;&gt;&lt;span&gt;로드밸런서(LoadBalancer)&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 유형의 서비스입니다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;3,10&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;3,11&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;p-rc_8053bf7d7a371352-121&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span data-path-to-node=&quot;4,0&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;4,1&quot;&gt;&lt;span&gt;로드밸런서 서비스의 가장 큰 장점은 &lt;/span&gt;&lt;b data-index-in-node=&quot;20&quot; data-path-to-node=&quot;4,1&quot;&gt;&lt;span&gt;클러스터 전체를 커버한다&lt;/span&gt;&lt;/b&gt;&lt;span&gt;는 점입니다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;4,2&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;4,3&quot;&gt;. &lt;/span&gt;&lt;span data-path-to-node=&quot;4,4&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;4,5&quot;&gt;&lt;span&gt;트래픽이 특정 노드로 들어오더라도, 대상 파드가 반드시 해당 노드에 있을 필요는 없습니다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;4,6&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;4,7&quot;&gt;. &lt;/span&gt;&lt;span data-path-to-node=&quot;4,8&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;4,9&quot;&gt;&lt;span&gt;설령 파드가 다른 노드에서 실행 중이더라도 로드밸런서가 알아서 올바른 노드와 파드로 트래픽을 안전하게 중계해 줍니다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;4,10&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;4,11&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;p-rc_8053bf7d7a371352-122&quot; data-path-to-node=&quot;5&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span data-path-to-node=&quot;5,0&quot;&gt;이것이 가능한 이유는 쿠버네티스가 내부적으로 파드의 위치를 일일이 탐색하는 비효율적인 방식을 쓰지 않기 때문입니다. &lt;/span&gt;&lt;span data-path-to-node=&quot;5,1&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;5,2&quot;&gt;&lt;span&gt;대신 쿠버네티스는 조건에 맞는 파드들의 실제 IP 주소 목록(엔드포인트)을 직접 실시간으로 관리합니다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;5,3&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;5,4&quot;&gt;. &lt;/span&gt;&lt;span data-path-to-node=&quot;5,5&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;5,6&quot;&gt;&lt;span&gt;트래픽이 인입되면 이 리스트를 바탕으로 가장 적절한 파드를 다이렉트로 골라 연결해 주기 때문에, 노드의 위치와 상관없이 신속하고 정확한 로드밸런싱이 이루어집니다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;5,7&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;5,8&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;576&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdBgyb/dJMcaasaAuX/JuOI8MO6p716YEpjQy4mV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdBgyb/dJMcaasaAuX/JuOI8MO6p716YEpjQy4mV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdBgyb/dJMcaasaAuX/JuOI8MO6p716YEpjQy4mV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdBgyb%2FdJMcaasaAuX%2FJuOI8MO6p716YEpjQy4mV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;563&quot; height=&quot;500&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;576&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #1f1f1f; text-align: start;&quot;&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;u&gt;web-service.yaml&lt;/u&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;, 외부 트래픽을 전달하는 로드밸런서 서비스 정의&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1781614340118&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apiVersion: v1
kind: Service

metadata:
	name: numbers-web
	
spec:
	ports:
		- port: 8080        # 서비스가 주시하는 포트
		 targetPort: 80     # 트래픽이 전달될 파드의 포트
	selector:
		app: numbers-web
	type: LoadBalancer    # 외부 트래픽도 전달할 수 있는 서비스&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;&lt;u&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;web-service.yaml&lt;/span&gt;&lt;/u&gt; 로드밸런서 서비스를 클러스터에 배치&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1781614361851&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 로드밸런서 서비스를 배치한다
# 방화벽에서 접근 허용 여부를 묻는다면 허용하라
kubectl apply -f numbers/web-service.yaml

# 서비스의 상세 정보를 확인한다
kubectl get svc numbers-web

# 애플리케이션의 URL을 EXTERNAL-IP 필드로 출력한다
kubectl get svc numbers-web -o jsonpath='http://{.status.loadBalancer.ingress[0].*}:8080'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;709&quot; data-origin-height=&quot;115&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Nq0If/dJMcaiKqb8B/KofkXxq42SGuZDYYcqYq60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Nq0If/dJMcaiKqb8B/KofkXxq42SGuZDYYcqYq60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Nq0If/dJMcaiKqb8B/KofkXxq42SGuZDYYcqYq60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNq0If%2FdJMcaiKqb8B%2FKofkXxq42SGuZDYYcqYq60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;709&quot; height=&quot;115&quot; data-origin-width=&quot;709&quot; data-origin-height=&quot;115&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로드밸런서 서비스에는 클러스터 IP가 함께 부여됩니다. 클러스터 안에 있는 다른 파드는 서비스 이름으로 서비스에 접근합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로드밸런서 서비스는 외부 IP 주소를 주시하다가 해당 주소로 돌아오는 트래픽을 클러스터로 전달합니다. 이 주소는 클러스터에서 제공되는 주소입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;외부 트래픽으로부터 웹 애플리케이션 파드에 트래픽을 전달하기에, &lt;b&gt;포트포워딩 설정을 하지 않아도 웹 애플리케이션에 접근할 수 있습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;65&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d9OKPh/dJMcaaeDn3h/831vAKmQyNJNsjT09VwG0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d9OKPh/dJMcaaeDn3h/831vAKmQyNJNsjT09VwG0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d9OKPh/dJMcaaeDn3h/831vAKmQyNJNsjT09VwG0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd9OKPh%2FdJMcaaeDn3h%2F831vAKmQyNJNsjT09VwG0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;685&quot; height=&quot;65&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;65&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;u&gt; MetalLB&lt;/u&gt;&lt;/span&gt;를 설치한다면 external-ip가 정상적으로 받아지고, 위 실습 결과처럼 웹 애플리케이션에 포트포워딩 설정 없이 접근이 가능합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AWS EC2 내부 트래픽 허용하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계속 시도해도 external-IP가 열리지 않아 여러 시도를 해보았습니다. 짜잘한 건 빼면 크게 4개는 나오는 것 같네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 인터넷 바꾸기(Wi-Fi에서 hot spot 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 모든 파드, 디플로이먼트 종료 후 재실행하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. NodePort 서비스의 설정 변경하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. AWS에서 보안 그룹 재설정하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;등등..&lt;/p&gt;
&lt;h3 data-path-to-node=&quot;9&quot; data-ke-size=&quot;size23&quot;&gt;AWS 보안 그룹의 &quot;내부 통신(IPIP)&quot; 차단 문제 (가장 유력)&lt;/h3&gt;
&lt;p data-path-to-node=&quot;10&quot; data-ke-size=&quot;size16&quot;&gt;아까 올려주신 보안 그룹 이미지를 다시 꼼꼼히 분석해 보았습니다. sg-0afe... 라는 동일한 보안 그룹 ID를 소스로 해서 Calico(네트워크 플러그인)용 포트(UDP 4789, 179 등)를 아주 정교하게 열어두셨더라고요!&lt;/p&gt;
&lt;p data-path-to-node=&quot;11&quot; data-ke-size=&quot;size16&quot;&gt;하지만 여기서 &lt;b data-index-in-node=&quot;8&quot; data-path-to-node=&quot;11&quot;&gt;EC2 쿠버네티스 구축 시 가장 많이 빠지는 함정&lt;/b&gt;이 하나 있습니다. 쿠버네티스 노드들(Master와 Worker)끼리 통신할 때는 단순 TCP/UDP 포트 외에도 IPIP (IP in IP, 프로토콜 번호 4번)라는 특수한 통신 방식을 사용하기도 합니다. 현재 인바운드 규칙에는 특정 포트만 열려있어서, &lt;b data-index-in-node=&quot;178&quot; data-path-to-node=&quot;11&quot;&gt;마스터 노드에서 워커 노드에 떠 있는 파드로 향하는 내부 트래픽이 AWS 방화벽에 막혀 증발&lt;/b&gt;하고 있는 것일 확률이 매우 높습니다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;12&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;12&quot;&gt; ️ 해결 방법: 보안 그룹에 '내부 모든 트래픽 허용' 규칙 추가하기&lt;/b&gt; 클러스터 노드끼리는 어떤 방식으로든 자유롭게 소통할 수 있도록 숨통을 트여주어야 합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-path-to-node=&quot;13&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;AWS EC2 보안 그룹 인바운드 규칙 편집에 들어갑니다.&lt;/li&gt;
&lt;li&gt;[규칙 추가]를 누르고 아래와 같이 설정합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;13,1,1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;13,1,1,0,0&quot;&gt;유형:&lt;/b&gt; 모든 트래픽 (All Traffic)&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;13,1,1,1,0&quot;&gt;소스:&lt;/b&gt; 사용자 지정으로 두고, &lt;b data-index-in-node=&quot;17&quot; data-path-to-node=&quot;13,1,1,1,0&quot;&gt;현재 사용 중인 보안 그룹 ID (sg-0afe8c12ad43661d5...)를 검색해서 선택&lt;/b&gt;합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;671&quot; data-origin-height=&quot;317&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bf1ggg/dJMcageO9Rd/a1FN48GIB0NanAzbUPQrz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bf1ggg/dJMcageO9Rd/a1FN48GIB0NanAzbUPQrz0/img.png&quot; data-alt=&quot;고생 끝에 성공..!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bf1ggg/dJMcageO9Rd/a1FN48GIB0NanAzbUPQrz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbf1ggg%2FdJMcageO9Rd%2Fa1FN48GIB0NanAzbUPQrz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;671&quot; height=&quot;317&quot; data-origin-width=&quot;671&quot; data-origin-height=&quot;317&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;고생 끝에 성공..!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1781615062947&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apiVersion: v1
kind: Service
metadata:
  name: numbers-web
spec:
  ports:
  - port: 8080      # 클러스터 내부에서 사용하는 포트 [cite: 904]
    targetPort: 80  # 파드(컨테이너)의 포트 [cite: 905]
    nodePort: 30080 # ★ 내 컴퓨터 브라우저로 접속할 때 쓸 포트 (30000~32767 사이 선택) 
  selector:
    app: numbers-web 
  type: NodePort    # ★ LoadBalancer 대신 NodePort로 지정 [cite: 909]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제 마스터노드(EC2)의 설정은 위와 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1781619892402&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; 'EOF' &amp;gt; metallb-nat.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: nat-ip-pool
  namespace: metallb-system
spec:
  addresses:
    - 172.31.43.200-172.31.43.250 # ◀ 노드들의 실제 대역인 43번 대역으로 설정
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: nat-l2-adv
  namespace: metallb-system
spec:
  ipAddressPools:
    - nat-ip-pool
EOF

kubectl apply -f metallb-nat.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 내용으로 파일 내용을 작성했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1781615135836&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl apply -f numbers/web-service.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 kubectl apply -f numbers/web-service.yaml 실행해주어서 적용했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;261&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0SwQW/dJMcad3pFVM/9aUjIFkRKpxr1ocOh0fFs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0SwQW/dJMcad3pFVM/9aUjIFkRKpxr1ocOh0fFs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0SwQW/dJMcad3pFVM/9aUjIFkRKpxr1ocOh0fFs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0SwQW%2FdJMcad3pFVM%2F9aUjIFkRKpxr1ocOh0fFs0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;647&quot; height=&quot;261&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;261&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;노드포트 서비스 유형&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노드포트 서비스는 외부 로드밸런서가 필요없이, 모든 노드가 이 서비스에 지정된 포트를 주시하며 들어온 트래픽을 대상 파드의 대상 포트로 전달합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;542&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d6amvh/dJMcadWGuqV/k8kAzk7BGTzeYThctLxKB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d6amvh/dJMcadWGuqV/k8kAzk7BGTzeYThctLxKB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d6amvh/dJMcadWGuqV/k8kAzk7BGTzeYThctLxKB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd6amvh%2FdJMcadWGuqV%2Fk8kAzk7BGTzeYThctLxKB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;596&quot; height=&quot;542&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;542&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노드포트 서비스는 서비스에서 설정된 포트가 모든 노드에서 개방되어 있어야 하기 때문에 로드밸런서 서비스만큼 유연하지는 않습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;web-service-nodePort.yaml&lt;/span&gt;&lt;/u&gt;, 노드포트 서비스의 정의 예&lt;/h4&gt;
&lt;pre id=&quot;code_1781621912757&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apiVersion: v1
kind: Service

metadata:
	name: numbers-web-node
	
spec:
	ports:
		- port: 8080       # 다른 파드가 서비스에 접근하기 위해 사용하는 포트
		  targetPort: 80   # 대상 파드에 트래픽을 전달하는 포트
		  nodePort: 30080  # 서비스가 외부에 공개되는 포트
  selector:
	  app: numbers-web
  type: NodePort       # 노드의 IP 주소를 통해 접근 가능한 서비스&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;쿠버네티스 클러스터 외부로 트래픽 전달하기&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;앞서서 클러스터 내부로 향하는 트래픽을 처리했다면, 이번엔 클러스터 외부로 나가는 트래픽을 처리해보겠습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이런 작업은 쿠버네티스에서 거의 모든 서버용 소프트웨어를 실행할 수 있게 해줍니다. 그렇다고 모든 서버용 소프트웨어를 꼭 쿠버네티스에서 실행하는 것은 아닙니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;관리의 복잡성&lt;br /&gt;단순하고 트래픽이 거의 없는 소규모 서버를 거대하고 복잡한 쿠버네티스에서 실행할 필요는 없다.&lt;/li&gt;
&lt;li&gt;특수 하드웨어 및 성능 요구사항&lt;br /&gt;정밀한 하드웨어 제어가 필요하거나, 초저지연 성능이 필요한 시스템은 쿠버네티스의 가상화 계층이 오히려 방해가 될 수 있다.&lt;/li&gt;
&lt;li&gt;상대 저장 리소스(Stateful)의 어려움&lt;br /&gt;쿠버네티스는 언제든 죽었다 살아나도 상관없는 Stateless 애플리케이션에 최적화되어 있다. &lt;b&gt;DB와 같은 소프트웨어를 설치하기엔 데이터 유실을 막기 위한 스토리지 설정과 백업 관리가 까다롭다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;데이터베이스 같은 스토리지 컴포넌트&lt;/b&gt; 등이 대표적으로 쿠버네티스 외부에서 동작하는 소프트웨어의 예다.&lt;/li&gt;
&lt;li&gt;데이터 센터에 배포한 시스템을 쿠버네티스와 통합되지 않은 시스템과 연동할 필요가 있을 수도 있다.&lt;/li&gt;
&lt;li&gt;애플리케이션 아키텍처와 무관하게 클러스터 외부를 가리키는 도메인 네임 해소에도 쿠버네티스 서비스 리소스를 활용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;익스터널네임(ExternalName) 서비스 사용&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;487&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Pp8KA/dJMcagZ81XC/ktSxc2MPlj7Xi3tzPThTxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Pp8KA/dJMcagZ81XC/ktSxc2MPlj7Xi3tzPThTxK/img.png&quot; data-alt=&quot;어떤 도메인 네임에 대한 설명&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Pp8KA/dJMcagZ81XC/ktSxc2MPlj7Xi3tzPThTxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPp8KA%2FdJMcagZ81XC%2FktSxc2MPlj7Xi3tzPThTxK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;655&quot; height=&quot;487&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;487&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;어떤 도메인 네임에 대한 설명&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;익스터널네임 서비스 실습&lt;/h3&gt;
&lt;pre id=&quot;code_1781623401075&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 현재 배포된 클러스터IP 서비스를 삭제한다
kubectl delete svc numbers-api

# 익스터널네임 서비스를 새로 배포한다
kubectl apply -f numbers-services/api-service-externalName.yaml

# 서비스의 상세 정보를 확인한다
kubectl get svc numbers-api

# 웹 애플리케이션에 포트포워딩을 적용한다
kubectl port-forward --address 0.0.0.0 deploy/numbers-web 8080:80
# 웹 페이지를 새로고침한 후 Go 버튼을 클릭한다&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;285&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yZWod/dJMcac4xvv3/JwgabIaOZFLtN9EeDNsN7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yZWod/dJMcac4xvv3/JwgabIaOZFLtN9EeDNsN7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yZWod/dJMcac4xvv3/JwgabIaOZFLtN9EeDNsN7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyZWod%2FdJMcac4xvv3%2FJwgabIaOZFLtN9EeDNsN7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;449&quot; height=&quot;285&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;285&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;로컬 API 대신 깃허브 저장소에 있는 텍스트 파일에서 정적 텍스트를 읽어들여 같은 결과값이 출력된다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;&lt;u&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;api-service-externalName.yaml&lt;/span&gt;&lt;/u&gt;, 익스터널네임 서비스 정의 예&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1781623543201&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apiVersion: v1
kind: Service

metadata:
	# 클러스터 안에서 쓰이는 로컬 도메인 네임
	name: numbers-api 
spec:
	type: ExternalName
	# 로컬 도메인 네임을 해소할 외부 도메인
	externalName: raw.githubusercontent.com&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/sixeyed/kiamol/master/ch03/numbers/rng&quot;&gt;https://raw.githubusercontent.com/sixeyed/kiamol/master/ch03/numbers/rng&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;쿠버네티스느 DNS의 표준 기능 중 하나인 캐노니컬 네임(Canonical NAME, CNAME)을 사용하여 익스터널네임 서비스를 구현했다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;웹 애플리케이션 파드가 도메인네임 numbers-api라는 이름을 조회하면 쿠버네티스 DNS 서버가 이 CNAME( raw.githubusercontent.com )을 반환한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/sixeyed/kiamol/master/ch03/numbers/rng&quot;&gt;https://raw.githubusercontent.com/sixeyed/kiamol/master/ch03/numbers/rng&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;서비스 역시 클러스터 전체를 커버하는 쿠버네티스 가상 네트워크 일부다. 따라서 모든 파드가 서비스를 사용할 수 있다.&lt;/p&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;이전 실습에 사용된 sleep 파드에서 API 서비스의 도메인 네임 조회&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7TshZ/dJMcabEy3fU/IFwqUbFIM81kzrUjKq27Gk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7TshZ/dJMcabEy3fU/IFwqUbFIM81kzrUjKq27Gk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7TshZ/dJMcabEy3fU/IFwqUbFIM81kzrUjKq27Gk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7TshZ%2FdJMcabEy3fU%2FIFwqUbFIM81kzrUjKq27Gk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;676&quot; height=&quot;257&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;257&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>클라우드/AWS</category>
      <category>K8s</category>
      <category>쿠버네티스</category>
      <author>JJong_H</author>
      <guid isPermaLink="true">https://study-it-all.tistory.com/265</guid>
      <comments>https://study-it-all.tistory.com/265#entry265comment</comments>
      <pubDate>Wed, 17 Jun 2026 00:27:55 +0900</pubDate>
    </item>
    <item>
      <title>[클라우드 프로그래밍] 9주차 클러스터IP</title>
      <link>https://study-it-all.tistory.com/264</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;파드와 파드 간 통신&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;서비스 유형 중 가장 기본이 되는 것을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;&lt;b&gt;클러스터IP&lt;/b&gt;&lt;/u&gt;(ClusterIP)라고 합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;클러스터IP는 클러스터 전체에서 통용되는 IP 주소를 생성하는데, 이 IP 주소는 파드가 어느 노드에 있더라도 접근이 가능합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 IP 주소는 클러스터 내에서만 유효하기 때문에 클러스터IP는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;파드와 파드 간 통신에서만 쓰입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그런데 이거 어딘가 익숙하지 않나요?&lt;span&gt;&lt;b&gt; 저는&lt;/b&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;마치 인트라넷같다고 생각하던 참이었습니다.&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이 특성은 내부에서는 접근이 가능하되 외부의 접근은 차단해야 하는 분산 시스템의 컴포넌트에 적합합니다.&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;클러스터IP 실습&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;두 개의 디플로이먼트 실행&lt;/li&gt;
&lt;li&gt;하나는 웹 애플리케이션&lt;/li&gt;
&lt;li&gt;다른 하나는 API 역할&lt;/li&gt;
&lt;li&gt;이 앱에는 아직 서비스가 없어서 웹 앱이 API에 접근하지 못해 애플리케이션이 제대로 동작하지 않은 상태이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1781612893922&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 웹 사이트와 API를 담당할 두 개의 디플로이먼트를 실행한다
kubectl apply -f numbers/api.yaml -f numbers/web.yaml

# 파드의 준비가 끝날 때까지 기다린다
kubectl wait --for=condition=Ready pod -l app=numbers-web

# 웹 애플리케이션에 포트포워딩을 적용한다
kubectl port-forward --address 0.0.0.0 deploy/numbers-web 8080:80

# 웹 브라우저에서 http://localhost:8080에 접근하여
# 화면상의 Go 버튼을 클릭하면 오류가 발생한다

# 포트포워딩을 중단한다
# Ctrl + C&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;747&quot; data-origin-height=&quot;221&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDzKOc/dJMcaaZXRct/rZ7J4aWfV8gXLH4RKNqNtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDzKOc/dJMcaaZXRct/rZ7J4aWfV8gXLH4RKNqNtK/img.png&quot; data-alt=&quot;정상적으로 접속된 웹페이지 Go! 버튼을 누르면 숫자를 뱉어줘야되지만 현재는 그러지 못한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDzKOc/dJMcaaZXRct/rZ7J4aWfV8gXLH4RKNqNtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDzKOc%2FdJMcaaZXRct%2FrZ7J4aWfV8gXLH4RKNqNtK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;747&quot; height=&quot;221&quot; data-origin-width=&quot;747&quot; data-origin-height=&quot;221&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정상적으로 접속된 웹페이지 Go! 버튼을 누르면 숫자를 뱉어줘야되지만 현재는 그러지 못한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;140&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bm550m/dJMcaijo8cm/cr2ZHQ7hpxXDJQFt8TiK3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bm550m/dJMcaijo8cm/cr2ZHQ7hpxXDJQFt8TiK3k/img.png&quot; data-alt=&quot;Go! 버튼을 눌렀더니 나타난 문구&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bm550m/dJMcaijo8cm/cr2ZHQ7hpxXDJQFt8TiK3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbm550m%2FdJMcaijo8cm%2Fcr2ZHQ7hpxXDJQFt8TiK3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;682&quot; height=&quot;140&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;140&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Go! 버튼을 눌렀더니 나타난 문구&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹에서 접근하려던 API 주소 &lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;(http://numbers-api/&amp;hellip;) 도메인 네임이 쿠버네티스 내부의 DNS 서버에 등록되어 있지 않습니다. 따라서 api-service.yaml을 정의한 뒤 배포해야 정상적으로 동작할 것입니다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1781613179079&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apiVersion: v1
kind: Service

metadata:
	name: numbers-api
	
spec:
	ports:
		- port: 80
	selector:
		app: numbers-api
	type: ClusterIP&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;u&gt;api-service.yaml&lt;/u&gt; &lt;/span&gt;서비스 배포&lt;/h4&gt;
&lt;pre id=&quot;code_1781613185587&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 예제에 정의된 서비스를 배포한다
kubectl apply -f numbers/api-service.yaml

# 서비스의 상세 정보를 출력한다
kubectl get svc numbers-api

# 웹 애플리케이션에 접근할 수 있도록 포트포워딩을 적용한다
kubectl port-forward --address 0.0.0.0 deploy/numbers-web 8080:80

# 웹 브라우저에서 http://localhost:8080에 접근하여
# Go 버튼을 클린하면 잘 실행된다

# 포트포워딩을 중단한다
# Ctrl + C&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1014&quot; data-origin-height=&quot;417&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZptEq/dJMcaaTdslM/dF2H7wQpcoy6bS7JobO780/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZptEq/dJMcaaTdslM/dF2H7wQpcoy6bS7JobO780/img.png&quot; data-alt=&quot;하지만 저는 무한 로딩에 걸려서 숫자를 뱉진 않았습니다....&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZptEq/dJMcaaTdslM/dF2H7wQpcoy6bS7JobO780/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZptEq%2FdJMcaaTdslM%2FdF2H7wQpcoy6bS7JobO780%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1014&quot; height=&quot;417&quot; data-origin-width=&quot;1014&quot; data-origin-height=&quot;417&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;하지만 저는 무한 로딩에 걸려서 숫자를 뱉진 않았습니다....&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 파드는 디플로이먼트가 관리하므로, 수동으로 파드를 지우더라도 대체 파드가 생성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로 생성된 파드 역시 API 서비스에 정의된 레이블 셀렉터와 일치하므로 새로운 파드에도 트래픽이 연결되어 애플리케이션도 기존처럼 잘 동작합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1781613789337&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# API 파드의 이름과 IP 주소를 확인한다
kubectl get pod -l app=numbers-api -o custom-columns=NAME:metadata.name,POD_IP:status.podIP

# API 파드를 수동으로 삭제한다
kubectl delete pod -l app=numbers-api

# 새로 생성된 대체 파드의 이름과 IP 주소를 확인한다 (새로 생성되는 시간 대기)
kubectl get pod -l app=numbers-api -o custom-columns=NAME:metadata.name,POD_IP:status.podIP

# 웹 애플리케이션에 포트포워딩을 적용한다
kubectl port-forward --address 0.0.0.0 deploy/numbers-web 8080:80

# 웹 브라우저에서 htp://localhost:8080에 접근하여
# Go 버튼을 클릭한다

# 포트포워딩을 중단한다
# Ctrl + C&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;164&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIMZDI/dJMcafG1my4/xRFnAXueDZ7YaTwOuIvIek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIMZDI/dJMcafG1my4/xRFnAXueDZ7YaTwOuIvIek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIMZDI/dJMcafG1my4/xRFnAXueDZ7YaTwOuIvIek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIMZDI%2FdJMcafG1my4%2FxRFnAXueDZ7YaTwOuIvIek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;725&quot; height=&quot;164&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;164&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;* 하지만 여전히 접속해도 무작위 숫자를 받아보진 못했습니다..&lt;/i&gt;&lt;/p&gt;</description>
      <author>JJong_H</author>
      <guid isPermaLink="true">https://study-it-all.tistory.com/264</guid>
      <comments>https://study-it-all.tistory.com/264#entry264comment</comments>
      <pubDate>Tue, 16 Jun 2026 21:46:00 +0900</pubDate>
    </item>
    <item>
      <title>[클라우드 프로그래밍] 9주차 Network</title>
      <link>https://study-it-all.tistory.com/263</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;네트워크를 통해 서비스에 파드 연결&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 파드는 서로 통신할 수 있어야 한다. 파드끼리 통신을 위해 쿠버네티스는 표준 네트워크 프로토콜인 TCP와 UDP를 지원한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;TCP: 데이터를 보내기 전에 먼저 상대방과 연결이 되었는지 확인하는 연결 지향적 방식&lt;/li&gt;
&lt;li&gt;UDP: 상대방 연결과 상관없이 데이터를 일방적으로 전달하는 비연결형 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;두 프로토콜은 모두 IP 주소로 트래픽을 제어하는데, &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;IP 주소는 파드를 대체할 때 주소가 변경된다는 문제&lt;/b&gt;&lt;/span&gt;가 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;쿠버네티스는 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;서비스(Service)&lt;/b&gt;&lt;/span&gt;에 &lt;b&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;어드레스 디스커버리(address discovery)&lt;/span&gt;&lt;/b&gt; 기능을 제공하여 이 문제를 해결한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;서비스 리소스&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;파드 간에 통신을 하고 싶지만 문제가 있다&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;파드의 특징은 다음과 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-ke-style=&quot;style2&quot;&gt;파드는 쿠버네티스에서 부여한 IP 주소를 가진 가상 환경이다.&lt;/li&gt;
&lt;li data-ke-style=&quot;style2&quot;&gt;파드가 다른 컨트롤러 객체에 의해 생애 주기가 관장되는 &amp;lsquo;쓰고 버리는&amp;rsquo; 리소스이다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드간 통신하는 데 IP 주소가 필요하다. 하지만 이 때 두가지 문제가 발생합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;&lt;b&gt;파드가 새로운 파드로 교체될 때 IP 주소가 바뀐다&lt;/b&gt;&lt;/li&gt;
&lt;li style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;&lt;b&gt;새로운 IP 주소는 쿠버네티스 API를 통해서만 파악할 수 있다.&lt;/b&gt; (교체된 파드의 새로운 IP 주소를 찾기 어렵다)&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;IP가 변하니 전담 서비스를 만들자.&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-path-to-node=&quot;2,1&quot;&gt;&lt;span&gt;이러한 IP 주소의 가변성과 관리의 어려움을 해결하기 위해 등장한 것이 바로 &lt;b&gt;'&lt;u&gt;서비스(Service)&lt;/u&gt;' 리소스&lt;/b&gt;입니다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;2,2&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;2,3&quot;&gt;. &lt;/span&gt;&lt;span data-path-to-node=&quot;2,4&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;2,5&quot;&gt;&lt;span&gt;서비스는 고정된 가상 IP 주소를 제공하고 쿠버네티스의 DNS 서버와 연동하여, 파드가 매번 변하는 &lt;b&gt;IP 대신 서비스의 이름(도메인 네임)을 통해 안정적으로 서로를 찾을 수 있게 해줍니다&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span data-path-to-node=&quot;2,6&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;2,7&quot;&gt;. &lt;/span&gt;&lt;/b&gt;&lt;span data-path-to-node=&quot;2,8&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;2,9&quot;&gt;&lt;span&gt;덕분에 파드가 교체되거나 재생성되어 IP가 바뀌더라도, 서비스가 중간에서 트래픽을 올바른 파드로 라우팅해주기 때문에 애플리케이션의 통신은 중단 없이 유지될 수 있습니다. &lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;2,13&quot;&gt;&lt;span&gt;또한 서비스는 서비스가 삭제될 때까지 IP 주소가 변경되지 않는 정적 주소를 보장하므로, 복잡한 API 조회 없이도 신뢰할 수 있는 통신 연결을 가능하게 합니다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;2,14&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;2,15&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;IP가 정말 변하는가?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IP가 정말 변하는지 한 번 확인해보겠다.&lt;/p&gt;
&lt;pre id=&quot;code_1781611911583&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 각각 파드 하나를 실행하는 두 개의 디플로이먼트를 생성한다
kubectl apply -f sleep/sleep1.yaml -f sleep/sleep2.yaml

# 파드가 완전히 시작될 때까지 기다린다
kubectl wait --for=condition=Ready pod -l app=sleep-2

# 두 번째 파드의 IP 주소를 확인한다
kubectl get pod -l app=sleep-2 --output jsonpath='{.items[0].status.podIP}'

# 같은 주소를 사용하여 첫 번째 파드에서 두 번째 파드로 ping을 보낸다
kubectl exec deploy/sleep-1 -- ping -c 2 $(kubectl get pod -l app=sleep-2 --output jsonpath='{.items[0].status.podIP}')&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;152&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qRF9d/dJMcahShOrJ/1uZwpgB51cLbFyWaGBnOwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qRF9d/dJMcahShOrJ/1uZwpgB51cLbFyWaGBnOwk/img.png&quot; data-alt=&quot;두 번째 파드로 PING이 잘 전송된 모습 / 두 번째 파드의 IP 주소: 192.168.235.136&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qRF9d/dJMcahShOrJ/1uZwpgB51cLbFyWaGBnOwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqRF9d%2FdJMcahShOrJ%2F1uZwpgB51cLbFyWaGBnOwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;640&quot; height=&quot;152&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;152&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;두 번째 파드로 PING이 잘 전송된 모습 / 두 번째 파드의 IP 주소: 192.168.235.136&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 파드는 컨트롤러 객체인 디플로이먼트로 관리됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드를 수동으로 삭제하면 이를 관리하는 디플로이먼트가 다른 IP 주소를 가진 새로운 파드를 생성할 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 삭제되기 전까지는 고정된 IP 주소를 가질 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;56&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3P2gm/dJMcaf70kDp/diy9Og6fCCBnfEdH1ZAp40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3P2gm/dJMcaf70kDp/diy9Og6fCCBnfEdH1ZAp40/img.png&quot; data-alt=&quot;# 파드의 현재 IP 주소 확인
 kubectl get pod -l app = sleep-2 --output jsonpath = '{.items[0].status.podIP}'&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3P2gm/dJMcaf70kDp/diy9Og6fCCBnfEdH1ZAp40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3P2gm%2FdJMcaf70kDp%2Fdiy9Og6fCCBnfEdH1ZAp40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;636&quot; height=&quot;56&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;56&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;# 파드의 현재 IP 주소 확인
 kubectl get pod -l app = sleep-2 --output jsonpath = '{.items[0].status.podIP}'&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;641&quot; data-origin-height=&quot;112&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nlvxT/dJMcaaeDndD/7DdOrJ14bsZEMP3k8qm0fk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nlvxT/dJMcaaeDndD/7DdOrJ14bsZEMP3k8qm0fk/img.png&quot; data-alt=&quot;# 디플로이먼트가 새 파드를 만들도록 현재 파드를 삭제한다 
kubectl delete pods -l app = sleep-2

 # 새로 대체된 파드의 IP 주소를 확인한다 
kubectl get pod -l app = sleep-2 --output jsonpath = '{.items[0].status.podIP}'&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nlvxT/dJMcaaeDndD/7DdOrJ14bsZEMP3k8qm0fk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnlvxT%2FdJMcaaeDndD%2F7DdOrJ14bsZEMP3k8qm0fk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;641&quot; height=&quot;112&quot; data-origin-width=&quot;641&quot; data-origin-height=&quot;112&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;# 디플로이먼트가 새 파드를 만들도록 현재 파드를 삭제한다 
kubectl delete pods -l app = sleep-2

 # 새로 대체된 파드의 IP 주소를 확인한다 
kubectl get pod -l app = sleep-2 --output jsonpath = '{.items[0].status.podIP}'&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삭제 이후에 새로 나온 파드의 IP 주소는 &lt;u&gt;192.168.235.137&lt;/u&gt;로, 이전과 달라진 모습입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언제든지 다른 것으로 변경되는 리소스에 접근하기 위한 &lt;u&gt;&lt;b&gt;고정된 주소&lt;/b&gt;&lt;/u&gt;는 새로운 문제가 아닙니다. 앞서 설명했던 것처럼 이런 문제를 인터넷에선 IP 주소를 기억하기 쉬운 이름의 도메인 네임을 도입하여 해결했습니다. 쿠버네티스에서도 같은 해결책으로 클러스터에 전용 DNS 서버가 존재합니다. 이 DNS 서버가 서비스 이름과 IP 주소를 대응시켜 줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z8l6k/dJMcaci8NKL/izWaH4OLqIi5GjkYdvxj41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z8l6k/dJMcaci8NKL/izWaH4OLqIi5GjkYdvxj41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z8l6k/dJMcaci8NKL/izWaH4OLqIi5GjkYdvxj41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ8l6k%2FdJMcaci8NKL%2FizWaH4OLqIi5GjkYdvxj41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;552&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스는 자신만의 IP 주소를 갖고, 서비스가 삭제될 때까지 바뀌지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스와 파드의 연결 관계는 디플로이먼트와 파드의 연결 관계와 마찬가지로 레이블 셀렉터를 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스에 필요한 최소한의 YAML 정의 예제는 다음과 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1781612432227&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apiVersion: v1     # 서비스는 코어 v1 API를 사용한다
kind: Service

metadata:
	name: sleep-2    # 서비스 이름이 도메인 네임으로 사용된다
	
# 서비스의 정의에는 셀렉터와 포트의 목록이 포함되어야 한다
spec:
	selector:
		app: sleep-2   # app 레이블의 값이 sleep-2인 모든 파드가 대상이다
	ports:
		- port: 80     # 80번 포트를 주시하다가 파드의 80번 포트로 트래픽을 전달한다&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스를 클러스터에 배포하면 sleep-2 라는 도메인 네임이 생성되고, 이 도메인 네임은 sleep-2 디플로이먼트에 포함된 파드로 트래픽을 연결해줍니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;다른 파드에서도 이 도메인 네임을 사용하여 이 파드로 통신을 보낼 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;sleep2-service.yaml 서비스 배포&lt;/h4&gt;
&lt;pre id=&quot;code_1781612516200&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 예제의 정의를 사용하여 서비스를 배포한다
kubectl apply -f sleep/sleep2-service.yaml

# 서비스의 상세 정보를 출력한다
kubectl get svc sleep-2

# 파드와 통신이 잘되는지 확인한다 - 이 명령은 실패한다
kubectl exec deploy/sleep-1 -- ping -c 1 sleep-2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;629&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NJ6oJ/dJMcadWGsh8/PkSqNzhIAlbGkOMjH8fpB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NJ6oJ/dJMcadWGsh8/PkSqNzhIAlbGkOMjH8fpB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NJ6oJ/dJMcadWGsh8/PkSqNzhIAlbGkOMjH8fpB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNJ6oJ%2FdJMcadWGsh8%2FPkSqNzhIAlbGkOMjH8fpB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;629&quot; height=&quot;168&quot; data-origin-width=&quot;629&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>클라우드/AWS</category>
      <category>K8s</category>
      <category>쿠버네티스</category>
      <author>JJong_H</author>
      <guid isPermaLink="true">https://study-it-all.tistory.com/263</guid>
      <comments>https://study-it-all.tistory.com/263#entry263comment</comments>
      <pubDate>Tue, 16 Jun 2026 21:26:35 +0900</pubDate>
    </item>
    <item>
      <title>[클라우드 프로그래밍] 9주차 Manifest</title>
      <link>https://study-it-all.tistory.com/262</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;애플리케이션 매니페스트&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;클러스터에 배포할 리소스(파드, 디플로이먼트, 서비스 등)의 원하는상태를 기술한 &lt;b&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;설계도 혹은 명세서&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;매니페스트는 JSON 또는 YAML 포맷으로 작성할 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;쿠버네티스 API의 정식 스크립트 포맷은 JSON이지만, 가독성이 뛰어나고 더 많은 리소스를 정의할 수 있는 &lt;b&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;YAML&lt;/span&gt;&lt;/b&gt;을 많이 쓴다. (특히, 주석을 작성할 수 있다는 장점이 있다)&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;매니페스트 vs 디플로이먼트&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설명만 읽으면 디플로이먼트랑 큰 차이를 느끼기 어렵다. 그게 그거 아닌가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 둘은 서로 상호작용하는 관계이므로 분명히 차이가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매니페스트는 설계도이고 디플로이먼트는 관리자이다. 즉, YAML이나 JSON 형식으로 작성된 매니페스트를 디플로이먼트가 참고한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-path-to-node=&quot;11&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;매니페스트 (Manifest)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;디플로이먼트 (Deployment)&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,1,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,1,0,0&quot;&gt;성격&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,1,1,0&quot;&gt;파일 (Blueprint/Recipe)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,1,2,0&quot;&gt;리소스 (Controller/Manager)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,2,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,2,0,0&quot;&gt;형태&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,2,1,0&quot;&gt;YAML 또는 JSON 파일&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,2,2,0&quot;&gt;쿠버네티스 내부에서 구동되는 객체&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,3,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,3,0,0&quot;&gt;하는 일&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,3,1,0&quot;&gt;상태를 정의함&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,3,2,0&quot;&gt;상태를 유지하고 관리함&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;15,0,0&quot;&gt;매니페스트 작성:&lt;/b&gt; 사용자가 deployment.yaml 파일에 디플로이먼트의 설정(이미지, 파드 수 등)을 적습니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;15,1,0&quot;&gt;명령 실행:&lt;/b&gt; &lt;u&gt;kubectl apply -f deployment.yaml&lt;/u&gt; 명령을 내립니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;15,2,0&quot;&gt;디플로이먼트 생성:&lt;/b&gt; 쿠버네티스가 이 매니페스트(파일)를 읽고, 그 내용대로 '디플로이먼트(컨트롤러 객체)'라는 관리자를 클러스터에 생성합니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;15,3,0&quot;&gt;작업 수행:&lt;/b&gt; 이제 생성된 '디플로이먼트'가 매니페스트에 적힌 설계도대로 파드를 만들고, 문제가 생기면 복구하는 등 실질적인 일을 수행합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;매니페스트 예시: pod.yaml (컨테이너 하나를 실행하는 단일 파드)&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;#&amp;nbsp;매니페스트&amp;nbsp;스크립트는&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;쿠버네티스&amp;nbsp;API의&amp;nbsp;버전&lt;/span&gt;과&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;정의하려는&amp;nbsp;유형&lt;/span&gt;을&amp;nbsp;밝히며&amp;nbsp;시작한다 &lt;br /&gt;apiVersion:&amp;nbsp;v1 &lt;br /&gt;kind:&amp;nbsp;Pod &lt;br /&gt;&lt;br /&gt;#&amp;nbsp;리소스의&amp;nbsp;메타데이터에는&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;이름(필수&amp;nbsp;요소)&lt;/span&gt;과&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;레이블(비필수&amp;nbsp;요소)&lt;/span&gt;이&amp;nbsp;있다. &lt;br /&gt;metadata: &lt;br /&gt;&amp;nbsp; &amp;nbsp; name: hello-kiamol-3 &lt;br /&gt;&lt;br /&gt;#&amp;nbsp;스펙은&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;리소스의&amp;nbsp;실제&amp;nbsp;정의&amp;nbsp;내용&lt;/span&gt;이다. &lt;br /&gt;#&amp;nbsp;파드의&amp;nbsp;경우&amp;nbsp;실행할&amp;nbsp;컨테이너를&amp;nbsp;정의해야&amp;nbsp;한다 &lt;br /&gt;#&amp;nbsp;컨테이너는&amp;nbsp;이름과&amp;nbsp;이미지로&amp;nbsp;정의된다 &lt;br /&gt;spec: &lt;br /&gt;&amp;nbsp; &amp;nbsp; containers: &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - name: web &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; image: kiamol/ch02-hello-kiamol&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;u&gt;kubectl run&lt;/u&gt;&lt;/span&gt; 또는 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;u&gt;kubectl create&lt;/u&gt;&lt;/span&gt; 명령을 사용하는 방식은 명령형으로, 쿠버네티스에 할 일을 사용자가 직접 일일이 지시하는 방식이었다면,&lt;b&gt;애플리케이션 매니페스트&lt;/b&gt;는 선언적 방식으로, 최종 결과가 어떻게 되어야 하는지 알려 주고 그 최종 결과를 만드는 과정은 따지지 않는 방식이다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;매니페스트 파일로 애플리케이션 배포하기&lt;/h3&gt;
&lt;pre id=&quot;code_1781602229510&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 매니페스트 파일을 작성했더라도 애플리케이션을 배포하려면 kubectl을 사용해야 한다
# 파일에 기술된 설정을 클러스터에 적용하라는 의미의 apply 명령 사용

# 예제 코드의 최상위 디렉터리에서 ch02 디렉터리로 이동
cd ch02

# 매니페스트 파일로 애플리케이션 배포
kubectl apply -f pod.yaml

# 실행 중인 파드 목록 확인
kubectl get pods&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;544&quot; data-origin-height=&quot;95&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bH03DG/dJMcadbfnws/XyvMzNGX28nzVhdGX5Nyz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bH03DG/dJMcadbfnws/XyvMzNGX28nzVhdGX5Nyz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bH03DG/dJMcadbfnws/XyvMzNGX28nzVhdGX5Nyz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbH03DG%2FdJMcadbfnws%2FXyvMzNGX28nzVhdGX5Nyz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;544&quot; height=&quot;95&quot; data-origin-width=&quot;544&quot; data-origin-height=&quot;95&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;apply 명령을 실행하면 YAML 파일에 기술된 상태를 클러스터에 반영한다. 이 상태를 만들기 위한 과정이 출력된다. 이번 예제에서는 파드 한 개만 생성됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 파드 두 개는 똑같은 설정을 가지고 같은 애플리케이션을 실행한다. 하지만 이들 파드는 각각 다른 방식으로 생성됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매니페스트로 생성된 파드를 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;u&gt;kubectl&lt;/u&gt;&lt;/span&gt;을 사용하여 다른 파드와 마찬가지 방식으로, 세부 정보를 보거나 네트워크 트래픽을 이 파드로 전달하는 것도 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;하지만 매니페스트는 애플리케이션 정의를 공유하기 쉽고, 똑같은 배포를 반복할 수 있다는 차이가 존재한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언제든지 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;u&gt;kubectl&lt;/u&gt;&lt;/span&gt;로 &lt;u&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;apply&lt;/span&gt;&lt;/u&gt;명령을 실행하면 항상 &lt;u&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;hello-kiamol-3&lt;/span&gt;&lt;/u&gt;파드가 생기는 동일한 결과를 얻게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매니페스트 파일을 로컬 컴퓨터에 따로 복사하지 않아도 공개된 URL만 있으면 kubectl로 배포가 가능하다.&lt;/p&gt;
&lt;pre id=&quot;code_1781602545675&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 원격 URL에서 제공되는 매니페스트 파일로 애플리케이션 배포
kubectl apply -f https://raw.githubusercontent.com/sixeyed/kiamol/master/ch02/pod.yaml

# 파드 삭제 명령어는 kubectl delete pod &amp;lt;파드명&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;kubectl apply -f&lt;/b&gt;&lt;/u&gt; https:// : 메니페스트 파일은 로컬 컴퓨터에 있는 파일이나 URL이 가리키는 웹 서버에 저장된 파일 모두 사용할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;53&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LIzqf/dJMb9906ukz/50akpDZ8n3frEfcYeXH8Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LIzqf/dJMb9906ukz/50akpDZ8n3frEfcYeXH8Kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LIzqf/dJMb9906ukz/50akpDZ8n3frEfcYeXH8Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLIzqf%2FdJMb9906ukz%2F50akpDZ8n3frEfcYeXH8Kk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;864&quot; height=&quot;53&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;53&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹서버에서 내려받은 매니페스트 파일의 내용이 조금 전 파일과 같으므로 파드에 변경이 일어나지 않았다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;YAML 포맷으로 디플로이먼트 적용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관리자가 설계도를 보며 명세대로 동작하게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;YAML 포맷으로 디플로이먼트 적용할 때 필수적으로 디플로이먼트가 실행할 파드를 정의해야 한다. 파드를 어떻게 굴릴 건지에 대한 정보를 정의해야 한다는 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드는 또 자신만의 정의 내용이 따로 있으므로 디플로이 먼트 정의는 파드에 대한 정의를 포함하게 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1781610115916&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kind: Deployment  # 1. 디플로이먼트 객체 시작 (관리자)
metadata: ...
spec:
  replicas: 3     # 디플로이먼트만의 설정 (몇 개를 돌릴까?)
  selector: ...   # 디플로이먼트만의 설정 (누구를 관리할까?)
  template:       # ★ 여기가 바로 &quot;파드 정의&quot;가 들어가는 자리
    metadata:     # 여기서부터는 파드의 독립적인 정의 내용
      labels: ...
    spec:         # 여기서부터는 파드가 실행할 컨테이너 정의
      containers:
      - name: ...
        image: ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드는 자신만의 정의 내용이 따로 있다는 말은 &quot;파드는 그 자체로 하나의 완결된 리소스 규격(Kind:Pod)을 가진다&quot;는 뜻이다. 따라서 디플로이먼트는 &quot;내가 파드를 새로 찍어내야 하는데, 그 파드의 설계도는 '이런 규격(Kind:Pod)'을 따라야 한다&quot;는 것을 알려주기 위해, 자신의 YAML명세서 안에 파드의 규격을 그대로 삽입(포함)하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; 이렇게 설계하면 나중에 디플로이먼트의 관리 방식(개수, 업데이트 전략 등)만 바꾸거나, 반대로 파드의 상세 설정(이미지 버전 등)만 따로 바꿔서 관리할 수 있어 훨씬 유연해진다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1781610227905&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 디플로이먼트는 API 버전 1에 속한다
apiVersion: app/v1
kind: Deployment

# 디플로이먼트의 이름을 정해야 한다
metadata:
	name: hello-kiamol-4
	
# 디플로이먼트가 자신의 관리 대상을 결정하는 레이블 셀렉터가 정의된다
# 여기에서는 app 레이블을 사용, 레이블은 임의의 키-값 쌍이다
spec:
	selector:
		matchLabels:
			app: hello-kiamol-4
			
# 이 템플릿은 디플로이먼트가 파드를 만들 때 쓰인다
template:
# 디플로이먼트 정의 속 파드의 정의에는 이름이 없다
# 그 대신 레이블 셀렉터와 일치하는 레이블을 지정해야 한다
	metadata:
		labels:
			app: hello-kiamol-4
			
# 파드의 정의에는 컨테이너 이름과 이미지 이름을 지정한다
spec:
	containers:
		-name: web
		 image: kiamol/ch02-hello-kiamol&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;디플로이먼트의 매니페스트를 사용하여 디플로이먼스 생성&lt;/h4&gt;
&lt;pre id=&quot;code_1781610259209&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 디플로이먼트의 매니페스트로 애플리케이션 실행
kubectl apply -f deployment.yaml

# 새로운 디플로이먼트가 만든 파드 찾기
kubectl get pods -l app=hello-kiamol-4&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;547&quot; data-origin-height=&quot;85&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YQJwT/dJMcacKjirf/zBepq9CbHR9jU53AnUB4z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YQJwT/dJMcacKjirf/zBepq9CbHR9jU53AnUB4z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YQJwT/dJMcacKjirf/zBepq9CbHR9jU53AnUB4z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYQJwT%2FdJMcacKjirf%2FzBepq9CbHR9jU53AnUB4z0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;547&quot; height=&quot;85&quot; data-origin-width=&quot;547&quot; data-origin-height=&quot;85&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;apply 명령은 YAML에 정의된 것이라면 어떤 리소스든 동일한 방식으로 동작한다. 이 명령은 디플로이먼트만 생성하며, 파드를 생성하는 것은 디플로이먼트가 맡는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빨강: 디플로이먼트가 즉시 파드를 생성하고 있다. 매니페스트에 정의된 대로 파드의 레이블을 부여했으니 이 레이블로 파드를 찾을 수 있을 것이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 디플로이먼트 생성 실습과 결과는 같지만, 이번엔 애플리케이션 정의가 YAML 파일에 기술되어 있다는 점이 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;애플리케이션 정의로, 복제본을 몇 개나 둘지, CPU와 메모리의 사용 상한, 애플리케이션 상태 체크는 어떤 방식으로 할지, 애플리케이션에서 사용할 설정값은 어디서 읽어들이고 데이터는 어디에 저장할지 등 YAML 파일에 추가할 수 있다.&lt;/span&gt; &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;쿠버네티스 리소스 관리&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;kubectl을 사용하면 쿠버네티스 리소스를 쉽게 삭제할 수 있지만 리소스가 되살아나는 경우가 있다. 앞에서 디플로이먼트 설명을 했었는데, 그 내용을 떠올리면 이해가 쉬울 것 같다. 디플로이먼트와 같은 컨트롤러 객체가 만든 리소스의 삭제는 해당 컨트롤러 객체의 책임이다. 컨트롤러 객체는 자신이 관리하는 리소스의 생애 주기를 관장하며 외부 간섭을 용인하지 않는다. 따라서, 컨트롤러 객체가 관리하는 리소스를 우리가 직접 삭제하면 이를 대체하는 새로운 리소스가 생성된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1781610571055&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 실행 중인 모든 파드의 목록 출력
kubectl get pods&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;550&quot; data-origin-height=&quot;85&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFgtQM/dJMcadPRVHk/x9D70OnXnekkZwAkxFqTQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFgtQM/dJMcadPRVHk/x9D70OnXnekkZwAkxFqTQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFgtQM/dJMcadPRVHk/x9D70OnXnekkZwAkxFqTQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFgtQM%2FdJMcadPRVHk%2Fx9D70OnXnekkZwAkxFqTQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;550&quot; height=&quot;85&quot; data-origin-width=&quot;550&quot; data-origin-height=&quot;85&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 중인 파드 목록을 확인해보니 3개의 파드가 나타났다.&lt;/p&gt;
&lt;pre id=&quot;code_1781610627328&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 모든 파드 삭제
kubectl delete pods --all&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;438&quot; data-origin-height=&quot;84&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baGgUz/dJMcaffXssV/nysUYSmykJgouEWvpDvEc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baGgUz/dJMcaffXssV/nysUYSmykJgouEWvpDvEc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baGgUz/dJMcaffXssV/nysUYSmykJgouEWvpDvEc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaGgUz%2FdJMcaffXssV%2FnysUYSmykJgouEWvpDvEc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;438&quot; height=&quot;84&quot; data-origin-width=&quot;438&quot; data-origin-height=&quot;84&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt; * delete 명령은 여러 가지 유형의 리소스를 삭제할 수 있다. --all 플래그를 사용하면 모든 유형의 리소스슬 한 번에 삭제한다. kubectl은 삭제할 때 확인을 하지 않으므로 주의해야 한다. 그렇지 않으면 모든 파드가 삭제될 수 있다.&lt;/i&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1781610634768&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 모든 파드가 삭제되었는지 확인
kubectl get pods&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;78&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwe1lD/dJMcahri0tK/66lTP038QkENuzCmhzKyZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwe1lD/dJMcahri0tK/66lTP038QkENuzCmhzKyZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwe1lD/dJMcahri0tK/66lTP038QkENuzCmhzKyZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbwe1lD%2FdJMcahri0tK%2F66lTP038QkENuzCmhzKyZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;535&quot; height=&quot;78&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;78&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삭제 이후에 다시 목록을 확인해보았는데, 이번엔 두 개밖에 없다. 그 이유는 디플로이먼트가 자신이 관리하던 파드를 대체할 새로운 파드를 만들었기 때문이다. 나머지 하나는 사용자(나)가 직접 실행했던 파드였기 때문에 그렇다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디플로이먼트 관리&lt;/p&gt;
&lt;pre id=&quot;code_1781610879977&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 디플로이먼트 목록 확인
kubectl get deploy

# 디플로이먼트 모두 삭제
kubectl delete deploy --all&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;56&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkhfHq/dJMcaayV8VR/8jVqLjEOkr0E9xilp0DO31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkhfHq/dJMcaayV8VR/8jVqLjEOkr0E9xilp0DO31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkhfHq/dJMcaayV8VR/8jVqLjEOkr0E9xilp0DO31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkhfHq%2FdJMcaayV8VR%2F8jVqLjEOkr0E9xilp0DO31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;461&quot; height=&quot;56&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;56&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kubectl 명령의 문법은 대체로 일관적인데, 주로 명사 뒤에 동사 형태에 명령어가 온다. 또한 모든 유형의 리소스를 삭제하려면 delete 명령을 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1781610917649&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 모든 리소스 목록 확인
kubectl get all&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;365&quot; data-origin-height=&quot;42&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kxmaI/dJMcabEyZlk/pBaeGwx4N5ZX4UsDgseqCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kxmaI/dJMcabEyZlk/pBaeGwx4N5ZX4UsDgseqCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kxmaI/dJMcabEyZlk/pBaeGwx4N5ZX4UsDgseqCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkxmaI%2FdJMcabEyZlk%2FpBaeGwx4N5ZX4UsDgseqCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;365&quot; height=&quot;42&quot; data-origin-width=&quot;365&quot; data-origin-height=&quot;42&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1781610961910&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 파드 목록 확인
kubectl get pods&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;61&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Xjfba/dJMcaijo7fx/9nAvQrcWA6L4mKb4Kjxle1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Xjfba/dJMcaijo7fx/9nAvQrcWA6L4mKb4Kjxle1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Xjfba/dJMcaijo7fx/9nAvQrcWA6L4mKb4Kjxle1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXjfba%2FdJMcaijo7fx%2F9nAvQrcWA6L4mKb4Kjxle1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;610&quot; height=&quot;61&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;61&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 클러스터에 있는 모든 리소스를 확인하는 명령어다. 지금은 모든 파드와 디플로이먼트가 삭제됐기 때문에 쿠버네티스API만 남아있는 상태이다.&lt;/p&gt;</description>
      <category>클라우드/AWS</category>
      <category>K8s</category>
      <category>쿠버네티스</category>
      <author>JJong_H</author>
      <guid isPermaLink="true">https://study-it-all.tistory.com/262</guid>
      <comments>https://study-it-all.tistory.com/262#entry262comment</comments>
      <pubDate>Tue, 16 Jun 2026 20:57:54 +0900</pubDate>
    </item>
    <item>
      <title>[클라우드 프로그래밍] 9주차 Deployment</title>
      <link>https://study-it-all.tistory.com/261</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;디플로이먼트(Deployment)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;디플로이먼트는 쿠버네티스에서 파드를 관리하는 상위 수준의 &lt;b&gt;&amp;lsquo;컨트롤러 객체&amp;rsquo;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;디플로이먼트는 파드를 관리하고, 파드는 컨테이너를 관리하는 계층 구조를 가진다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;디플로이먼트는 시스템의 현재 상태를 감시하다가 사용자가 설정한 상태와 차이가 생기면 이를 자동으로 바로잡는다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;* &lt;a href=&quot;https://study-it-all.tistory.com/260&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 실습&lt;/a&gt;과 이어집니다.&lt;/i&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;디플로이먼트 생성하기&lt;/h3&gt;
&lt;pre id=&quot;code_1781600100238&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 조금 전과 같은 웹 애플리케이션을 실행하는 디플로이먼트
# 'hello-kiamol-2'를 생성
kubectl create deployment hello-kiamol-2 --image=kiamol/ch02-hello-kiamol

# 파드의 목록을 출력
kubectl get pods&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;101&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qjB0k/dJMcadoM7Eg/j4FENc7ring7RJ10eH7Mik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qjB0k/dJMcadoM7Eg/j4FENc7ring7RJ10eH7Mik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qjB0k/dJMcadoM7Eg/j4FENc7ring7RJ10eH7Mik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqjB0k%2FdJMcadoM7Eg%2Fj4FENc7ring7RJ10eH7Mik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;728&quot; height=&quot;101&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;101&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디플로이먼트 소속 파드 이름 뒤에 무작위 문자열(hello-kiamol-2-&lt;b&gt;787f8db75d-tk5vf&lt;/b&gt;)이 붙는걸 확인할 수 있다. &amp;rarr; &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;디플로이먼트가 여러 개의 복제본을 구분하고 관리하기 위해 자동으로 붙이는 고유 식별자이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1781600266083&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 디플로이먼트가 부여한 파드의 레이블 출력
kubectl get deploy hello-kiamol-2 -o jsonpath='{.spec.template.metadata.labels}'
# 디플로이먼트가 파드를 만들 때 어떤 레이블을 붙이도록 설정되어 있는지 확인
# 이 디플로이먼트가 만드는 모든 파드에 같은 레이블을 붙인다&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;34&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uws4p/dJMcafNOheX/Kg9o0QcobbAIipPG0OuMBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uws4p/dJMcafNOheX/Kg9o0QcobbAIipPG0OuMBk/img.png&quot; data-alt=&quot;{&amp;quot;app&amp;quot;:&amp;quot;hello-kiamol-2&amp;quot;}&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uws4p/dJMcafNOheX/Kg9o0QcobbAIipPG0OuMBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fuws4p%2FdJMcafNOheX%2FKg9o0QcobbAIipPG0OuMBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;778&quot; height=&quot;34&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;34&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;{&quot;app&quot;:&quot;hello-kiamol-2&quot;}&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1781600278458&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 앞서 출력한 레이블을 가진 파드의 목록 출력
kubectl get pods -l app=hello-kiamol-2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;45&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciWyvS/dJMcag6WpDY/0Y5p4hjuX5r1zFW1x2POik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciWyvS/dJMcag6WpDY/0Y5p4hjuX5r1zFW1x2POik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciWyvS/dJMcag6WpDY/0Y5p4hjuX5r1zFW1x2POik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciWyvS%2FdJMcag6WpDY%2F0Y5p4hjuX5r1zFW1x2POik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;551&quot; height=&quot;45&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;45&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 확인했던 &lt;b&gt;레이블을 이용하면 리소스 간 관계를 파악&lt;/b&gt;할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;573&quot; data-origin-height=&quot;482&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqrmrM/dJMcajbr5aW/4hwEio7sTRJmr7HDqHjk81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqrmrM/dJMcajbr5aW/4hwEio7sTRJmr7HDqHjk81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqrmrM/dJMcajbr5aW/4hwEio7sTRJmr7HDqHjk81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqrmrM%2FdJMcajbr5aW%2F4hwEio7sTRJmr7HDqHjk81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;573&quot; height=&quot;482&quot; data-origin-width=&quot;573&quot; data-origin-height=&quot;482&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;레이블 조작&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레이블은 디플로이먼트가 자신의 파드를 인식하기 위해 필요하다. 이것이 있어야, 본인 명세에 쓰인대로 파드를 운용할 수 있기 때문이다. 디플로이먼트에 명세한 파드 개수대로 파드를 운영하기 때문에 만약 레이블을 변경해서 본인의 파드가 적어지면 새로운 파드를 생성할 것이고, 레이블 변경으로 새롭게 추가 파드를 갖는 디플로이먼트는 파드를 하나 줄임으로써 운용 개수를 조절할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 레이블을 조작해보며 디플로이먼트가 어떻게 동작하는 지 확인하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 모든 파드 이름과 레이블을 확인해보자.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 레이블 확인 및 레이블 변경&lt;/h4&gt;
&lt;pre id=&quot;code_1781600680785&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 모든 파드 이름과 레이블 확인
kubectl get pods -o custom-columns=NAME:metadata.name,LABELS:metadata.labels

# 디플로이먼트가 생성한파드의 'app' 레이블 수정
kubectl label pods -l app=hello-kiamol-2 --overwrite app=hello-kiamol-x
# 디플로이먼트가 설정한 레이블과 파드의 레이블이 일치하지 않게된다
# 디플로이먼트와 파드 사이의 관리 관계가 끊어지게 된다

# 파드가 또 하나 생성되었다.
kubectl get pods -o custom-columns=NAME:metadata.name,LABELS:metadata.labels
# 디플로이먼트는 입력받은 상태(파드 1개 유지)를 맞추기 위해 새로운 파드를 생성한다
# 레이블이 바뀐 기존 파드는 누구의 관리도 받지 안흔 독립적인 파드가 되어 클러스터에 남아있게 된다&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;148&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/neLdX/dJMcagZ8UaJ/NdQeJ90I89RaqtoUmvFA1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/neLdX/dJMcagZ8UaJ/NdQeJ90I89RaqtoUmvFA1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/neLdX/dJMcagZ8UaJ/NdQeJ90I89RaqtoUmvFA1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FneLdX%2FdJMcagZ8UaJ%2FNdQeJ90I89RaqtoUmvFA1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;755&quot; height=&quot;148&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;148&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 파랑: 모든 파드 이름과 레이블을 확인해보니 레이블 이름과 같은 콜론으로 구분된다. (app:hello-kiamol-2)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 빨강: 'app' 레이블의 값이 hello-kiamol-2인 파드를 모두 찾아 해당 레이블 값을 &lt;b&gt;hello-kiamol-x로 수정&lt;/b&gt;한다. 레이블이 수정되면 실질적으로 파드와 디플로이먼트 간의 관계그 끊어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 노랑: 레이블이 수정되면서 디플로이먼트 입장에선 파드가 유실됐으므로 이를 대체하는 새로운 파드가 만들어진 것을 볼 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 레이블 원래대로 수정하기&lt;/h4&gt;
&lt;pre id=&quot;code_1781601008839&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 'app'이라는 레이블이 부여된 모든 파드의 이름과 레이블을 출력
kubectl get pods -l app -o custom-columns=NAME:metadata.name,LABELS:metadata.labels

# 디플로이먼트의 관리를 벗어난 파드의 'app' 레이블을 원래대로 수정
kubectl label pods -l app=hello-kiamol-x --overwrite app=hello-kiamol-2
# 디플로이먼트는 쿠버네티스 API를 통해 레이블 셀렉터와 일치하는 파드 수가 두 개가 된 것을 확인하고,
# 정의상 파드를 하나만 유지하면 되므로 그중 하나를 삭제한다

# 파드의 목록을 다시 한 번 확인
kubectl get pods -l app -o custom-columns=NAME:metadata.name,LABELS:metadata.labels&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;176&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxjppO/dJMcacpZnKY/oKcLQ22iLw8mgryCiKmvV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxjppO/dJMcacpZnKY/oKcLQ22iLw8mgryCiKmvV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxjppO/dJMcacpZnKY/oKcLQ22iLw8mgryCiKmvV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxjppO%2FdJMcacpZnKY%2FoKcLQ22iLw8mgryCiKmvV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;819&quot; height=&quot;176&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;176&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 디플로이먼트 포트포워딩&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스 안에서 실행 중인 파드(Pod)는 기본적으로 '쿠버네티스 내부 네트워크(Cluster IP)'에 갇혀 있다. 따라서 EC2 인스턴스 안에서는 보이지만, 외부(내 PC)에서는 접근할 수 없다.&lt;/p&gt;
&lt;pre id=&quot;code_1781601051345&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 로컬 컴퓨터에서 디플로이먼트로 포트포워딩 설정
# kubectl port-forward deploy/hello-kiamol-2 8080:80
kubectl port-forward --address 0.0.0.0 deploy/hello-kiamol-2 8080:80
# 내 PC와 쿠버네티스 파드 사이에 임시 터널을 뚫어주는 역할을 합니다.
# 특히 --address 0.0.0.0 옵션을 붙이는 이유는, 기본적으로 port-forward는 127.0.0.1 (로컬호스트)에서만 접속 가능하게 막혀있는데, 이걸 열어서 EC2 외부(질문자님의 PC)에서도 접속할 수 있게 만들어주는 것입니다.

# 웹 브라우저에서 http://localhost:8080 접근
# 확인이 끝나면 ctrl+c 로 종료&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bC2pvx/dJMcabkkqWZ/kATMsXNcNigsQfMwnWKNok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bC2pvx/dJMcabkkqWZ/kATMsXNcNigsQfMwnWKNok/img.png&quot; data-alt=&quot;EC2 환경이기 때문에 EC2의 '퍼블릭ip:로트번호'로 젒속했습니다. 접속이 안 된다면 보안 그룹의 인바운드포트 규칙을 열어줄 것!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bC2pvx/dJMcabkkqWZ/kATMsXNcNigsQfMwnWKNok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbC2pvx%2FdJMcabkkqWZ%2FkATMsXNcNigsQfMwnWKNok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;697&quot; height=&quot;208&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;208&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;EC2 환경이기 때문에 EC2의 '퍼블릭ip:로트번호'로 젒속했습니다. 접속이 안 된다면 보안 그룹의 인바운드포트 규칙을 열어줄 것!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹이 잘 나타나는 것을 확인했습니다.&amp;nbsp;&lt;/p&gt;</description>
      <category>클라우드/AWS</category>
      <category>K8s</category>
      <category>쿠버네티스</category>
      <author>JJong_H</author>
      <guid isPermaLink="true">https://study-it-all.tistory.com/261</guid>
      <comments>https://study-it-all.tistory.com/261#entry261comment</comments>
      <pubDate>Tue, 16 Jun 2026 18:24:57 +0900</pubDate>
    </item>
    <item>
      <title>[클라우드 프로그래밍] 9주차 파드 삭제</title>
      <link>https://study-it-all.tistory.com/260</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Deployment&lt;/h2&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; font-size: 16px; letter-spacing: 0px;&quot; data-path-to-node=&quot;7,0,1,0,0,1&quot;&gt;디플로이먼트(Deployment)가 레플리카셋(ReplicaSet)을 관리하고, 이 레플리카셋이 파드(Pod)들을 관리합니다&lt;/span&gt;&lt;span style=&quot;color: #333333; font-size: 16px; letter-spacing: 0px;&quot; data-path-to-node=&quot;7,0,1,0,0,2&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; font-size: 16px; letter-spacing: 0px;&quot; data-path-to-node=&quot;7,0,1,0,0,3&quot;&gt;.&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;파드(Pod):&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;쿠버네티스의 최소 배포 단위&lt;/b&gt;로, 쿠버네티스에서 애플리케이션을 구성하는 기본 요소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너는&amp;nbsp;항상 파드&amp;nbsp;안에&amp;nbsp;포함되어&amp;nbsp;동작하며,&amp;nbsp;파드란&amp;nbsp;하나&amp;nbsp;또는&amp;nbsp;그&amp;nbsp;이상의&amp;nbsp;컨테이너를&amp;nbsp;관리하는&amp;nbsp;데&amp;nbsp;사용하는&amp;nbsp;단위이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 컨테이너를 직접 실행하지 않는 것처럼, &lt;b&gt;실제 운영 환경에서 파드조차 직접 하나하나 관리하지 않는다&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 &lt;u&gt;&lt;b&gt;리소스(디플로이먼트)&lt;/b&gt;&lt;/u&gt;가 파드를 관리하고, 우리가 원하는 애플리케이션 상태(사용자가 정해준 상태)를 지시면 이 상태를 실제로 만들어 낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;컨테이너&lt;/b&gt;는 일반적으로 애플리케이션 구성 요소 하나를 실행하는 가상화된 환경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;파드&lt;/b&gt;는 이 컨테이너를 감싼 또 다른 가상 환경으로, 클러스터를 이루는 노드 중 하나에서 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 파드는 쿠버네티스로 관리되는&amp;nbsp;&lt;u&gt;가상&amp;nbsp;IP&amp;nbsp;주소&lt;/u&gt;를 가지며, 이 주소로 가상 네트워크에 접속된 다른 파드, 다른 노드에서 실행되는 파드와 통신을 주고받을 수 있다. 또한 파드에 포함된 모든 컨테이너는 이 IP 주소를 공유한다. 파드에 포함된 IP주소가 여러 개이면 이들은 localhost로 서로 통신할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드는 쿠버네티스가 관리하는 가상 네트워크에 연결된다. 파드 역시 IP 주소를 기반으로 통신하며, 서로 다른 노드에서 실행되더라도 통신이 가능하다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;쿠버네티스 컨테이너 실행 관리 실습&lt;/h3&gt;
&lt;pre id=&quot;code_1781598662085&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 예제코드 내려받기
# Master 노드에서만 한 번 실행한다.
git clone https://github.com/gilbutITbook/kiamol&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 작업은 마스터 노드에서 명령어를 통해 수행한다. 마스터 노드에서 내린 명령을 쿠버네티스 API 서버가 받아 워커 노드들에게 전달한다. 그래서 위 실습 예제 코드는 Master에서 한 번만 실행하면 되는 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;마스터 노드 &amp;rarr; 쿠버네티스 API 서버 &amp;rarr; 워커 노드&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;422&quot; data-origin-height=&quot;94&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhg2tj/dJMb9906rgJ/OSppYOrC20lqx897R4Dv7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhg2tj/dJMb9906rgJ/OSppYOrC20lqx897R4Dv7k/img.png&quot; data-alt=&quot;모두 READY 상태에서 실습 진행&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhg2tj/dJMb9906rgJ/OSppYOrC20lqx897R4Dv7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbhg2tj%2FdJMb9906rgJ%2FOSppYOrC20lqx897R4Dv7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;422&quot; height=&quot;94&quot; data-origin-width=&quot;422&quot; data-origin-height=&quot;94&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;모두 READY 상태에서 실습 진행&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;YAML 파일 정의 없이 파드 생성 및 관리&lt;/p&gt;
&lt;pre id=&quot;code_1781598750293&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 컨테이너 하나를 담은 파드를 실행한다
kubectl run hello-kiamol --image=kiamol/ch02-hello-kiamol
# --image의 이미지를 사용하여 'hello-kiamol'이름의 파드를 생성

# 파드가 준비 상태가 될 때까지 기다린다
kubectl wait --for=condition=Ready pod hello-kiamol
# 'pod/hello-kiamol condition met'이 출력되면 정상 결과이다

# 클러스터에 있는 모든 파드의 목록을 출력한다
kubectl get pods

# 파드의 상세 정보를 확인한다
kubectl describe pod hello-kiamol
# 파드가 어느 노드에 배치되었는지, 할당된 주소는 무엇인지 확인할 수 있다&lt;/code&gt;&lt;/pre&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;-- 실행 결과 (로그가 길어서 캡쳐를 뜨면 보이지 않아 복붙) --&lt;br /&gt;&lt;br /&gt;ubuntu@master:~$&amp;nbsp;kubectl&amp;nbsp;describe&amp;nbsp;pod&amp;nbsp;hello-kiamol &lt;br /&gt;Name:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hello-kiamol &lt;br /&gt;Namespace:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;default &lt;br /&gt;Priority:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0 &lt;br /&gt;Service&amp;nbsp;Account:&amp;nbsp;&amp;nbsp;default &lt;br /&gt;Node:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;worker1/172.31.43.245 &lt;br /&gt;Start&amp;nbsp;Time:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Tue,&amp;nbsp;16&amp;nbsp;Jun&amp;nbsp;2026&amp;nbsp;08:32:45&amp;nbsp;+0000 &lt;br /&gt;Labels:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;run=hello-kiamol &lt;br /&gt;Annotations:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cni.projectcalico.org/containerID:&amp;nbsp;5bd80c171368e48a6893d4bf6366d201a947d20e42d93b8528b3d3905191cf2f &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cni.projectcalico.org/podIP:&amp;nbsp;192.168.235.129/32 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cni.projectcalico.org/podIPs:&amp;nbsp;192.168.235.129/32 &lt;br /&gt;Status:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Running &lt;br /&gt;IP:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;192.168.235.129 &lt;br /&gt;IPs: &lt;br /&gt;&amp;nbsp;&amp;nbsp;IP:&amp;nbsp;&amp;nbsp;192.168.235.129 &lt;br /&gt;Containers: &lt;br /&gt;&amp;nbsp;&amp;nbsp;hello-kiamol: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Container&amp;nbsp;ID:&amp;nbsp;&amp;nbsp;&amp;nbsp;containerd://308795a323ec0c34261c74f2bb811f110460eb4aad044ed630881c12c66c49ea &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Image:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;kiamol/ch02-hello-kiamol &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Image&amp;nbsp;ID:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;docker.io/kiamol/ch02-hello-kiamol@sha256:f4165d27755978cffde4e5cc7187e8123d929d239409e108e760130d9e0d8f2f &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Port:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;none&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Host&amp;nbsp;Port:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;none&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;State:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Running &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Started:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Tue,&amp;nbsp;16&amp;nbsp;Jun&amp;nbsp;2026&amp;nbsp;08:32:50&amp;nbsp;+0000 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Ready:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;True &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Restart&amp;nbsp;Count:&amp;nbsp;&amp;nbsp;0 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Environment:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;none&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mounts: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/var/run/secrets/kubernetes.io/serviceaccount&amp;nbsp;from&amp;nbsp;kube-api-access-xsxjq&amp;nbsp;(ro) &lt;br /&gt;Conditions: &lt;br /&gt;&amp;nbsp;&amp;nbsp;Type&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Status &lt;br /&gt;&amp;nbsp;&amp;nbsp;PodReadyToStartContainers&amp;nbsp;&amp;nbsp;&amp;nbsp;True &lt;br /&gt;&amp;nbsp;&amp;nbsp;Initialized&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;True &lt;br /&gt;&amp;nbsp;&amp;nbsp;Ready&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;True &lt;br /&gt;&amp;nbsp;&amp;nbsp;ContainersReady&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;True &lt;br /&gt;&amp;nbsp;&amp;nbsp;PodScheduled&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;True &lt;br /&gt;Volumes: &lt;br /&gt;&amp;nbsp;&amp;nbsp;kube-api-access-xsxjq: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Type:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Projected&amp;nbsp;(a&amp;nbsp;volume&amp;nbsp;that&amp;nbsp;contains&amp;nbsp;injected&amp;nbsp;data&amp;nbsp;from&amp;nbsp;multiple&amp;nbsp;sources) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TokenExpirationSeconds:&amp;nbsp;&amp;nbsp;3607 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ConfigMapName:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;kube-root-ca.crt &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ConfigMapOptional:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;nil&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DownwardAPI:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;true &lt;br /&gt;QoS&amp;nbsp;Class:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BestEffort &lt;br /&gt;Node-Selectors:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;none&amp;gt; &lt;br /&gt;Tolerations:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;node.kubernetes.io/not-ready:NoExecute&amp;nbsp;op=Exists&amp;nbsp;for&amp;nbsp;300s &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;node.kubernetes.io/unreachable:NoExecute&amp;nbsp;op=Exists&amp;nbsp;for&amp;nbsp;300s &lt;br /&gt;Events: &lt;br /&gt;&amp;nbsp;&amp;nbsp;Type&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Reason&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Age&amp;nbsp;&amp;nbsp;&amp;nbsp;From&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Message &lt;br /&gt;&amp;nbsp;&amp;nbsp;----&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;------&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;----&amp;nbsp;&amp;nbsp;----&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;------- &lt;br /&gt;&amp;nbsp;&amp;nbsp;Normal&amp;nbsp;&amp;nbsp;Scheduled&amp;nbsp;&amp;nbsp;37s&amp;nbsp;&amp;nbsp;&amp;nbsp;default-scheduler&amp;nbsp;&amp;nbsp;Successfully&amp;nbsp;assigned&amp;nbsp;default/hello-kiamol&amp;nbsp;to&amp;nbsp;worker1 &lt;br /&gt;&amp;nbsp;&amp;nbsp;Normal&amp;nbsp;&amp;nbsp;Pulling&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;36s&amp;nbsp;&amp;nbsp;&amp;nbsp;kubelet&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Pulling&amp;nbsp;image&amp;nbsp;&quot;kiamol/ch02-hello-kiamol&quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;Normal&amp;nbsp;&amp;nbsp;Pulled&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;32s&amp;nbsp;&amp;nbsp;&amp;nbsp;kubelet&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Successfully&amp;nbsp;pulled&amp;nbsp;image&amp;nbsp;&quot;kiamol/ch02-hello-kiamol&quot;&amp;nbsp;in&amp;nbsp;3.921s&amp;nbsp;(3.921s&amp;nbsp;including&amp;nbsp;waiting) &lt;br /&gt;&amp;nbsp;&amp;nbsp;Normal&amp;nbsp;&amp;nbsp;Created&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;32s&amp;nbsp;&amp;nbsp;&amp;nbsp;kubelet&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Created&amp;nbsp;container:&amp;nbsp;hello-kiamol &lt;br /&gt;&amp;nbsp;&amp;nbsp;Normal&amp;nbsp;&amp;nbsp;Started&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;32s&amp;nbsp;&amp;nbsp;&amp;nbsp;kubelet&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Started&amp;nbsp;container&amp;nbsp;hello-kiamol &lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;pre id=&quot;code_1781598883362&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 다양한 형태로 파드 리소스 정보 출력

# 파드에 대한 기본적인 정보를 확인한다
kubectl get pod hello-kiamol
# 전체 파드 정보 확인: kubectl get pod

# 네트워크 상세 정보 중 특정한 항목을 따로 지정해서 출력한다
kubectl get pod hello-kiamol --output custom-columns=NAME:metadata.name,NODE_IP:status.hostIP,POD_IP:status.podIP
# 출력 결과의 NODE_IP 내용으로 어떤 워커노드에서 파드가 생성됐는지 알 수 있다

# JSONPath로 복잡한 출력을 구성한다
# 파드의 첫 번째 컨테이너의 컨테이너 식별자만 출력한다
kubectl get pod hello-kiamol -o jsonpath='{.status.containerStatuses[0].containerID}'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;718&quot; data-origin-height=&quot;209&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OEtZR/dJMcaci8GO5/lR5vrYJW0wEprnKBcKx1lk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OEtZR/dJMcaci8GO5/lR5vrYJW0wEprnKBcKx1lk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OEtZR/dJMcaci8GO5/lR5vrYJW0wEprnKBcKx1lk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOEtZR%2FdJMcaci8GO5%2FlR5vrYJW0wEprnKBcKx1lk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;718&quot; height=&quot;209&quot; data-origin-width=&quot;718&quot; data-origin-height=&quot;209&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;빨강: 출력의 기본 형태는 컨테이너 개수, 파드의 상태, 재시작 횟수, 파드 생성 후 경과시간으로 구성된다.&lt;/li&gt;
&lt;li&gt;없음: 이름과 그에 대응하는 데이터의 JSON 표현 형태로 항목을 정의해서 출력 형태를 저장할 수 있다.&lt;/li&gt;
&lt;li&gt;노랑: JSONPath 질의 형태로 복잡한 출력을 직접 구성할 수도 있다. 예제에 나온 질의는 파드에 포함된 첫 번째 컨테이너의 컨테이너 식별자를 출력하라는 의미다. 지금은 컨테이너가 하나뿐이지만, 파드에 컨테이너가 여러 개 있어도 첫 번째 컨테이너의 식별자만 출력된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;pod 안의 컨테이너 삭제해보기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;Docker 이용. 비추천하는 방법&lt;/i&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1781599167428&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 우리 실습 환경에서는 컨테이너 런타임이 containerd이다
# 아래 예제를 진행하려면 컨테이너 런타임이 도커여야만 한다.

# 파드에 포함된 컨테이너 찾기
docker container ls -q --filter label=io.kubernetes.container.name=hello-kiamol
혹은
sudo crictl ps -q --label io.kubernetes.container.name=hello-kiamol&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스는 컨테이너를 만들 때 파드 이름을 &lt;u&gt;&lt;b&gt;컨테이너 레이블&lt;/b&gt;&lt;/u&gt;에 추가한다. 이 점을 활용하여 도커에서 파드에 포함된 컨테이너를 찾아낼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1781599519875&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 해당 컨테이너 삭제하기
docker container rm -f $(docker container ls -q --filter label=io.kubernetes.container.name=hello-kiamol)
혹은
sudo crictl rm -f $(sudo crictl ps -q --label io.kubernetes.container.name=hello-kiamol)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 찾은 컨테이너를 삭제한다. 이 파드는 한 개의 컨테이너가 있어야 하지만 이제 파드에는 컨테이너가 없다.&lt;/p&gt;
&lt;pre id=&quot;code_1781599527660&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 파드 상태 확인
kubectl get pod hello-kiamol&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드의 상세 정보에서 한 개의 컨테이너가 동작 중임을 확인한다.&lt;/p&gt;
&lt;pre id=&quot;code_1781599532121&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 이전 컨테이너 다시 찾아보기
docker container ls -q --filter label=io.kubernetes.container.name=hello-kiamol
혹은
sudo crictl ps -a -q --label io.kubernetes.container.name=hello-kiamol
# (참고: 삭제 후 다시 찾아볼 때는 -a (all) 옵션을 붙여야 이미 삭제된 컨테이너의 흔적까지 볼 수 있다.)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 컨테이너의 식별자가 이전과는 다르다. 쿠버네티스가 새로운 컨테이너로 파드를 복원했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스 환경에서는 컨테이너 자체를 지우는 것보다 &lt;b data-index-in-node=&quot;32&quot; data-path-to-node=&quot;13&quot;&gt;파드(Pod)를 관리하는 것&lt;/b&gt;이 정석이다. 쿠버네티스가 제공하는 기능을 사용하는 것이 훨씬 안전하고 깔끔하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;14,0,0&quot;&gt;파드를 삭제하고 싶을 때:&lt;/b&gt;이렇게 하면 쿠버네티스가 컨테이너를 안전하게 종료하고 파드를 삭제합니다.
&lt;div&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;kubectl delete pod hello-kiamol&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;14,1,0&quot;&gt;파드가 왜 죽었는지(혹은 잘 도는지) 확인하고 싶을 때:&lt;/b&gt;
&lt;div&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;kubectl get pod hello-kiamol -o wide
kubectl describe pod hello-kiamol&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;123&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2y6Bt/dJMcaijoZYv/cYTZOFJooklKsParEA4v8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2y6Bt/dJMcaijoZYv/cYTZOFJooklKsParEA4v8K/img.png&quot; data-alt=&quot;pod &amp;quot;hello-kiamol&amp;quot; deleted&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2y6Bt/dJMcaijoZYv/cYTZOFJooklKsParEA4v8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2y6Bt%2FdJMcaijoZYv%2FcYTZOFJooklKsParEA4v8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;481&quot; height=&quot;123&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;123&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;pod &quot;hello-kiamol&quot; deleted&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pod &quot;hello-kiamol&quot;가 제거되고나서 검색되지 않는 모습이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 디플로이먼트 생성 및 지워진 파드 재실행은 &lt;a href=&quot;https://study-it-all.tistory.com/261&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;다음 실습&lt;/a&gt;에서 진행&lt;/p&gt;</description>
      <category>클라우드/AWS</category>
      <category>K8s</category>
      <category>쿠버네티스</category>
      <author>JJong_H</author>
      <guid isPermaLink="true">https://study-it-all.tistory.com/260</guid>
      <comments>https://study-it-all.tistory.com/260#entry260comment</comments>
      <pubDate>Tue, 16 Jun 2026 17:53:06 +0900</pubDate>
    </item>
    <item>
      <title>[클라우드 프로그래밍] 7주차 linux에서 쿠버네티스 환경 구축하기</title>
      <link>https://study-it-all.tistory.com/259</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;저는 virtual box에서 오류가 발생하는 바람에 EC2 환경에서 실습을 진행하게 됐습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안그룹은 gemini의 도움으로 같은 클러스터 내에서 네트워킹을 잘 할 수 있도록 연결 설정을 완료했습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;보안 그룹 설정&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;336&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJFTy4/dJMcagMH2Pw/CFrrNAVe6Dwy2yghP0Rps0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJFTy4/dJMcagMH2Pw/CFrrNAVe6Dwy2yghP0Rps0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJFTy4/dJMcagMH2Pw/CFrrNAVe6Dwy2yghP0Rps0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJFTy4%2FdJMcagMH2Pw%2FCFrrNAVe6Dwy2yghP0Rps0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1260&quot; height=&quot;336&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;336&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFsTgW/dJMcacKi8wr/CkqeTBxSm6Q5I8nRGzhIzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFsTgW/dJMcacKi8wr/CkqeTBxSm6Q5I8nRGzhIzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFsTgW/dJMcacKi8wr/CkqeTBxSm6Q5I8nRGzhIzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFsTgW%2FdJMcacKi8wr%2FCkqeTBxSm6Q5I8nRGzhIzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;648&quot; height=&quot;222&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;222&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1781596077513&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo hostnamectl set-hostname master
bash&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령으로 ubuntu@프라이빗주소 형태의 이름 대신 별명을 붙여서 볼 수 있게 해두었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-path-to-node=&quot;3&quot; data-ke-size=&quot;size23&quot;&gt;1단계: 기본 설정 및 Containerd 설치 (모든 노드 공통)&lt;/h3&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;4&quot;&gt;1. 스왑(Swap) 메모리 끄기&lt;/b&gt; 쿠버네티스가 정상 작동하기 위한 필수 조건입니다.&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQkyE&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;sudo swapoff -a
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-path-to-node=&quot;6&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;6&quot;&gt;2. 필수 패키지 설치 및 Docker 공식 GPG 키 등록&lt;/b&gt; 이전에 계속 실패했던 그 부분입니다. EC2에서는 순식간에 완료될 것입니다. 한 줄씩, 혹은 뭉텅이로 복사해서 붙여넣어 주세요.&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQlCE&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8&quot;&gt;3. APT 저장소에 Docker 리포지토리 추가&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQlSE&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&quot;)
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-path-to-node=&quot;10&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;10&quot;&gt;4. Containerd 설치&lt;/b&gt; (강의 자료에 따라 전체 도커를 깔아도 되지만, 최신 쿠버네티스에서는 가벼운 containerd.io만 설치하는 것이 표준입니다.)&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQliE&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install -y containerd.io
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-path-to-node=&quot;12&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;12&quot;&gt;5. Containerd 설정 변경 (★가장 중요★)&lt;/b&gt; 쿠버네티스(Kubelet)와 컨테이너 엔진이 똑같은 관리자(systemd)를 사용하도록 설정을 맞춰주는 작업입니다. 이 설정을 안 하면 나중에 노드가 'NotReady' 상태에 빠집니다.&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQlyE&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml &amp;gt; /dev/null
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-path-to-node=&quot;14&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;14&quot;&gt;6. 서비스 재시작 및 자동 실행 등록&lt;/b&gt; 방금 바꾼 설정을 적용하기 위해 서비스를 껐다 켭니다.&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQmCE&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;sudo systemctl restart containerd
sudo systemctl enable containerd
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-path-to-node=&quot;17&quot; data-ke-size=&quot;size23&quot;&gt;1단계 완료 확인&lt;/h3&gt;
&lt;p data-path-to-node=&quot;18&quot; data-ke-size=&quot;size16&quot;&gt;세 대의 노드에서 모두 위 작업을 마치셨다면, 각각의 창에 아래 명령어를 쳐보세요.&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQmSE&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;sudo systemctl status containerd
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-path-to-node=&quot;20&quot; data-ke-size=&quot;size16&quot;&gt;출력 결과 중에 &lt;b data-index-in-node=&quot;9&quot; data-path-to-node=&quot;20&quot;&gt;초록색으로 active (running)&lt;/b&gt; 이 뜬다면 1단계가 완벽하게 성공한 것입니다! (확인 후 터미널 창에서 빠져나오려면 키보드 q를 누르시면 됩니다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;681&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rLIlT/dJMb99UhIqD/SAaZvp89EvtaG9dJVR4esK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rLIlT/dJMb99UhIqD/SAaZvp89EvtaG9dJVR4esK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rLIlT/dJMb99UhIqD/SAaZvp89EvtaG9dJVR4esK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrLIlT%2FdJMb99UhIqD%2FSAaZvp89EvtaG9dJVR4esK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;621&quot; height=&quot;681&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;681&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-path-to-node=&quot;6&quot; data-ke-size=&quot;size23&quot;&gt;(네트워크 커널 설정 켜기)&lt;/h3&gt;
&lt;p data-path-to-node=&quot;7&quot; data-ke-size=&quot;size16&quot;&gt;이 설정은 마스터 노드뿐만 아니라 &lt;b data-index-in-node=&quot;19&quot; data-path-to-node=&quot;7&quot;&gt;Worker1, Worker2 노드 터미널에도 똑같이&lt;/b&gt; 적용해 주셔야 나중에 통신 에러가 나지 않습니다. 세 대의 터미널에 아래 명령어를 뭉텅이로 복사/붙여넣기 해주세요.&lt;/p&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8&quot;&gt;1. 리눅스 네트워크 커널 모듈 활성화&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQ-iE&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt;EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-path-to-node=&quot;10&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;10&quot;&gt;2. IP 포워딩 및 iptables 설정 적용&lt;/b&gt;&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQ-yE&quot; data-hveid=&quot;0&quot;&gt;
&lt;pre class=&quot;dos&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt;EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

sudo sysctl --system&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-path-to-node=&quot;3&quot; data-ke-size=&quot;size23&quot;&gt;2단계: 쿠버네티스 3대장 설치 (kubeadm, kubelet, kubectl)&lt;/h3&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;4&quot;&gt;  대상: 모든 노드 (Master, Worker1, Worker2)&lt;/b&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;5&quot; data-ke-size=&quot;size16&quot;&gt;이 명령어들도 세 대의 터미널 창에 모두 똑같이 복사/붙여넣기 해주시면 됩니다. &lt;i data-index-in-node=&quot;45&quot; data-path-to-node=&quot;5&quot;&gt;(참고: 2024년 초에 쿠버네티스 공식 저장소 주소가 변경되었으므로, 최신 표준 방식인 pkgs.k8s.io 주소를 사용한 명령어입니다.)&lt;/i&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;6&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;6&quot;&gt;1. 필수 패키지 설치 및 GPG 키 다운로드&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQvSE&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

# 기존 키가 있다면 덮어쓰기 에러가 나지 않도록 폴더 확인 후 키 다운로드
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8&quot;&gt;2. APT 저장소 목록에 쿠버네티스 추가&lt;/b&gt;&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQviE&quot; data-hveid=&quot;0&quot;&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-path-to-node=&quot;10&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;10&quot;&gt;3. 패키지 설치 및 버전 고정&lt;/b&gt; (버전을 고정해 두면 나중에 우분투가 멋대로 업데이트해서 클러스터가 깨지는 것을 막아줍니다.)&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQvyE&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-path-to-node=&quot;13&quot; data-ke-size=&quot;size23&quot;&gt;3단계: 마스터 노드 초기화 (컨트롤 플레인 구축)&lt;/h3&gt;
&lt;p data-path-to-node=&quot;14&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;14&quot;&gt;  대상: 오직 &lt;span style=&quot;color: #ee2323;&quot;&gt;Master 노드&lt;/span&gt;에서만 (Worker 창은 잠시 대기)&lt;/b&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;15&quot; data-ke-size=&quot;size16&quot;&gt;이제 워커 노드들을 지휘할 대장(Master) 서버의 뇌를 깨울 차례입니다. &lt;b data-index-in-node=&quot;43&quot; data-path-to-node=&quot;15&quot;&gt;Master 창에서만&lt;/b&gt; 아래 명령어를 실행해 주세요.&lt;/p&gt;
&lt;p data-path-to-node=&quot;16&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;16&quot;&gt;1. 클러스터 초기화&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQwCE&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;sudo kubeadm init
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-path-to-node=&quot;18&quot; data-ke-size=&quot;size16&quot;&gt;이 명령어를 치면 마스터 노드가 수많은 초기화 작업을 백그라운드에서 진행하며 화면에 로그가 주르륵 올라갑니다. (1~3분 정도 소요될 수 있습니다.)&lt;/p&gt;
&lt;p data-path-to-node=&quot;19&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;19&quot;&gt;2. 완료 후 조치 (가장 중요!)&lt;/b&gt; 초기화가 성공적으로 끝나면 화면에 아주 긴 결과 메시지가 출력됩니다. 그중에서 아래 두 가지를 꼭 확인하셔야 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;20&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;20,0,0&quot;&gt;첫 번째 (조종기 권한 설정):&lt;/b&gt; 중간쯤에 있는 아래 세 줄을 Master 창에 복사해서 붙여넣습니다.&lt;span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQwSE&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;20,1,0&quot;&gt;두 번째 (워커 노드 초대장):&lt;/b&gt; 화면 맨 밑에 kubeadm join 172.31.X.X:6443 --token ... 으로 시작하는 긴 명령어가 있습니다. &lt;b data-index-in-node=&quot;88&quot; data-path-to-node=&quot;20,1,0&quot;&gt;이 명령어를 마우스로 드래그해서 꼭 메모장에 복사해 두세요!&lt;/b&gt; (4단계에서 워커 노드들에 입력할 비밀번호입니다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;59&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V06Kg/dJMcac4xiNH/Ji8eLeIeCFaQwKuTeuAkV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V06Kg/dJMcac4xiNH/Ji8eLeIeCFaQwKuTeuAkV1/img.png&quot; data-alt=&quot;kubeadm join 172.31.43.132:6443 --token uk9url.xwr76l58mxi94eoy \ --discovery-token-ca-cert-hash sha256:a1fc5b984b6ea8d51c8bc97d7b765e1a32371a2556ca8a3141e18765f4c7f7f7&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V06Kg/dJMcac4xiNH/Ji8eLeIeCFaQwKuTeuAkV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV06Kg%2FdJMcac4xiNH%2FJi8eLeIeCFaQwKuTeuAkV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;643&quot; height=&quot;59&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;59&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;kubeadm join 172.31.43.132:6443 --token uk9url.xwr76l58mxi94eoy \ --discovery-token-ca-cert-hash sha256:a1fc5b984b6ea8d51c8bc97d7b765e1a32371a2556ca8a3141e18765f4c7f7f7&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-path-to-node=&quot;3&quot; data-ke-size=&quot;size23&quot;&gt;4단계: 워커 노드를 클러스터에 합류시키기 (Join)&lt;/h3&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;4&quot;&gt;  대상: &lt;span style=&quot;color: #009a87;&quot;&gt;worker1, worker2 터미널&lt;/span&gt; 창&lt;/b&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;5&quot; data-ke-size=&quot;size16&quot;&gt;올려주신 토큰 명령어 맨 앞에 관리자 권한인 sudo만 붙여서 두 대의 워커 노드 터미널에 각각 복사/붙여넣기 하고 엔터를 쳐주세요.&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQrCI&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;sudo kubeadm join 172.31.43.132:6443 --token uk9url.xwr76l58mxi94eoy \
        --discovery-token-ca-cert-hash sha256:a1fc5b984b6ea8d51c8bc97d7b765e1a32371a2556ca8a3141e18765f4c7f7f7
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;7&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실행 후 화면에 &lt;b data-index-in-node=&quot;9&quot; data-path-to-node=&quot;7,0,0&quot;&gt;&quot;This node has joined the cluster&quot;&lt;/b&gt; 라는 문구가 뜨면 성공적으로 마스터의 부하(?)로 들어간 것입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-path-to-node=&quot;9&quot; data-ke-size=&quot;size23&quot;&gt;5단계: 네트워크 플러그인(CNI) 설치&lt;/h3&gt;
&lt;p data-path-to-node=&quot;10&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;10&quot;&gt;  대상: 오직 &lt;span style=&quot;color: #ee2323;&quot;&gt;master 터미널&lt;/span&gt; 창에서만&lt;/b&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;11&quot; data-ke-size=&quot;size16&quot;&gt;워커 노드들이 합류하긴 했지만, 아직 노드들끼리 통신할 수 있는 '가상 랜선'이 깔리지 않아서 모두 NotReady (준비 안 됨) 상태로 대기하고 있을 것입니다. 가상 랜선을 깔아주기 위해 마스터 창에 아래 명령어를 입력해 주세요. (가장 널리 쓰이는 Calico 플러그인 기준입니다. 만약 교수님 강의 자료에 Weave나 Flannel 등 다른 플러그인이 있다면 그걸 쓰셔도 무방합니다.)&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQrSI&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;crystal&quot;&gt;&lt;code&gt;kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-path-to-node=&quot;14&quot; data-ke-size=&quot;size23&quot;&gt;최종 클러스터 확인&lt;/h3&gt;
&lt;p data-path-to-node=&quot;15&quot; data-ke-size=&quot;size16&quot;&gt;위의 통신망 설치까지 끝났다면, 마스터 노드 터미널에서 아래 명령어를 치고 1~2분 정도 기다려 보세요.&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjXo4ma-IqVAxUAAAAAHQAAAAAQriI&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;kubectl get nodes&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;96&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsEU68/dJMcaayVY9X/Kox75EhVu1LBtXmHpLtCr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsEU68/dJMcaayVY9X/Kox75EhVu1LBtXmHpLtCr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsEU68/dJMcaayVY9X/Kox75EhVu1LBtXmHpLtCr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsEU68%2FdJMcaayVY9X%2FKox75EhVu1LBtXmHpLtCr0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;433&quot; height=&quot;96&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;96&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;422&quot; data-origin-height=&quot;94&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfhxIL/dJMb997O3D3/idj8hTltcf6sRbK0m6vhiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfhxIL/dJMb997O3D3/idj8hTltcf6sRbK0m6vhiK/img.png&quot; data-alt=&quot;잠시 대기하니, Ready 상태로 변경됐습니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfhxIL/dJMb997O3D3/idj8hTltcf6sRbK0m6vhiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfhxIL%2FdJMb997O3D3%2Fidj8hTltcf6sRbK0m6vhiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;422&quot; height=&quot;94&quot; data-origin-width=&quot;422&quot; data-origin-height=&quot;94&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;잠시 대기하니, Ready 상태로 변경됐습니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>클라우드/AWS</category>
      <category>쿠버네티스</category>
      <author>JJong_H</author>
      <guid isPermaLink="true">https://study-it-all.tistory.com/259</guid>
      <comments>https://study-it-all.tistory.com/259#entry259comment</comments>
      <pubDate>Tue, 16 Jun 2026 17:10:02 +0900</pubDate>
    </item>
  </channel>
</rss>