본문 바로가기
Server/🚢 Kubernetes

[minikube] 쿠버네티스 서비스(Service) 구조와 실행

by 코딩하는 동현 2025. 4. 8.

 

Kubernetes에서 Service란? – Pod를 외부로 노출하는 방법

앞선 강의에서는 Kubernetes 클러스터 안에 첫 번째 Pod를 만들어보고, 그 안에 웹 애플리케이션 컨테이너를 배포했습니다. 하지만 그 상태에서는 웹 브라우저로 아무리 접근해도 연결되지 않았습니다. 왜 그럴까요?

그 이유는 Pod는 기본적으로 외부에서 접근할 수 없도록 설계되어 있기 때문입니다. 이 제한을 해결하기 위해 Kubernetes는 Service라는 리소스를 제공합니다.

왜 Service가 필요한가?

Kubernetes에서 Pod는 수명이 짧고 가볍게 쓰고 버리는 존재입니다. 특정 Pod가 중단되면, Kubernetes는 새롭게 동일한 Pod를 생성합니다. 이 과정에서 IP 주소도 바뀌게 됩니다. 이렇게 계속 바뀌는 Pod의 위치에 웹 브라우저나 외부 클라이언트가 안정적으로 접근하려면 어떻게 해야 할까요?

그 해답이 바로 Service입니다.

Service란?

Service는 Kubernetes 클러스터 내부 혹은 외부에서 Pod에 안정적으로 접근할 수 있게 해주는 네트워크 추상화 객체입니다.

Service는 고정된 IP와 포트를 갖고, 그 뒤에서 실행 중인 Pod들과 연결되어 요청을 전달합니다. 이 과정에서 Pod에 부여된 Label(라벨)을 기반으로 특정 Pod들을 선택합니다. 예를 들어, 웹앱 Pod에 app: webapp이라는 라벨이 달려 있다면, 이 라벨을 기준으로 해당 Pod를 선택하여 연결할 수 있습니다.

 

서비스와 셀렉터(Selector)의 관계

서비스는 Kubernetes 클러스터 내부 또는 외부에서 특정 Pod로 트래픽을 전달하는 네트워크 객체입니다. 서비스는 어떤 Pod로 트래픽을 전달할지를 Selector를 통해 결정합니다.

selector:
  app: webapp

위와 같이 서비스 정의에 app: webapp 셀렉터가 있다면, 클러스터 내부에서 이 라벨을 가진 Pod를 찾아 연결하게 됩니다. 따라서 Pod에도 동일한 라벨이 있어야 합니다.

 

Pod에 라벨 추가하기

이전 강의에서 우리가 만든 Pod에는 라벨이 없었습니다. 다음과 같이 수정해 줘야 합니다:

metadata:
  name: webapp
  labels:
    app: webapp

또는 아래처럼 키 이름은 임의로 지정할 수도 있습니다:

labels:
  mylabelname: webapp

이때, 서비스 파일의 셀렉터도 같이 수정해줘야 합니다:

selector:
  mylabelname: webapp

다시 한번 강조하지만, 라벨 키 이름은 임의로 지정 가능하지만, 일관성과 협업을 위해 일반적으로 app: 같은 키를 자주 사용합니다.

 

여러 Pod 버전을 라벨로 관리하기

우리는 지금부터 두 가지 버전의 Pod를 동시에 배포할 예정입니다. release라는 라벨을 사용해서 다음과 같이 나눕니다:

첫 번째 Pod (v0):

metadata:
  name: webapp
  labels:
    app: webapp
    release: "0"
spec:
  containers:
    - name: webapp
      image: richardchesterwood/k8s-fleetman-webapp-angular:release0-arm64

 

두 번째 Pod (v0-5):

metadata:
  name: webapp-release-0-5
  labels:
    app: webapp
    release: "0-5"
spec:
  containers:
    - name: webapp
      image: richardchesterwood/k8s-fleetman-webapp-angular:release0-5-arm64

YAML에서 숫자 "0"을 따옴표로 감싸지 않으면 int64 오류가 발생할 수 있으니 주의하세요!

 

서비스 정의: 라벨과 매칭

이제 서비스 정의에서 어떤 라벨을 가진 Pod와 연결할지를 명확하게 지정해줘야 합니다:

apiVersion: v1
kind: Service
metadata:
  name: fleetman-webapp
spec:
  selector:
    app: webapp
    release: "0-5"
  ports:
    - name: http
      port: 80
      nodePort: 30080
  type: NodePort

이 서비스는 app=webapp, release=0-5인 Pod에만 연결됩니다.

서비스 라우팅 동작 확인

서비스 정의 적용:

kubectl apply -f webapp-service.yaml

 

Pod 정의 적용:

kubectl apply -f first-pod.yaml

 

확인:

kubectl get all

 

 

서비스가 제대로 연결되지 않는다면 다음 명령어로 서비스의 라벨 매칭 상태를 확인할 수 있습니다:

kubectl describe svc fleetman-webapp

브라우저에서 확인

Minikube 환경이라면 다음과 같이 접근합니다:

minikube ip

이 주소와 서비스의 NodePort(예: 30080)를 조합하여 웹 브라우저에서 확인합니다:

http://<minikube-ip>:30080

 

⚠️ Docker Driver 사용 시

  • Minikube Docker 드라이버를 사용하는 경우:
minikube service fleetman-webapp

  • 포트포워딩 방식으로 접근:
kubectl port-forward pod/webapp 30080:80

 

브라우저에서:

<http://127.0.0.1:30080>

 


라벨 전환으로 빠르게 버전 교체하기

release: "0"을 release: "0-5"로 변경하고 다시 서비스 적용:

kubectl apply -f webapp-service.yaml

브라우저 새로고침 후 새로운 UI가 나타나야 합니다. 캐시 문제로 동일한 UI가 보인다면 Ctrl+F5강제 새로고침을 수행하세요.


유용한 명령어 요약

  • 전체 리소스 보기:
kubectl get all

  • Pod만 보기:
kubectl get po

  • 라벨 정보 보기:
kubectl get po --show-labels

  • 특정 라벨의 Pod만 보기:
kubectl get po -l release=0
kubectl get po -l release=0-5

반응형

댓글