날씨 정보를 불러오는 중...

리눅스 3대로 쿠버네티스 클러스터 구성기 (마스터/워커, 장애 복구, 오토스케일링)

2026-09-07 06:42 · IT기술 · 조회 41
쿠버네티스 3노드 클러스터 구축기

리눅스 3대로 쿠버네티스 클러스터 직접 구성기 (마스터/워커, 장애 복구, 오토스케일링까지)

요즘 회사든 사이드 프로젝트든 "쿠버네티스(Kubernetes, k8s) 정도는 다뤄봐야지"라는 말을 자주 듣습니다. 그런데 막상 문서만 보면 개념은 알 것 같은데 실제로 노드가 죽었을 때 정말 무중단으로 버텨주는지, 트래픽이 몰리면 파드가 알아서 늘어나는 게 맞는지는 직접 해보기 전엔 감이 잘 안 옵니다.

그래서 이번 글에서는 리눅스 서버 3대로 쿠버네티스 클러스터를 구성하고, 일부러 노드를 하나 꺼뜨리거나 파드를 강제로 죽여보면서 정말 서비스가 끊기지 않는지, 그리고 HPA(Horizontal Pod Autoscaler)로 파드 개수가 트래픽에 맞춰 자동으로 늘었다 줄었다 하는지까지 직접 확인해본 과정을 정리했습니다. 마지막에는 실무에서 정말 자주 쓰는 kubectl 명령어도 모아뒀으니 필요할 때 검색해서 바로 찾아 쓰시면 됩니다.

쿠버네티스란

쿠버네티스가 정확히 뭘 해주는 놈인가

쿠버네티스는 한마디로 컨테이너(도커) 여러 개를 여러 서버에 나눠서 실행하고, 그 상태를 계속 감시하면서 "원래 있어야 할 상태"를 유지시켜주는 오케스트레이션 도구입니다. 서버 한 대에서 docker run으로 컨테이너 몇 개 돌리는 거랑은 차원이 다른 이야기인데, 핵심 차이는 딱 세 가지입니다.

  1. 자가 치유(Self-healing) — 컨테이너(파드)가 죽으면 쿠버네티스가 알아서 같은 걸 다시 띄웁니다. 사람이 새벽에 알람 받고 서버 접속해서 재시작할 필요가 없어요.
  2. 스케줄링 — "이 앱은 3개 떠 있어야 해"라고 선언만 하면, 클러스터 안 여러 서버(노드) 중에 자원이 남는 곳을 찾아 알아서 배치합니다.
  3. 오토스케일링 — CPU/메모리 사용률이 올라가면 파드 개수를 자동으로 늘리고, 트래픽이 빠지면 다시 줄여서 자원을 아낍니다.

이 세 가지가 실제로 눈으로 보일 때까지 확인해보는 게 이번 글의 목표입니다.

클러스터 아키텍처

왜 하필 3대인가 - 마스터 노드와 워커 노드

쿠버네티스 클러스터는 역할이 다른 노드들의 집합입니다. 크게 두 종류로 나뉩니다.

  1. 컨트롤 플레인(마스터 노드) — API 서버, 스케줄러, 컨트롤러 매니저, etcd(클러스터 상태 저장소) 같은 "두뇌" 역할을 하는 컴포넌트가 여기서 돕니다. 실제 애플리케이션 파드는 원칙적으로 여기 배치되지 않도록 테인트(taint)가 걸려 있습니다.
  2. 워커 노드 — 실제 우리 애플리케이션 파드가 올라가서 돌아가는 곳입니다. kubelet과 kube-proxy, 컨테이너 런타임(containerd)이 여기서 동작하면서 마스터의 지시를 받아 컨테이너를 실행합니다.

