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
'Server > 🚢 Kubernetes' 카테고리의 다른 글
[minikube] 쿠버네티스 포드(pod) 구조와 실행 (0) | 2025.04.08 |
---|---|
[minikube] Kubernetes 실습을 위한 Minikube 설치 가이드 (Mac / Windows / Linux) (0) | 2025.04.08 |
댓글