본문 바로가기
개발 이야기/Kubernetes

Kubernetes, Deployment와 Service 구성 해보기

by 농개 2024. 3. 2.

배포 (Deployments): 컨테이너의 롤아웃 및 업데이트를 관리하며, 응용 프로그램 복제본 및 이미지 버전의 원하는 상태를 유지합니다. 롤링 업데이트 및 롤백을 지원합니다. 실제 Application 구성 단위가 됩니다.

 

 

서비스 (Services): 클러스터 내부에서 응용 프로그램 컨테이너에 대한 네트워킹 및 액세스를 제공하며, 아래와 같은 타입이 있습니다.

  • ClusterIP: 쿠버네티스 클러스터 내부에서만 통신을 허용합니다. 운영환경에서 백엔드 서버 구성에 사용됩니다.
  • NodePort: 특정 포트를 매핑 시킵니다. 그리고 클러스터 외부에서 해당 포트로 접근을 허용합니다. 운영환경에서는 권장하지 않습니다.
  • Loadbalancer: 클라우드 제공업체에서 제공하는 로드 밸런서를 사용하여 서비스를 외부로 노출시킵니다. AWS와 같은 클라우드에 구성할 때 사용됩니다.

 

이번 포스팅에서는 Deployment, Serviceyml 파일을 통해 구성해봅니다.

 

1. Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: springboot-app-deploy
spec:
  replicas: 2
  selector:
    matchLabels:
      app: springboot-app
  template:
    metadata:
      name: springboot-app-pod
      labels:
        app: springboot-app
    spec:
      containers:
        - name: springboot-app-container
          image: springboot-exam:0.0.1
          ports:
            - containerPort: 8080

위와 같이 deployment.yml 파일을 작성하고 아래 명령어를 실행해봅시다.

kubectl apply -f deployment.yml

 ~ kubectl apply -f deployment.yml
deployment.apps/springboot-app-deploy created
 ~ kubectl get po -n default                                                                                                                                 ✔    minikube ⎈
NAME                                   READY   STATUS    RESTARTS   AGE
springboot-app-deploy-9f9d497f-r6dkn   1/1     Running   0          29m
springboot-app-deploy-9f9d497f-xkcsn   1/1     Running   0          29m

위와 정상적으로 replica: 2 설정으로 인해 2개의 Pod가 뜬 것을 확인 할 수 있습니다.

kubectl get po -n default

여기서 -n은 Namespace를 뜻하며, default로 배포되었다는 것을 알 수 있습니다.

 

2. Service

apiVersion: v1
kind: Service
metadata:
  name: springboot-app-svc
spec:
  ports:
    - name: svc-port
      port: 8080
      targetPort: 8080
  selector:
    app: springboot-app
  type: ClusterIP

위와 같이 ClusterIP 타입으로 Service를 구성하였습니다.

포트는 8080:8080으로 매핑 시켜줬습니다.

 

똑같이 kubectl apply -f svc.yml 로 실행해봅시다.

~ kubectl apply -f svc.yml
service/springboot-app-svc created
~ kubectl get svc -n default
NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
kubernetes           ClusterIP   10.96.0.1     <none>        443/TCP    7h51m
springboot-app-svc   ClusterIP   10.108.28.1   <none>        8080/TCP   27s

위와 같이 Service도 구성되었네요.

 

10.108.28.1라는 private ip를 통해

Cluster 내에서 springboot-app과 통신이 가능하겠네요.

당연히 외부(ex.브라우저)에서는 호출안됩니다.

 

3. Pod 접근하여 확인

아래 명령어로 앞서 띄웠던 파드에 접속해봅시다.

 ~ kubectl get po -n default
NAME                                   READY   STATUS    RESTARTS   AGE
springboot-app-deploy-9f9d497f-r6dkn   1/1     Running   0          45m
springboot-app-deploy-9f9d497f-xkcsn   1/1     Running   0          45m

 ~ kubectl exec -n default -it springboot-app-deploy-9f9d497f-r6dkn /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
bash-4.2#

kubectl get po -n default 명령어로 Pod 이름 확인 후

kubectl exec -n default -it {PodName} /bin/bash 명령어로 컨테이너로 접근하였습니다.

 

bash-4.2# curl -v 10.108.28.1:8080
*   Trying 10.108.28.1:8080...
* Connected to 10.108.28.1 (10.108.28.1) port 8080
> GET / HTTP/1.1
> Host: 10.108.28.1:8080
> User-Agent: curl/8.3.0
> Accept: */*
> 
< HTTP/1.1 200 
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 19
< Date: Sat, 02 Mar 2024 12:45:33 GMT
< 
* Connection #0 to host 10.108.28.1 left intact
Hello World!

curl 명령어로 호출해봤습니다. 정상 접근 가능한 걸 확인 할 수 있습니다.

 

보통은 내부 통신에서 IP를 통해 통신할 일은 없습니다.

아래와 같이 Cluster 내에서는 {ServceName}.{Namespace}:{PORT} 형식으로도 가능합니다.

쿠버네티스 내부에서 이를 Host로 인식하도록 서비스 등록이 되어있는 듯 하네요.

bash-4.2# curl springboot-app-svc.default:8080
Hello World!

같은 네임스페이스 내에서 통신이라면 .{Namespace} 부분은 생략 가능합니다.

 


Kubernetes 클러스터를 운영할 때 흔히 접해볼 수 있는

DeploymentService를 구성해보았습니다.

 

다음 포스팅에서는 Ingress 설정을 다뤄보려고 합니다.