Kubernetes 구조 및 원리 이해
1.  Kubernetes 주요 개념 이해 
1-1. 구조 이해하기 
다음의 용어들이 무엇인지 간단히 설명하고, 이것들을 이용해 Kubernetes의 Architecture를 그려보세요. 
Kubernetes 
kubectl 
kube-apiserver 
etcd 
controller-manager 
scheduler 
node 
kubelet 
pod
- Kubernetes (쿠버네티스): 컨테이너화된 애플리케이션을 자동으로 배포, 확장 및 관리해주는 오픈소스 시스템입니다. 줄여서 'K8s'라고도 부릅니다.
 - kubectl: Kubernetes 클러스터를 제어하기 위한 커맨드 라인 도구(CLI)입니다. 사용자는 kubectl을 통해 클러스터에 명령을 내립니다.
 - kube-apiserver: Kubernetes API를 노출하는 컨트롤 플레인의 핵심 컴포넌트입니다. kubectl을 포함한 모든 클러스터 통신은 이 API 서버를 통해 이루어집니다.
 - etcd: 모든 클러스터 데이터를 저장하는 키-값 저장소입니다. 클러스터의 상태, 구성 정보 등을 모두 이곳에 저장하여 일관성을 유지합니다.
 - controller-manager (컨트롤러 매니저): 클러스터의 상태를 관리하고 조절하는 다양한 컨트롤러를 실행합니다. 예를 들어, 노드가 다운되면 이를 감지하고 대응하는 역할을 합니다.
 - scheduler (스케줄러): 새로 생성된 Pod를 어떤 Node에 할당할지 결정하는 역할을 합니다. 리소스 요구량, 정책 등을 고려하여 최적의 노드를 찾습니다.
 - Node (노드): 컨테이너화된 애플리케이션(Pod)이 실제로 실행되는 워커 머신(가상 또는 물리적)입니다.
 - kubelet: 각 Node에서 실행되는 에이전트입니다. 컨트롤 플레인의 지시를 받아 컨테이너가 의도된 상태로 동작하도록 관리합니다.
 - Pod (파드): Kubernetes에서 생성하고 관리할 수 있는 가장 작은 배포 단위입니다. 하나 이상의 컨테이너 그룹으로 구성되며, 스토리지와 네트워크를 공유합니다.
 
Kubernetes 아키텍처
Kubernetes 아키텍처는 클러스터를 관리하는 **컨트롤 플레인(Control Plane)**과 애플리케이션이 실행되는 **노드(Node)**들로 구성됩니다.
+--------------------------------------------------------------------+
|                         Control Plane (마스터)                     |
|                                                                    |
|   +-------------------+      +-------------------+       +------+  |
|   |  kube-apiserver   |<---->| controller-manager| <--->| etcd  |  |
|   +-------------------+      +-------------------+       +------+  |
|          ^                       ^                                 |
|          |                       |                                 |
|          |              +-------------------+                      |
|          +--------------|     scheduler     |                      |
|                         +-------------------+                      |
|                                                                    |
+--------------------------------------------------------------------+
       ^
       |  (API 요청/상태 보고)
       |
+------|-----------------------------------------------------------------+
|      v                                                                 |
|   +-----------------------------+     +-----------------------------+  |
|   |          Node 1             |     |          Node 2             |  |
|   |                             |     |                             |  |
|   |  +----------+               |     |  +----------+               |  |
|   |  |  kubelet | <-----------> |     |  |  kubelet | <-----------> |  |
|   |  +----------+   (Pod 관리)  |     |  +----------+   (Pod 관리)  |  |
|   |       ^    |                |     |       ^    |                |  |
|   |       |    v                |     |       |    v                |  |
|   |  +----------+  +----------+ |     |  +----------+  +----------+ |  |
|   |  |   Pod    |  |   Pod    | |     |  |   Pod    |  |   Pod    | |  |
|   |  |(Container)||(Container)| |     |  |(Container)||(Container)| |  |
|   |  +----------+  +----------+ |     |  +----------+  +----------+ |  |
|   +-----------------------------+     +-----------------------------+  |
|                                                                        |
+------------------------------------------------------------------------+
       ^
       |