이번 실습은 마스터 1대 + 워커 2대, 총 3대 구성으로 진행했습니다. 마스터가 1대뿐이라 마스터 자체의 고가용성(HA)까지 테스트하지는 못하지만, "워커 노드가 죽어도 서비스가 유지되는가"와 "파드가 죽어도 자동으로 복구되는가"를 확인하는 데는 충분한 구성입니다. 참고로 각 노드 사양은 이렇게 잡았습니다.

  1. node-1 (master) — 역할: control-plane, vCPU 2, RAM 4GB
  2. node-2 (worker) — 역할: worker, vCPU 2, RAM 4GB
  3. node-3 (worker) — 역할: worker, vCPU 2, RAM 4GB

OS는 세 대 모두 Ubuntu 22.04 LTS를 사용했고, 쿠버네티스 배포판은 원본 kubeadm 기준으로 정리했습니다(k3s처럼 경량화된 배포판을 쓰면 설치 과정은 훨씬 짧아지지만, 개념을 제대로 이해하려면 kubeadm으로 한 번쯤 손으로 구성해보는 걸 추천합니다).

클러스터 구성

클러스터 구성 과정

1) 사전 준비 (3대 모두 동일하게)

세 노드 모두에 공통으로 해줘야 하는 작업입니다. 스왑을 끄고, 커널 모듈과 sysctl 설정을 넣고, containerd를 설치합니다.

# 스왑 비활성화 (쿠버네티스는 스왑이 켜져 있으면 kubelet이 뜨지 않습니다)
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab

# 컨테이너 네트워킹에 필요한 커널 모듈
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter

# 네트워크 관련 sysctl 값
cat <<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

# containerd 설치
sudo apt-get update && sudo apt-get install -y containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd

2) kubeadm, kubelet, kubectl 설치 (3대 모두)

sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key \
  | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] \
  https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' \
  | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

3) 마스터 노드에서 클러스터 초기화

node-1(마스터)에서만 실행합니다. --pod-network-cidr는 이후 설치할 CNI(Calico)가 기본으로 쓰는 대역에 맞춰줍니다.

sudo kubeadm init --pod-network-cidr=192.168.0.0/16 --apiserver-advertise-address=192.168.0.11

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

초기화가 끝나면 마지막에 kubeadm join ...으로 시작하는 명령어가 출력됩니다. 이걸 복사해뒀다가 워커 노드에서 그대로 실행하면 됩니다. 토큰이 만료됐다면 마스터에서 kubeadm token create --print-join-command로 새로 뽑을 수 있습니다.

4) CNI(Calico) 설치

노드끼리, 그리고 파드끼리 통신하려면 CNI 플러그인이 필요합니다. 이번엔 Calico를 사용했습니다.

kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/calico.yaml

5) 워커 노드 조인

node-2, node-3에서 각각 실행합니다.

sudo kubeadm join 192.168.0.11:6443 --token <토큰값> \
  --discovery-token-ca-cert-hash sha256:<해시값>

세 대가 다 붙었는지는 마스터에서 확인합니다.

$ kubectl get nodes -o wide
NAME     STATUS   ROLES           AGE   VERSION   INTERNAL-IP
node-1   Ready    control-plane   10m   v1.30.2   192.168.0.11
node-2   Ready    worker          6m    v1.30.2   192.168.0.12
node-3   Ready    worker          5m    v1.30.2   192.168.0.13

STATUS가 전부 Ready로 뜨면 클러스터 구성은 끝난 겁니다. 생각보다 별거 없죠? 진짜 재미있는 부분은 지금부터입니다.

테스트 파드 배포

테스트용 애플리케이션 배포하고 분산 배치 확인하기

간단한 nginx 디플로이먼트를 레플리카 3개로 띄워서, 정말 워커 노드들에 골고루 분산되는지 확인해봤습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: demo-web
  template:
    metadata:
      labels:
        app: demo-web
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 100m
            memory: 64Mi
          limits:
            cpu: 200m
            memory: 128Mi
---
apiVersion: v1
kind: Service
metadata:
  name: demo-web-svc
