본문 바로가기
IT/k8s

[K8s] 맨땅에 쿠버네티스 구축하기 Day 3: Nginx 배포와 '죽지 않는 서버' 만들기 (Self-Healing)

by 수누다 2026. 1. 28.

들어가며

안녕하세요, 13년 차 시스템 엔지니어 수누다입니다.

지난 [Day 1] 기초 공사와 [Day 2] 클러스터 구축을 통해, 우리는 3대의 서버를 하나의 거대한 '컴퓨터'로 만들었습니다. 이제 빈집은 다 지었으니, 세입자를 입주킬 차례입니다.

오늘은 쿠버네티스의 "Hello World"라 할 수 있는 Nginx 웹 서버를 띄우고, 외부에서 접속해 보며, 서버를 강제로 죽여도 좀비처럼 되살아나는 자가 치유(Self-Healing) 기능을 눈으로 확인해 보겠습니다.

1. Nginx 배포 (Deployment)

초보 때는 kubectl run 같은 한 줄 명령어를 쓰지만, 우리 엔지니어들은 YAML 파일로 명세서를 작성합니다. 이것이 바로 IaC(Infrastructure as Code)의 시작이니까요.

nginx-deploy.yaml 작성

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

💡 코드 분석: replicas: 2라는 설정이 핵심입니다. "Nginx 서버 2대를 무슨 일이 있어도 항상 유지해라"라고 쿠버네티스에게 명령하는 것입니다.

배포 실행

kubectl apply -f nginx-deploy.yaml

2. 외부 접속 허용 (Service - NodePort)

파드(Pod)가 생성되었지만, 아직은 클러스터 내부에서만 접근할 수 있습니다. 내 PC(외부)에서 브라우저로 접속하기 위해 NodePort를 열어주겠습니다.

nginx-service.yaml 작성

apiVersion: v1
kind: Service
metadata:
  name: my-nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30000  # 30000번 포트로 접속하겠다! (30000~32767 가능)

서비스 생성

kubectl apply -f nginx-service.yaml

3. 접속 테스트

이제 브라우저를 열고 테스트해 봅니다. 여기서 쿠버네티스 서비스(Service)의 마법을 볼 수 있습니다.

  • http://192.168.20.141:30000 (Master IP)
  • http://192.168.20.142:30000 (Worker1 IP)
  • http://192.168.20.143:30000 (Worker2 IP)

⚠️ 주의: 위 IP(192.168.20.xxx)는 제 환경의 예시입니다. 여러분은 [Day 1]에서 설정한 본인의 서버 IP를 입력하셔야 합니다.

결과 확인:
어떤 노드의 IP로 접속하더라도 똑같은 "Welcome to nginx!" 화면이 떠야 합니다. 파드가 어느 워커 노드에 있든 상관없이, 쿠버네티스가 알아서 트래픽을 연결(Load Balancing) 해주기 때문입니다.

4. 엔지니어의 로망: "죽여보기" (Self-Healing)

자, 이제 우리가 왜 비싼 돈 주고 VM 대신 쿠버네티스를 쓰는지 증명할 시간입니다. 멀쩡히 돌아가는 서버를 강제로 지워보겠습니다.

1. 현재 파드 이름 확인

kubectl get pods
# 예: my-nginx-6b7f... (이름 복사)

2. 파드 하나 강제 삭제 (Kill)

kubectl delete pod <파드이름>

3. 즉시 상태 확인

kubectl get pods

[결과 화면 예시]

NAME                        READY   STATUS        RESTARTS   AGE
my-nginx-6b7f...(방금 지운애)   0/1     Terminating   0          5m
my-nginx-xxxx...(새로 뜬 애)    1/1     Running       0          3s

보셨나요? 방금 지운 파드는 죽어가고 있지만(Terminating), 동시에 새로운 파드가 이미 생성되어 실행(Running) 중입니다.
우리가 처음에 replicas: 2라고 주문했기 때문에, 쿠버네티스는 갯수가 1개로 줄어드는 것을 용납하지 않고 즉시 복구한 것입니다. 이것이 새벽 3시에 서버가 죽어도 엔지니어가 꿀잠을 잘 수 있는 이유입니다.

⚠️ 엔지니어의 '삽질 방지' Tip

Q. 브라우저에서 접속이 안 돼요! (무한 로딩)

  1. 방화벽(Firewall): 리눅스 자체 방화벽(ufw)이 30000번 포트를 막고 있을 확률이 99%입니다. 테스트 환경이라면 sudo ufw disable로 잠시 끄거나, 30000번을 허용해 주세요.
  2. IP 확인: 실수로 내부 IP(10.244...)나 파드 IP를 입력하지 않았는지 확인하세요. 반드시 노드의 물리 IP여야 합니다.

요약 (Summary)

  1. Deployment: YAML 파일을 통해 Nginx 2대(Replicas)를 선언적으로 배포했습니다.
  2. Service: NodePort(30000)를 통해 외부에서 접속할 길을 뚫었습니다.
  3. Self-Healing: 파드를 강제로 삭제해도, 설정한 수만큼 자동으로 복구되는 것을 확인했습니다.

이제 기초는 끝났습니다. 다음 시간에는 다양한 인프라 구축에 대해서공부하는 시간을 가져보겠습니다. 고생하셨습니다!