+------------+
|  kubectl   | (사용자/관리자)
+------------+
흐름 설명:
- 사용자는 kubectl을 통해 "새로운 Pod를 생성해줘"와 같은 명령을 내립니다.
 - 이 명령은 Control Plane의 kube-apiserver로 전달됩니다.
 - kube-apiserver는 요청을 검증하고, 클러스터의 상태 정보를 etcd에 저장합니다.
 - scheduler는 새로운 Pod가 생성되어야 함을 인지하고, 어떤 Node에 할당할지 결정합니다.
 - controller-manager는 클러스터의 전반적인 상태를 모니터링하며, 의도한 상태와 실제 상태가 일치하도록 관리합니다.
 - kubelet은 각 Node에서 자신의 노드에 Pod가 할당되었음을 감지하고, 해당 Pod의 컨테이너를 실행하고 관리합니다.
 - 이 모든 과정에서 각 컴포넌트는 kube-apiserver를 통해 통신하며, 클러스터의 모든 상태는 etcd에 기록됩니다.
 
1-2. 주요 개념 이해하기 
Kubernetes의 다음의 개념들에 대해 서술하세요. 
Replicaset 
Deployment 
Service 
특히 Service의 타입들에 대해 정리
Deployment (디플로이먼트)
Deployment는 Pod와 ReplicaSet에 대한 선언적인 업데이트를 제공하는, 더 상위 레벨의 개념입니다. 애플리케이션의 배포, 업데이트, 롤백을 손쉽게 관리할 수 있게 해줍니다.
- 주요 기능: 애플리케이션의 배포 및 업데이트 관리
 - 작동 방식: 사용자가 원하는 상태를 Deployment에 정의하면, Deployment는 이 상태를 달성하기 위해 ReplicaSet을 생성하고 관리합니다. 예를 들어, "앱 v1을 3개의 Pod로 실행해줘"라고 선언하면 Deployment가 이를 위한 ReplicaSet을 만듭니다. 이후 "앱 v2로 업데이트해줘"라고 선언하면, 새로운 ReplicaSet을 만들어 점진적으로 Pod를 교체하는 '롤링 업데이트'를 수행합니다.
 
Deployment가 ReplicaSet보다 선호되는 이유는 롤링 업데이트, 롤백, 배포 기록 추적 등 훨씬 정교하고 편리한 기능을 제공하기 때문입니다.
Service (서비스)
Service는 여러 Pod에 대한 안정적인 단일 네트워크 엔드포인트를 제공합니다. Pod는 생성되거나 삭제될 때마다 IP 주소가 바뀌기 때문에, 외부 또는 클러스터 내부에서 Pod에 안정적으로 접근하기 어렵습니다. Service는 이러한 Pod들을 논리적인 그룹으로 묶고, 고유한 DNS 이름과 고정된 IP 주소를 부여하여 이 문제를 해결합니다.
- 주요 기능: Pod 그룹에 대한 안정적인 네트워크 연결 제공, 로드 밸런싱
 