spec:
  selector:
    app: demo-web
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP
$ kubectl apply -f demo-web.yaml
deployment.apps/demo-web created
service/demo-web-svc created

$ kubectl get pods -o wide
NAME                        READY   STATUS    NODE
demo-web-6f9d8c7b5d-2kxqz   1/1     Running   node-2
demo-web-6f9d8c7b5d-9j4pl   1/1     Running   node-3
demo-web-6f9d8c7b5d-h7wtn   1/1     Running   node-2

스케줄러가 워커 노드(node-2, node-3)에만 파드를 배치하고, 컨트롤 플레인 노드(node-1)는 건드리지 않는 걸 확인할 수 있습니다. 이게 아까 말씀드린 테인트 덕분입니다.

노드 장애 테스트

장애 테스트 1 - 워커 노드를 통째로 꺼봤습니다

실무에서 가장 궁금한 건 결국 "서버 한 대가 죽으면 서비스는 어떻게 되나"입니다. 직접 node-2의 전원을 내려서 재현해봤습니다.

테스트 방법은 간단합니다. 로컬에서 서비스에 계속 요청을 보내는 반복문을 돌려놓고, 그 상태에서 node-2를 강제 종료합니다.

# 별도 터미널에서 0.5초마다 응답 확인
$ while true; do curl -s -o /dev/null -w "%{http_code} " http://192.168.0.11:30080/; sleep 0.5; done
200 200 200 200 200 200 200 200 ...

# node-2 전원 강제 종료 (실제로는 콘솔에서 shutdown -h now)

node-2가 죽고 나서 쿠버네티스가 바로 반응하는 건 아닙니다. kubelet이 마스터에 상태를 보고하지 못하면, 마스터는 일정 시간(기본 node-monitor-grace-period 40초) 동안 기다렸다가 노드를 NotReady로 표시합니다.

$ kubectl get nodes
NAME     STATUS     ROLES           AGE
node-1   Ready      control-plane   40m
node-2   NotReady   worker          36m
node-3   Ready      worker          35m

그리고 다시 5분(기본 pod-eviction-timeout) 정도가 더 지나면, 컨트롤러 매니저가 죽은 노드에 있던 파드를 "더 이상 신뢰할 수 없다"고 판단하고 다른 노드에 새 파드를 만들어 대체합니다.

$ kubectl get pods -o wide
NAME                        READY   STATUS        NODE
demo-web-6f9d8c7b5d-2kxqz   1/1     Terminating   node-2
demo-web-6f9d8c7b5d-9j4pl   1/1     Running       node-3
demo-web-6f9d8c7b5d-h7wtn   1/1     Running       node-2
demo-web-6f9d8c7b5d-qm2rx   1/1     Running       node-3   <- 새로 뜬 파드

# 몇 분 후
$ kubectl get pods -o wide
NAME                        READY   STATUS    NODE
demo-web-6f9d8c7b5d-9j4pl   1/1     Running   node-3
demo-web-6f9d8c7b5d-qm2rx   1/1     Running   node-3
demo-web-6f9d8c7b5d-rz8kd   1/1     Running   node-3

레플리카 3개를 유지하라는 선언(replicas: 3)이 있었기 때문에, 살아있는 node-3 한 대에 파드 3개가 전부 몰려서라도 개수를 맞춰준 겁니다. curl 반복문 결과를 보면 서비스(ClusterIP + 트래픽을 받는 로드밸런서/인그레스) 뒤에 파드가 최소 하나라도 떠 있는 동안에는 200 응답이 끊기지 않았습니다. 다만 완전히 끊기지 않으려면 아래 두 가지가 전제되어야 합니다.

  1. 레플리카 수가 최소 2개 이상이어야 합니다. 1개짜리 파드가 죽으면 재스케줄링되는 몇 초~몇 분 사이는 무조건 다운타임이 생깁니다.
  2. 노드마다 파드가 분산되어 있어야 합니다. 파드 3개가 전부 node-2에만 몰려 있었다면 node-2가 죽는 순간 서비스는 완전히 끊겼다가 재스케줄링될 때까지 복구되지 않습니다. 이런 상황을 막으려면 podAntiAffinity로 "같은 노드에는 같은 앱의 파드를 하나만 배치"하도록 강제하는 걸 추천합니다.

