Kubernetes Service를 이용한 Pod 연결

KubernetesBeginner
지금 연습하기

소개

Kubernetes에서 Pod는 일시적인 존재로, 언제든지 종료되고 다시 생성될 수 있습니다. 이로 인해 Pod에 직접 연결하는 것이 어려워 네트워크 구성에 문제가 발생합니다. 이 문제를 해결하기 위해 Kubernetes는 Service라는 더 높은 수준의 추상화 계층을 제공합니다. Service는 일련의 Pod에 대해 안정적인 IP 주소와 DNS 이름을 제공하여 다른 구성 요소들이 쉽게 연결할 수 있도록 합니다. 이번 실습에서는 Kubernetes에서 Service를 사용하여 Pod를 네트워크로 연결하는 방법을 배웁니다.

Minikube 클러스터 시작

리소스를 생성하기 전에 실행 중인 Kubernetes 클러스터가 필요합니다. Minikube는 로컬 머신에서 실행되는 경량 Kubernetes 환경입니다.

  1. 작업 디렉토리로 이동:

    터미널을 열고 기본 프로젝트 폴더로 이동합니다:

    cd /home/labex/project
    
  2. Minikube 시작:

    Minikube를 시작하여 Kubernetes 클러스터를 초기화합니다:

    minikube start
    
    • 이 명령은 로컬 머신에 단일 노드 Kubernetes 클러스터를 설정합니다.
    • 시스템 성능에 따라 Minikube가 시작되는 데 몇 분 정도 걸릴 수 있습니다.
  3. Minikube 실행 확인:

    Minikube 클러스터의 상태를 확인합니다:

    minikube status
    
    • kubeletapiserver와 같은 구성 요소가 Running 상태인지 확인하세요.
    • 클러스터가 실행 중이 아니라면 minikube start를 다시 실행하세요.

Minikube 시작 중 문제가 발생하면 minikube delete를 사용하여 환경을 초기화할 수 있습니다.

Pod 생성

첫 번째 단계는 간단한 Pod를 생성하는 것입니다. /home/labex/project/myapp-pod.yaml 파일을 생성하고 다음 내용을 입력합니다:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod-1
  labels:
    app: nginx
spec:
  containers:
    - name: my-container
      image: nginx

파일을 저장하고 다음 명령을 실행하여 Pod를 생성합니다:

minikube kubectl -- apply -f /home/labex/project/myapp-pod.yaml

이 명령은 Nginx 이미지를 실행하는 단일 컨테이너를 포함한 my-pod-1이라는 이름의 Pod를 생성합니다.

Service 생성

두 번째 단계는 이전 단계에서 생성한 Pod를 대상으로 하는 Service를 만드는 것입니다. /home/labex/project/service.yaml 파일을 생성하고 다음 내용을 입력합니다:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: nginx
  ports:
    - name: http
      port: 80
      targetPort: 80

파일을 저장하고 다음 명령을 실행하여 Service를 생성합니다:

minikube kubectl -- apply -f /home/labex/project/service.yaml

이 명령은 app=nginx 레이블이 지정된 Pod를 대상으로 하며 80번 포트를 노출하는 my-service라는 이름의 Service를 생성합니다.

Service 테스트

세 번째 단계는 다른 Pod에서 Service에 접속하여 테스트하는 것입니다. /home/labex/project/test-pod-1.yaml 파일을 생성하고 다음 내용을 입력합니다:

apiVersion: v1
kind: Pod
metadata:
  name: test-pod-1
spec:
  containers:
    - name: my-container
      image: busybox
      command:
        - sleep
        - "3600"

파일을 저장하고 다음 명령을 실행하여 테스트 Pod를 생성합니다:

minikube kubectl -- apply -f /home/labex/project/test-pod-1.yaml

이 명령은 Busybox 이미지를 실행하는 단일 컨테이너를 포함한 test-pod-1이라는 이름의 Pod를 생성합니다.

다음으로, wget을 사용하여 Busybox Pod에서 Service에 접속합니다:

minikube kubectl -- exec test-pod-1 -- wget -qO- http://my-service

이 명령은 기본 Nginx 페이지를 반환하며, 이는 Service가 정상적으로 작동하고 있음을 의미합니다.

Service 업데이트

네 번째 단계는 다른 Pod 집합을 대상으로 하도록 Service를 업데이트하는 것입니다. /home/labex/project/service.yaml 파일의 selector 필드를 다음과 같이 수정합니다:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: busybox
  ports:
    - name: http
      port: 80
      targetPort: 80

파일을 저장하고 다음 명령을 실행하여 Service를 업데이트합니다:

minikube kubectl -- apply -f /home/labex/project/service.yaml

이 명령은 Service가 app=busybox 레이블을 가진 Pod를 대상으로 하도록 업데이트합니다. 현재 이 레이블을 사용하는 Pod가 없으므로 Service의 엔드포인트는 비어 있게 됩니다.

업데이트된 Service 테스트

다섯 번째 단계는 다른 Pod에서 접속하여 업데이트된 Service를 테스트하는 것입니다. 다음 명령으로 새로운 테스트 Pod를 생성합니다:

minikube kubectl -- run my-pod-2 --image=busybox --restart=Never -- sleep 3600

이 명령은 Busybox 이미지를 실행하는 단일 컨테이너를 포함한 my-pod-2라는 이름의 새로운 Pod를 생성합니다.

레이블을 변경하기 전에 Service에 일치하는 엔드포인트가 없는지 확인합니다:

minikube kubectl -- get endpoints my-service

현재 app=busybox 레이블을 가진 Pod가 없으므로 출력 결과는 <none>으로 표시됩니다.

이는 Service 셀렉터가 app=busybox를 찾고 있지만, Nginx 서버 Pod는 여전히 app=nginx로 레이블이 지정되어 있기 때문입니다. 이를 해결하려면 원래 서버 Pod의 레이블을 다시 지정하여 Service가 다시 Nginx 컨테이너를 가리키도록 해야 합니다.

다음 명령을 실행하여 서버 Pod의 레이블을 업데이트합니다:

minikube kubectl -- label pod my-pod-1 app=busybox --overwrite

이 명령은 my-pod-1의 레이블을 업데이트하여 Service 셀렉터와 일치하게 만듭니다.

이제 my-pod-2에서 Service를 다시 테스트합니다:

minikube kubectl -- exec my-pod-2 -- wget -qO- http://my-service

이 명령은 다시 기본 Nginx 페이지를 반환해야 하며, 이는 Service가 정상적으로 작동하고 있음을 의미합니다.

요약

이번 실습에서는 Kubernetes에서 Service를 사용하여 Pod를 네트워크로 연결하는 방법을 배웠습니다. Nginx Pod를 생성하고 Service로 노출한 뒤, Busybox 클라이언트 Pod에서 해당 Service를 테스트했습니다. 또한 Service 셀렉터를 업데이트하고 원래의 Nginx Pod 레이블을 다시 지정하여 Service가 정상적인 웹 서버를 다시 가리키도록 설정했습니다. Service는 Kubernetes 네트워킹의 핵심 구성 요소이며, 안정적이고 확장 가능한 방식으로 Pod에 연결할 수 있게 해줍니다.