Service 타입 (Types)
Service는 어떻게 Pod에 접근을 허용할지에 따라 다음과 같은 타입으로 나뉩니다.
| 타입 | 설명 | 사용 사례 | 
| ClusterIP | (기본값) 클러스터 내부에서만 접근 가능한 가상 IP를 할당합니다. 외부에서는 이 IP로 접근할 수 없습니다. | 클러스터 내부의 다른 애플리케이션 간 통신 | 
| NodePort | 모든 노드(Node)의 특정 포트를 열고, 해당 포트로 들어오는 트래픽을 Service에 연결된 Pod로 전달합니다. ClusterIP가 자동으로 생성됩니다. | 개발 또는 테스트 목적으로 외부 접근이 필요할 때 | 
| LoadBalancer | 클라우드 제공업체(AWS, GCP, Azure 등)의 외부 로드 밸런서를 프로비저닝하고, 이 로드 밸런서를 통해 외부 트래픽을 Service로 전달합니다. | 프로덕션 환경에서 애플리케이션을 외부에 안정적으로 노출할 때 | 
| ExternalName | 클러스터 외부의 특정 DNS 이름(예: mydb.example.com)에 대한 CNAME 레코드를 반환합니다. 클러스터 내에서 외부 서비스를 마치 내부 서비스처럼 사용할 수 있게 해줍니다. | 클러스터 내의 서비스가 외부의 특정 서비스(DB 등)를 참조해야 할 때 | 
2.  Kubernetes 실습 환경 구축 
2-1. 다음 Kubernetes 실행 도구들의 차이점을 간단히 비교해 보세요. 
EKS, Minikube, Kind
EKS, Minikube, Kind는 모두 쿠버네티스 환경을 제공하지만, 목적과 사용 환경에 따라 명확한 차이가 있습니다.
**EKS (Amazon Elastic Kubernetes Service)**는 운영 환경을 위한 관리형 서비스이고, Minikube와 Kind는 로컬 개발 및 테스트를 위한 도구입니다.
아래 표에서 세 가지 도구의 주요 차이점을 확인할 수 있습니다.
| 구분 | EKS (Amazon Elastic Kubernetes Service) | Minikube | Kind (Kubernetes in Docker) | 
| 주요 목적 | 프로덕션 (운영) 환경 🚀 | 로컬 개발 및 학습 💻 | 로컬 개발 및 CI/CD ⚙️ | 
| 환경 | AWS 클라우드 | 개인 컴퓨터 (VM 또는 Docker) | 개인 컴퓨터 (Docker) | 
| 아키텍처 | 관리형 서비스 (AWS가 컨트롤 플레인 관리) | 단일 노드 클러스터 (VM 또는 컨테이너) | Docker 컨테이너를 노드로 사용 (다중 노드 구성 가능) | 
| 설치 및 설정 | AWS 인프라 구성 필요 | 간단한 명령어, 하이퍼바이저/Docker 필요 | 매우 빠름, Docker만 필요 | 
| 핵심 특징 | - 고가용성 및 확장성 보장 - AWS 생태계와 완벽한 통합 - 보안 및 안정성 중심  | 
- 다양한 애드온(Add-on) 내장 - 쿠버네티스 기능 학습에 용이  | 
- 클러스터 생성 및 삭제가 매우 빠름 - 다중 노드 클러스터 구성 용이 - 테스트 자동화에 유리  | 
| 적합한 사용자 | 실제 서비스를 운영하려는 기업 또는 개발자 | 쿠버네티스를 처음 배우는 입문자, 개인 개발자 | 빠른 테스트 환경이 필요한 개발자, CI/CD 파이프라인 | 
2-2. minikube를 설치해 보세요. 
참고 : https://minikube.sigs.k8s.io/docs/start/?arch=%2Flinux%2Fx86-64%2Fstable%2Fbinary+download

2-3. 다음 명령어를 실행하고 결과를 공유해보세요.
minikube start
echo 'alias kubectl="minikube kubectl --"' >> ~/.bashrc
source ~/.bashrc
kubectl run test-pod --image=nginx
kubectl get pods
kubectl describe pod test-pod
kubectl logs test-pod
kubectl delete pod test-pod
kubectl get pods








3.1 Deployment 구성 : 같은 역할을 하는 웹 서버가 여러 개 실행되는 환경을 구성합니다. 
다음의 조건을 만족하는 nginx Deployment 를 구성하세요. 
웹 서버가 2개 이상 실행되도록 구성 
각각의 웹 서버들은 같은 역할을 하도록 설정 
각 컨테이너는 80번 포트를 통해 웹 서비스를 제공 
이를 적용
Nginx Deployment YAML 구성
아래 내용을 nginx-deployment.yaml과 같은 파일 이름으로 저장하세요.
# apiVersion: 사용할 Kubernetes API 버전을 정의합니다. Deployment는 apps/v1을 사용합니다.
apiVersion: apps/v1
# kind: 생성할 리소스의 종류를 정의합니다. 여기서는 Deployment입니다.
kind: Deployment
# metadata: 이름 등 리소스를 식별하기 위한 정보입니다.
metadata:
  name: nginx-deployment
  labels:
    app: nginx