참고로 훨씬 안전하고 빠르게 노드를 내리는 방법은 전원을 그냥 뽑는 게 아니라 kubectl drain으로 먼저 파드를 안전하게 다른 노드로 옮겨두는 겁니다. 유지보수 목적이라면 이 방법이 정석입니다.

$ kubectl drain node-2 --ignore-daemonsets --delete-emptydir-data
node/node-2 cordoned
evicting pod default/demo-web-6f9d8c7b5d-2kxqz
node/node-2 drained

# 유지보수 끝나고 다시 스케줄링 대상에 포함시키기
$ kubectl uncordon node-2
node/node-2 uncordoned
파드 장애 테스트

장애 테스트 2 - 파드를 강제로 죽여봤습니다

노드가 아니라 파드 하나만 죽는 상황(애플리케이션 크래시, OOM 등)도 재현해봤습니다. 이번엔 훨씬 간단하고 훨씬 빠릅니다.

$ kubectl get pods -o wide
NAME                        READY   STATUS    NODE
demo-web-6f9d8c7b5d-9j4pl   1/1     Running   node-3
demo-web-6f9d8c7b5d-qm2rx   1/1     Running   node-3
demo-web-6f9d8c7b5d-rz8kd   1/1     Running   node-2

$ kubectl delete pod demo-web-6f9d8c7b5d-rz8kd
pod "demo-web-6f9d8c7b5d-rz8kd" deleted

$ kubectl get pods -o wide -w
NAME                        READY   STATUS              NODE
demo-web-6f9d8c7b5d-9j4pl   1/1     Running             node-3
demo-web-6f9d8c7b5d-qm2rx   1/1     Running             node-3
demo-web-6f9d8c7b5d-x4n8w   0/1     ContainerCreating   node-2
demo-web-6f9d8c7b5d-x4n8w   1/1     Running             node-2

파드가 사라지자마자 1~2초 안에 새 파드 이름(x4n8w)으로 곧바로 대체된 걸 볼 수 있습니다. 이건 디플로이먼트가 관리하는 레플리카셋(ReplicaSet)이 "현재 상태(2개)"와 "원하는 상태(3개)"의 차이를 계속 감시하다가, 차이가 생기자마자 즉시 새 파드를 만들어 채워 넣기 때문입니다. 노드 장애와 다르게 노드 자체는 멀쩡하니 40초씩 기다릴 필요도 없이 거의 즉각 복구됩니다.

여기서 얻을 수 있는 실무 교훈은 명확합니다. 파드 단위 장애는 쿠버네티스가 알아서 처리해주지만, 노드 단위 장애는 복구까지 시간이 걸리고 레플리카 분산 설계에 따라 순간적인 다운타임이 생길 수도 있다는 점입니다.

오토스케일링

Pod 개수 자동 조절 - HPA 오토스케일링 테스트

이제 가장 신기했던 부분입니다. 트래픽이 몰릴 때 파드 개수가 자동으로 늘어나는지 확인해봤습니다. 먼저 CPU 사용률을 확인하려면 metrics-server가 설치돼 있어야 합니다.

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

$ kubectl top nodes
NAME     CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
node-1   180m         9%     1120Mi          28%
node-2   95m          4%     780Mi           19%
node-3   102m         5%     810Mi           20%

