k8s 직접 해보기 (3) - CLI로 서버 이미지 배포하기

Endermaru·2025년 6월 24일

k8s 직접 해보기

목록 보기
4/11

배포

  • 토이프로젝트로 사용했던 endermaru/22-5-team1-server 이미지를 deployment로 사용
# latest 태그가 붙은 이미지를 기본으로 사용
$ kubectl create deployment spring --image=endermaru/22-5-team1-server
$ kubectl expose deployment spring --type=LoadBalancer --port=8080
$ minikube service spring

# 접속 후 정상 작동!(외부 포트는 랜덤)
http://127.0.0.1:2150/swagger-ui


$ kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
spring-6b68c5cbb6-sqv29   1/1     Running   0          2m34s

# Spring 앱 시작 시 프로필 등 환경변수 설정 안 됨(local, prod 등)
$ kubectl logs spring-6b68c5cbb6-sqv29 
...
2025-04-22T15:21:08.278+09:00  INFO 1 --- [team1server] [           main] c.waffletoy.team1server.ApplicationKt    : No active profile set, falling back to 1 default profile: "default"
...

문제점

  • docker compose, env 등을 활용한 환경변수 사용 불가능(spring.profiles.active...)
    → deployment를 생성한 뒤 새로운 pod에 환경변수를 지정하여 생성 가능
    → 그럼에도 환경변수값을 일일이 넣어준 pod을 별도 생성 필요

  • docker compose에 선언한 redis 컨테이너도 별도로 생성, 연결 필요

# deployment 없이 spring이라는 이름, app=spring2 라벨을 가진 pod을 생성
# spring.profiles.active 속성을 환경변수로 지정(underscore)
$ kubectl run spring \
  --image=endermaru/22-5-team1-server \
  --env=SPRING_PROFILES_ACTIVE=local \
  --port=8080 \
  --labels="app=spring2" # 라벨 지정으로 기존 pod과 구분 가능하게
 
# pod 이름과 라벨 확인
$ kubectl get pods --show-labels
NAME                      READY   STATUS    RESTARTS   AGE   LABELS
spring                    1/1     Running   0          72s   app=spring2
spring-6b68c5cbb6-sqv29   1/1     Running   0          20m   app=spring,pod-template-hash=6b68c5cbb6


# 서비스 생성(미리 생성된 spring 서비스와 이름 구분, 필요시 --selector로 특정 pod 지정 가능)
$ kubectl expose pod spring --type=LoadBalancer --port=8080 --name=spring2
$ kubectl get svc
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP      10.96.0.1      <none>        443/TCP          4d19h
spring       LoadBalancer   10.111.25.65   <pending>     8080:30687/TCP   23m
spring2      LoadBalancer   10.98.10.200   <pending>     8080:31232/TCP   11s

# 접속해서 작동하는지 확인
$ minikube service spring2

# 해당 pod의 로그 확인
$ kubectl logs spring
...
2025-06-24T15:34:57.630+09:00  INFO 1 --- [internhasha] [           main] c.w.internhasha.ApplicationKt            : The following 1 profile is active: "local"
....

# 서비스에 연결된 pod 엔드포인트 확인
$ kubectl get endpoints spring
NAME     ENDPOINTS          AGE
spring   10.244.0.15:8080   28m  # 기존 서비스

$ kubectl get endpoints spring2
NAME      ENDPOINTS          AGE
spring2   10.244.0.17:8080   5m42s # 새로 만든 서비스

# pod의 IP(엔드포인트) 확인
$ kubectl get pods -o wide
NAME                      READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
spring                    1/1     Running   0          11m   10.244.0.17   minikube   <none>           <none>
spring-6b68c5cbb6-sqv29   1/1     Running   0          31m   10.244.0.15   minikube   <none>           <none>

Cluster IP vs. Endpoint by GPT

엔드포인트:

  • 서비스가 실제로 트래픽을 보낼 Pod들의 네트워크 주소(IP) 목록
  • Pod가 재시작되면 변경될 수 있음
  • 서비스의 selector를 기반으로 자동으로 엔드포인트를 생성/업데이트
    • 서비스의 selector와 일치하는 라벨을 가진 Pod들을 찾음
    • 해당 Pod들의 IP와 포트를 엔드포인트에 등록
    • Pod가 추가/삭제되면 엔드포인트도 자동으로 업데이트

Cluster IP:

  • 서비스의 가상 IP 주소
  • kube-proxy에 의해 관리되는 Virtual IP
  • 다른 Pod이 ClusterIP로 요청을 보내면, kube-proxy가 해당 요청을 Endpoint에 등록된 실제 Pod IP로 직접 전달

CLI 방식 정리

  • 한 줄 명령어로 즉시 리소스 생성/삭제 가능
  • 반대로 매번 명령어를 입력해서 리소스를 생성, 삭제, 접근해야함
  • 복잡한 설정(replicas, 리소스 제한, 환경변수 등) 구성 어려움
  • RBAC 정책에 의해 kubectl 명령어를 사용이 제한되는 환경에서는 사용 불가능
  • 버전 관리 불가, 설정 변경 이력 추적 어려움

⇒ 배포 환경이나 복잡한 환경에서는 더 관리하기 용이한 선언적 방식을 채택할 필요성이 있음

0개의 댓글