# spec: 리소스의 원하는 상태를 상세히 기술합니다.
spec:
  # replicas: 동일한 Pod를 몇 개 복제하여 실행할지 지정합니다. (조건: 2개 이상)
  replicas: 3
  # selector: 이 Deployment가 관리할 Pod를 찾는 방법을 정의합니다.
  selector:
    matchLabels:
      app: nginx
  # template: Deployment가 생성할 Pod의 명세를 정의합니다.
  template:
    metadata:
      # Pod에 'app: nginx' 라벨을 붙여 selector가 찾을 수 있도록 합니다.
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        # 사용할 컨테이너 이미지를 지정합니다.
        image: nginx:latest
        ports:
        # 컨테이너가 노출할 포트를 지정합니다. (조건: 80번 포트)
        - containerPort: 80
YAML 파일 적용하기
위에서 작성한 YAML 파일을 Kubernetes 클러스터에 적용하려면 터미널에서 다음 kubectl 명령어를 실행합니다.
kubectl apply -f nginx-deployment.yaml

적용 확인
Deployment가 성공적으로 생성되고 3개의 Pod가 실행 중인지 확인하려면 다음 명령어를 사용합니다.
kubectl get deployment nginx-deployment
kubectl get pods -l app=nginx


질문 localhost 를 통해 접속허면 나와야 되는거 아냐?
아니요, Deployment만 생성한 상태에서는 localhost로 바로 접속할 수 없습니다. 아주 좋은 질문이며, 많은 분들이 처음 겪는 혼란입니다.
이유는 간단합니다. 생성된 nginx Pod들은 Kubernetes 클러스터라는 격리된 내부 네트워크 안에서 실행되기 때문입니다. 제 컴퓨터의 localhost는 그 클러스터 네트워크의 바깥에 있습니다.
아파트에 비유해 보겠습니다.
- Kubernetes 클러스터: 하나의 아파트 단지 🏠
 - nginx Pod들: 각 아파트 세대 (예: 101호, 102호, 103호)
 - 내 PC (localhost): 아파트 단지 밖 길가
 - Deployment: 아파트 세대(Pod) 수를 3개로 유지하는 관리 사무소 역할
 
지금은 아파트 단지 안에 3개의 세대가 잘 운영되고 있지만, 밖에서는 어느 세대로 들어가야 할지 알 수 있는 방법이 없는 상태입니다.
어떻게 외부에서 접속할 수 있나요?
클러스터 외부에서 Pod에 접속하려면, 외부 트래픽을 내부의 Pod로 연결해주는 **"관문"**이 필요합니다. 이 관문을 만드는 방법은 크게 두 가지입니다.
해결 방법 1: Service 생성 (권장 방식) 🚀
Service는 여러 Pod에 대한 안정적인 단일 진입점(고정 주소)을 만들어주는 Kubernetes의 핵심 기능입니다.
- service.yaml 파일 생성 아래 내용으로 nginx-service.yaml 파일을 만드세요. NodePort 타입은 외부에서 접근할 수 있도록 각 노드(Node)에 포트를 개방하는 방식입니다.
 - 
YAML
apiVersion: v1 kind: Service metadata: name: nginx-service spec: # type: NodePort는 외부에서 노드의 IP와 특정 포트를 통해 접속할 수 있게 합니다. type: NodePort selector: # 이 Service가 어떤 Pod들을 바라볼지 선택합니다. # 이전에 만든 Deployment의 Pod 라벨(app: nginx)과 일치해야 합니다. app: nginx ports: - protocol: TCP # Service가 내부적으로 사용할 포트 port: 80 # Pod가 노출하는 컨테이너 포트 targetPort: 80 - Service 적용 및 접속 아래 명령어로 서비스를 생성하고, Minikube를 사용 중이라면 자동으로 브라우저를 열어 접속할 수 있습니다.
 - 
Bash
# Service 생성 kubectl apply -f nginx-service.yaml # (Minikube 사용자) Service에 접속 (자동으로 브라우저 실행) minikube service nginx-service 
해결 방법 2: Port-Forwarding (빠른 테스트용) 🔌
개발이나 디버깅 목적으로 특정 Pod에 임시로 빠르게 접속하고 싶을 때 사용합니다. 내 PC의 포트와 Pod의 포트를 직접 터널처럼 연결합니다.
- Port-Forward 명령어 실행 아래 명령어는 내 PC의 8080 포트로 오는 모든 요청을 nginx-deployment에 속한 Pod 중 하나의 80 포트로 전달합니다.
 - 