그 다음 아까 만든 demo-web 디플로이먼트에 HPA를 붙였습니다. "평균 CPU 사용률이 50%를 넘으면 파드를 늘리되, 최소 2개, 최대 8개까지만 늘려라"는 규칙입니다.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: demo-web-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: demo-web
  minReplicas: 2
  maxReplicas: 8
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
$ kubectl apply -f demo-web-hpa.yaml
horizontalpodautoscaler.autoscaling/demo-web-hpa created

$ kubectl get hpa
NAME           REFERENCE             TARGETS   MINPODS   MAXPODS   REPLICAS
demo-web-hpa   Deployment/demo-web   3%/50%    2         8         3

이 상태에서 부하 테스트용 파드를 하나 띄워서 계속 요청을 퍼부었습니다.

kubectl run load-generator --image=busybox --restart=Never -- \
  /bin/sh -c "while true; do wget -q -O- http://demo-web-svc; done"

1분 정도 지나자 CPU 사용률이 임계치를 넘으면서 HPA가 파드를 하나씩 늘리기 시작했습니다.

$ kubectl get hpa -w
NAME           REFERENCE             TARGETS    MINPODS   MAXPODS   REPLICAS
demo-web-hpa   Deployment/demo-web   118%/50%   2         8         3
demo-web-hpa   Deployment/demo-web   118%/50%   2         8         6
demo-web-hpa   Deployment/demo-web   72%/50%    2         8         7
demo-web-hpa   Deployment/demo-web   51%/50%    2         8         7

$ kubectl get pods -o wide
NAME                        READY   STATUS    NODE
demo-web-6f9d8c7b5d-9j4pl   1/1     Running   node-3
demo-web-6f9d8c7b5d-qm2rx   1/1     Running   node-3
demo-web-6f9d8c7b5d-x4n8w   1/1     Running   node-2
demo-web-6f9d8c7b5d-b7f2m   1/1     Running   node-2
demo-web-6f9d8c7b5d-tn5jx   1/1     Running   node-3
demo-web-6f9d8c7b5d-k9wpq   1/1     Running   node-2
demo-web-6f9d8c7b5d-w2vdc   1/1     Running   node-3

부하 테스트 파드를 지우고 나니, 몇 분 뒤(기본 안정화 시간 5분) CPU 사용률이 떨어지면서 파드 개수도 서서히 minReplicas인 2개까지 줄어들었습니다.

$ kubectl delete pod load-generator
pod "load-generator" deleted

$ kubectl get hpa -w
NAME           REFERENCE             TARGETS   MINPODS   MAXPODS   REPLICAS
demo-web-hpa   Deployment/demo-web   4%/50%    2         8         7
demo-web-hpa   Deployment/demo-web   4%/50%    2         8         2

스케일 업은 거의 즉각적인데, 스케일 다운은 일부러 천천히(기본 안정화 창 300초) 진행되도록 설계돼 있습니다. 트래픽이 잠깐 튀었다가 바로 빠지는 상황에서 파드를 늘렸다 줄였다 반복하는 "플래핑(flapping)"을 막기 위한 정책입니다. 이 값은 behavior.scaleDown.stabilizationWindowSeconds로 조절할 수 있습니다.

자주 쓰는 명령어

실무에서 진짜 많이 쓰는 kubectl 명령어 모음

매번 검색하기 귀찮아서 자주 쓰는 것들만 정리해뒀습니다. 북마크해두고 필요할 때 꺼내 쓰세요.

기본 조회

  1. kubectl get nodes — 클러스터에 속한 노드 목록과 상태 확인
  2. kubectl get pods -A — 모든 네임스페이스의 파드 확인 (-A = --all-namespaces)
  3. kubectl get pods -o wide — 파드가 어느 노드에 떠 있는지, IP까지 함께 확인
  4. kubectl get deploy,svc,ingress — 디플로이먼트/서비스/인그레스를 한 번에 조회
  5. kubectl describe pod <파드명> — 파드 상세 정보 + 최근 이벤트(왜 안 뜨는지 디버깅할 때 가장 먼저 확인)

로그 및 디버깅

  1. kubectl logs -f <파드명> — 실시간 로그 스트리밍
  2. kubectl logs <파드명> --previous — 재시작 전(크래시 직전) 로그 확인
  3. kubectl exec -it <파드명> -- /bin/sh — 파드 컨테이너 내부로 직접 진입
  4. kubectl get events --sort-by=.metadata.creationTimestamp — 클러스터 전체 최근 이벤트를 시간순으로 확인
  5. kubectl top pods / kubectl top nodes — 실시간 CPU/메모리 사용량 (metrics-server 필요)

배포 및 변경

  1. kubectl apply -f <파일.yaml> — 매니페스트 적용 (있으면 업데이트, 없으면 생성)
  2. kubectl rollout status deployment/<이름> — 배포 진행 상황 실시간 확인
  3. kubectl rollout undo deployment/<이름> — 방금 배포한 게 문제 있을 때 바로 직전 버전으로 롤백
  4. kubectl scale deployment/<이름> --replicas=5 — 파드 개수 수동 조절
  5. kubectl set image deployment/<이름> <컨테이너명>=<이미지:태그> — 이미지 버전만 빠르게 교체

노드/클러스터 관리

  1. kubectl cordon <노드명> — 해당 노드에 새 파드가 스케줄링되지 않도록 막기
  2. kubectl drain <노드명> --ignore-daemonsets — 노드 위 파드를 안전하게 다른 곳으로 옮기고 비우기 (점검 전 필수)
  3. kubectl uncordon <노드명> — cordon/drain 해제, 다시 스케줄링 대상 포함
  4. kubectl taint nodes <노드명> key=value:NoSchedule — 특정 노드에 일반 파드가 못 붙게 제한

그 외 알아두면 유용한 것들

  1. kubectl get pods -w — 상태 변화를 실시간으로 계속 지켜보기 (watch)
  2. kubectl delete pod <파드명> — 파드 강제 재시작 대용으로 자주 사용 (디플로이먼트가 알아서 새로 만들어줌)
  3. kubectl get hpa — 오토스케일러 현재 목표 대비 실제 사용률, 레플리카 수 확인
  4. kubectl config use-context <컨텍스트명> — 여러 클러스터를 다룰 때 대상 클러스터 전환
  5. kubectl explain <리소스>.<필드> — 매니페스트 필드 스펙이 헷갈릴 때 공식 문서 대신 바로 터미널에서 확인
마무리

마무리

직접 노드를 꺼뜨려보고 파드를 죽여보기 전까지는 "쿠버네티스가 알아서 다 해준다"는 말이 사실 좀 막연했는데, 실제로 눈으로 보니 확실히 체감이 다릅니다. 정리하면 이렇습니다.

  1. 파드 하나가 죽는 건 레플리카셋이 몇 초 안에 즉시 복구합니다.
  2. 노드 하나가 죽는 건 감지(약 40초)와 축출(약 5분) 시간이 필요하고, 그 사이 무중단이려면 레플리카 분산과 최소 2개 이상의 복제본이 전제되어야 합니다.
  3. HPA는 스케일 업은 빠르게, 스케일 다운은 일부러 천천히 해서 트래픽 급변에도 안정적으로 대응합니다.

여기서 사용한 명령어와 매니페스트, 파라미터 기본값(grace period, eviction timeout, stabilization window 등)은 클러스터 버전이나 배포판(kubeadm/k3s/EKS/GKE 등)에 따라 조금씩 다를 수 있으니, 실제 운영 환경에 적용하기 전에는 반드시 각 환경의 공식 문서에서 최신 값을 다시 확인하시는 걸 추천드립니다. 다음 글에서는 마스터 노드 자체를 다중화(HA)해서 컨트롤 플레인까지 완전 무중단으로 만드는 과정을 다뤄보겠습니다.


댓글 0

로그인 후 댓글을 작성할 수 있습니다.