Bash
# kubectl port-forward <리소스타입>/<이름> <로컬포트>:<Pod포트> kubectl port-forward deployment/nginx-deployment 8080:80 - 접속 이제 원하셨던 대로 웹 브라우저에서 http://localhost:8080 으로 접속하면 nginx 환영 페이지가 나타납니다. 이 연결은 터미널에서 Ctrl + C를 눌러 명령을 중지하면 끊어집니다.
 
요약
- Deployment: Pod를 생성하고 관리하지만, 외부에 노출하지는 않습니다.
 - Service: Pod 그룹에 대한 영구적인 외부 접속 포인트를 만들 때 사용합니다. (권장)
 - Port-Forward: 특정 Pod에 임시로 직접 접속하여 테스트할 때 사용합니다.
 
3.2 Service 구성 : Pod이 바뀌더라도 항상 접근 가능한 고정 네트워크 주소를 구성합니다. 
다음 조건을 만족하는 Service를 구성하세요. 
위 Deployment와 연결되는 Service 
여러 Pod 중 아무 Pod에게나 요청을 보낼 수 있도록 ClusterIP 타입의 Service 생성 
Service가 올바르게 Pod을 선택하도록 Selector 설정 
이를 적용
ClusterIP Service YAML 구성
아래 내용을 nginx-clusterip-service.yaml과 같은 파일 이름으로 저장
# apiVersion: Service는 v1 API 그룹에 속합니다.
apiVersion: v1
# kind: 생성할 리소스의 종류는 Service입니다.
kind: Service
# metadata: Service의 이름을 정의합니다.
metadata:
  name: nginx-clusterip-service
# spec: Service의 상세 설정을 정의합니다.
spec:
  # type: Service의 타입을 지정합니다. ClusterIP는 클러스터 내부용 고정 IP를 할당합니다.
  # 이 타입은 기본값이므로 생략해도 동일하게 동작합니다.
  type: ClusterIP
  # selector: 이 Service가 트래픽을 전달할 Pod를 선택하는 규칙입니다. (조건)
  # nginx-deployment에서 정의한 Pod의 라벨(app: nginx)과 정확히 일치해야 합니다.
  selector:
    app: nginx
  ports:
    # Service가 노출할 포트 정보를 정의합니다.
    - protocol: TCP
      # Service 자체의 포트 번호입니다.
      port: 80
      # Service가 트래픽을 전달할 대상 Pod의 포트 번호입니다.
      targetPort: 80
YAML 파일 적용하기
터미널에서 다음 kubectl 명령어를 실행하여 Service를 클러스터에 적용합니다.
kubectl apply -f nginx-clusterip-service.yaml

Service가 잘 생성되었고, Deployment의 Pod들을 올바르게 찾아냈는지 확인합니다.
- Service 정보 확인: kubectl get service nginx-clusterip-service 명령어로 Service의 CLUSTER-IP가 할당되었는지 확인합니다.
 

Selector 동작 확인: kubectl describe service nginx-clusterip-service 명령어로 Endpoints 부분에 nginx-deployment에 속한 Pod들의 내부 IP 주소 3개가 정상적으로 표시되는지 확인합니다.

이제 nginx-clusterip-service라는 고정된 이름과 CLUSTER-IP를 통해 클러스터 내의 다른 애플리케이션들은 nginx Pod가 바뀌거나 재시작되어도 안정적으로 nginx 웹 서버에 접근할 수 있습니다.
질문: 그래도 localhost가 안열려
네, 맞습니다. ClusterIP 타입의 서비스를 만드셨기 때문에 여전히 localhost에서는 접속할 수 없습니다.
ClusterIP 타입은 쿠버네티스 클러스터 내부에서만 사용하기 위한 가상 IP를 만드는 것입니다.
다시 아파트 비유를 들어보겠습니다.
- ClusterIP 서비스: 아파트 단지 내부 인터컴 시스템 📞
 
이 인터컴은 101호(웹 서버 Pod)에서 201호(DB 서버 Pod)로 전화를 거는 등, 단지 내부 세대 간의 통신을 위해 존재합니다. 아파트 밖 길가(내 PC의 localhost)에서는 이 인터컴 번호를 눌러도 연결되지 않습니다.
그럼 어떻게 localhost에서 접속하나요?
localhost에서 접속하는 경험을 원하시면, 이전에 설명해 드렸던 **port-forward**가 가장 직접적인 방법입니다.
해결 방법: port-forward 사용하기 (임시 연결) 🔌
이 명령어는 내 PC의 localhost와 클러스터 안의 서비스를 직접 터널로 연결해 줍니다.
- 터미널에서 아래 명령어를 실행하세요. nginx-clusterip-service를 대상으로 직접 연결할 수 있습니다.출력 예시:
 - 
Forwarding from 127.0.0.1:8080 -> 80 Forwarding from [::1]:8080 -> 80 - 
Bash
# kubectl port-forward <서비스 타입>/<서비스 이름> <로컬 포트>:<서비스 포트> kubectl port-forward service/nginx-clusterip-service 8080:80 - 웹 브라우저에서 접속 이제 웹 브라우저 주소창에 http://localhost:8080 을 입력하면 nginx 환영 페이지가 보일 것입니다.
 
요약
- Deployment: Pod 생성 (내부 직원 채용)
 - ClusterIP Service: 내부 통신망 구축 (사내 인터컴 설치)
 - port-forward: 내 자리에서 특정 직원에게 직통 전화 연결 (임시 테스트)
 
만약 localhost가 아닌 다른 외부 네트워크에서도 계속 접속해야 한다면, 서비스 타입을 ClusterIP가 아닌 **NodePort**나 **LoadBalancer**로 변경해야 합니다.
3.3 포트포워딩 및 접근 확인 : 외부에서 웹 서비스에 접근하여 응답이 정상인지 확인합니다. 
포트포워딩을 통해 로컬의 특정 포트를 내부 서비스 80 포트에 연결하세요. 
웹 브라우저를 통해 nginx 응답을 확인해 보세요.
1. 포트포워딩 명령어 실행
터미널을 열고 다음 명령어를 실행하여 로컬 PC의 8080번 포트와 이전에 생성한 nginx-clusterip-service의 80번 포트를 연결합니다.
# kubectl port-forward <서비스 타입>/<서비스 이름> <로컬 포트>:<서비스 포트>
kubectl port-forward service/nginx-clusterip-service 8080:80
명령어를 실행하면 터미널은 아래와 같은 메시지를 출력하며 연결 대기 상태가 됩니다. 이 터미널 창은 닫지 말고 그대로 두어야 연결이 유지됩니다.

2. 웹 브라우저로 접속 확인
이제 웹 브라우저를 열고 주소창에 아래 주소를 입력하세요.
http://localhost:8080

이 화면이 보이면 Deployment로 배포된 Nginx Pod에 Service와 port-forward를 통해 외부에서 정상적으로 접근한 것입니다.
포트포워딩을 중지하려면 명령어를 실행한 터미널로 돌아가 Ctrl + C를 누르면 됩니다.
3.4 Pod 중단 시도 : 서비스 복원성이 유지되는지 테스트합니다. (다른 터미널에서) 
kubectl get pods 로 현재 상황을 확인하세요. 
kubectl delete pod <pod-name> 명령어를 사용하여 임의의 pod 하나를 삭제하세요. 
kubectl get pods 로 결과를 확인하세요. 
웹 브라우저에서 새로고침하여 서비스가 끊겼는지 확인하세요. 
위 과정을 처음 만들었던 pod이 모두 사라질때까지 반복하세요.



모두 지운 후

예상 시나리오대로는 새로운 pod들이 실향되면서 8080 nginx가 중단되지 않아야 하는데, 나는 다음과 같이 에러 발생

질문:
문제는, 내가 pod 한개를 delete 하면, 새로운 pod이 생기지만 포트포워딩에서 에러가 발생을 해 E0707 00:30:00.535379 26342 portforward.go:424] "Unhandled Error" err=<
an error occurred forwarding 8080 -> 80: error forwarding port 80 to pod e5805d80406543402a2e0bdc39f0803c73310a71868e03c60f41bb247f6c27fa, uid : exit status 1: 2025/07/06 15:30:00 socat[16358] E connect(5, AF=2 127.0.0.1:80, 16): Connection refused
>
error: lost connection to pod
정확한 에러 로그를 짚어주셨네요. 이 문제는 쿠버네티스의 잘못이 아니며, kubectl port-forward라는 도구의 동작 방식 때문에 발생하는 매우 정상적인 현상입니다.
결론부터 말하면, port-forward는 Pod가 삭제되고 교체되는 상황에서의 서비스 연속성을 테스트하기 위한 적절한 도구가 아닙니다.
## 왜 이런 현상이 발생하나요?
에러 로그의 핵심은 Connection refused (연결 거부)입니다.
- Pod 삭제: 사용자가 kubectl delete pod 명령으로 기존 Pod를 삭제합니다.
 - 연결 시도: port-forward는 Service를 통해 트래픽을 전달하려고 합니다. 이때 삭제된 Pod는 더 이상 연결 대상이 아닙니다.
 - 새로운 Pod 생성: Deployment는 즉시 새로운 Pod를 생성하기 시작합니다. Service의 Endpoint 목록에도 이 새로운 Pod의 IP가 거의 즉시 추가됩니다.
 - 타이밍 문제 (Race Condition): port-forward가 트래픽을 이 새로운 Pod로 보내려고 시도합니다. 하지만 이 시점에는 Pod의 컨테이너는 생성되었을지 몰라도, 그 안의 Nginx 애플리케이션이 아직 시작되지 않아 80번 포트가 열리기 전입니다.
 - 연결 거부: 준비되지 않은 Pod의 80번 포트로 연결이 시도되니 "Connection refused" 에러가 발생하고, 이로 인해 kubectl port-forward 프로세스 자체가 연결이 끊겼다고 판단하여 종료되는 것입니다.
 
쉽게 비유하면, 식당에서 일하던 직원이 퇴근하고 새 직원이 출근하는 상황과 같습니다. 새 직원의 이름이 직원 명단에는 바로 올라갔지만, 아직 유니폼을 입고 자리에 앉기 전이라 전화를 받을 수 없는 것과 같습니다.
## 어떻게 해결하나요?
이것은 port-forward가 영구적인 연결이 아닌 임시 디버깅 도구이기 때문에 발생하는 문제입니다. 서비스 복원성을 제대로 테스트하려면 다음 방법 중 하나를 사용해야 합니다.
해결 방법 1: NodePort 타입 Service 사용하기 (권장)
실제 외부 접속 환경과 가장 유사하게 테스트하는 방법입니다.
- 기존 ClusterIP 서비스를 NodePort 타입으로 변경합니다. kubectl edit service nginx-clusterip-service 명령으로 type: ClusterIP를 type: NodePort로 수정하고 저장하세요.
 - 아래 명령어로 접속 URL을 확인하고 접속합니다.
minikube service nginx-clusterip-service - 이제 이 브라우저 창을 열어둔 채로 Pod를 삭제하고 새로고침을 해보세요. port-forward와 달리 연결이 끊기지 않고 서비스가 계속 유지되는 것을 확인할 수 있습니다. NodePort 방식은 Pod가 완전히 준비될 때까지 기다렸다가 트래픽을 보내기 때문입니다.
NodePort 로 type 변경후 위 명령어 실행시 

이후 pod 삭제해도 8080 포트의 nginx 정상작동을 브라우저를 통해 확인 가능
해결 방법 2: port-forward 명령어 다시 실행하기
현재의 테스트를 그대로 이어가고 싶다면, 가장 간단한 방법은 에러로 인해 종료된 port-forward 명령어를 다시 실행하는 것입니다. 그 몇 초 사이에 새로운 Pod는 Nginx를 실행할 준비를 마쳤을 것이므로, 재실행된 명령어는 정상적으로 연결됩니다.
핵심 요약: kubectl port-forward는 디버깅을 위한 임시 터널입니다. Kubernetes의 고가용성 및 서비스 복원성을 테스트하기 위해서는 NodePort나 LoadBalancer 타입의 서비스를 통해 접속해야 합니다.
'CMES' 카테고리의 다른 글
| CMES: 컨테이너 & 인프라스터디 3회 (0) | 2025.06.22 | 
|---|