K8s(Kubernetes)

업데이트:

개요

  • 쿠버네티스(Kubernetes, 줄여서 K8s)1는 컨테이너화된 애플리케이션의 배포와 확장, 관리를 자동화하는 오픈 소스 컨테이너 오케스트레이션 플랫폼이다.

주요 기능

서비스 디스커버리와 로드 밸런싱

  • 쿠버네티스는 DNS 이름을 사용하거나 자체 IP 주소를 사용하여 컨테이너를 노출할 수 있다.
  • 컨테이너 트래픽이 많은 경우 쿠버네티스는 로드 밸런싱을 수행하고 네트워크 트래픽을 분산하여 배포를 안정적으로 수행할 수 있다.

스토리지 오케스트레이션

  • 쿠버네티스를 사용하면 로컬 스토리지, 퍼블릭 클라우드 제공업체 등 원하는 스토리지 시스템을 자동으로 마운트할 수 있다.

자동화된 롤아웃과 롤백

  • 쿠버네티스를 사용하여 배포된 컨테이너의 원하는 상태를 설명할 수 있으며, 실제 상태를 원하는 상태로 제어된 속도로 변경할 수 있다.
  • 예를 들어, 쿠버네티스를 자동화하여 배포할 새 컨테이너를 생성하고 기존 컨테이너를 제거한 후 모든 리소스를 새 컨테이너에 적용할 수 있다.
  • 롤링 업데이트, Canary, Blue-Green 등의 배포 전략을 사용할 수 있다.

자동화된 bin packing

  • 쿠버네티스는 컨테이너화된 작업을 실행하는 데 사용할 수 있는 노드 클러스터를 제공하고, 각 컨테이너에 필요한 CPU와 메모리의 양을 쿠버네티스에게 알려준다.
  • 쿠버네티스는 컨테이너를 노드에 장착하여 리소스를 최대한 활용할 수 있다.

자가 복구

  • 쿠버네티스는 실패한 컨테이너를 다시 시작하고 컨테이너를 교체하며, ‘사용자 정의 상태 검사’에 응답하지 않는 컨테이너를 죽이고 서비스 준비가 끝날 때까지 그러한 과정을 클라이언트에 보여주지 않는다.

보안 정보와 구성 관리

  • 쿠버네티스를 사용하면 암호, OAuth 토큰 및 SSH 키와 같은 보안 정보를 저장하고 관리할 수 있다.
  • 컨테이너 이미지를 재구성하거나 스택 구성의 보안 정보을 노출하지 않고도 보안 정보 및 애플리케이션 구성을 배포하고 업데이트할 수 있다.
  • NameSpace, RBAC, NetworkPolicy 등을 활용한 보안 격리가 가능하다.

배치 실행

  • 서비스 외에도, 쿠버네티스는 배치 및 CI 워크로드를 관리할 수 있으며, 필요한 경우 실패한 컨테이너를 교체할 수 있다.

확장

  • 간단한 명령어, UI, 또는 CPU 사용량에 따라 수평 오토 스케일링(HPA)으로 부하에 따라 자동으로 애플리케이션을 확장하거나 축소할 수 있다.
  • 업스트림 소스 코드를 변경하지 않고 쿠버네티스 클러스터 기능을 추가할 수 있다.

필요 항목

도구 설명
kubectl Kubernetes CLI
Docker 컨테이너 빌드용
  • Windows 환경에서는 Docker Desktop을 설치 후 설정의 Kubernetes에서 “Enable Kubernetes” 설정하면 모든 준비는 완료된다.

이미지 빌드

K8s 리소스 파일 작성

  • 기본 구성은 아래와 같다.
    • apiVersion : K8s API 버전
    • kind : 생성할 리소스의 종류
    • metadata : 애플리케이션의 이름, 레이블(Label)과 같은 메타데이터
    • spec : 배포의 실제 구성
  • 리소스의 종류는 아래와 같다.
    • Pod : 하나 이상의 컨테이너를 묶어 실행하는 가장 기본적인 단위이다.
    • Deployment : 파드를 생성하고 관리하며, 애플리케이션의 배포와 업데이트를 자동화한다.
    • Service : 파드들을 묶어 안정적인 네트워크 엔드포인트를 제공하고, 파드에 접근하는 방식을 정의한다.
    • StatefulSet : 순서가 중요한 데이터베이스와 같이 상태를 가지는 애플리케이션을 위한 워크로드 컨트롤러이다.
    • DaemonSet : 각 노드에 하나의 파드 복제본을 배포하도록 한다.
    • Custom Resource Definition (CRD) : 사용자가 직접 새로운 리소스를 정의할 수 있도록 하는 기능이다.
  • 여기선 간단히 구성할 예정이므로, 프로젝트 위치에서 “k8s” 폴더를 생성 후 아래 두 파일만 작성한다.

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-k8s
  template:
    metadata:
      labels:
        app: hello-k8s
    spec:
      containers:
      - name: hello-k8s
        image: hello-docker:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
  • deployment.yaml은 K8s에서 애플리케이션의 배포를 정의하는 파일로, 애플리케이션 배포에 필요한 구성 정보를 포함한 세부 설정을 작성하여 이 파일을 기반으로 클러스터에 자동으로 배포, 관리, 업데이트한다.

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: hello-service
spec:
  type: NodePort
  selector:
    app: hello-k8s
  ports:
  - port: 8080
    targetPort: 8080
    nodePort: 30080
  • service.yaml 파일은 K8s에서 파드(Pod) 그룹에 대한 고정적인 네트워크 서비스(IP 주소 및 포트)를 정의하는 파일이다.
  • 파드의 동적인 IP 주소 대신 안정적인 단일 엔드포인트를 제공하여 클라이언트가 애플리케이션을 안정적으로 호출할 수 있도록 하고, 파드 그룹의 IP 주소와 포트 번호를 직접 노출하는 대신 추상화된 네트워크 서비스로 제공하는 역할을 한다.

K8s에 배포

C:\Development\Workspace\hello-docker>kubectl apply -f k8s/deployment.yaml
deployment.apps/hello-deployment created

C:\Development\Workspace\hello-docker>kubectl apply -f k8s/service.yaml
service/hello-service created

서비스 점검

애플리케이션 확인

C:\Development\Workspace\hello-docker>kubectl get svc
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
hello-service   NodePort    10.110.61.174   <none>        8080:30080/TCP   35s
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP          67m

C:\Development\Workspace\hello-docker>curl http://localhost:30080/api/GracefulSoul
Hello GracefulSoul
  • 클러스터에 구성된 서비스를 조회하고, 서비스를 호출하여 정상적으로 애플리케이션이 구동되었는지 확인한다.

리소스 확인

C:\Development\Workspace\hello-docker>kubectl get all
NAME                                    READY   STATUS    RESTARTS   AGE
pod/hello-deployment-69cf9f9d77-lp5f7   1/1     Running   0          2m9s

NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/hello-service   NodePort    10.110.61.174   <none>        8080:30080/TCP   101s
service/kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP          68m

NAME                               READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/hello-deployment   1/1     1            1           2m9s

NAME                                          DESIRED   CURRENT   READY   AGE
replicaset.apps/hello-deployment-69cf9f9d77   1         1         1       2m9s
  • 현재 K8s 의 모든 정보를 조회한다.

로그 확인

C:\Development\Workspace\hello-docker>kubectl logs -l app=hello-k8s
2025-09-02T11:19:40.563Z  INFO 7 --- [hello-docker] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
2025-09-02T11:19:40.577Z  INFO 7 --- [hello-docker] [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2025-09-02T11:19:40.578Z  INFO 7 --- [hello-docker] [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.31]
2025-09-02T11:19:40.604Z  INFO 7 --- [hello-docker] [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2025-09-02T11:19:40.605Z  INFO 7 --- [hello-docker] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 616 ms
2025-09-02T11:19:40.841Z  INFO 7 --- [hello-docker] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
2025-09-02T11:19:40.852Z  INFO 7 --- [hello-docker] [           main] gracefulsoul.HelloDockerApplication      : Started HelloDockerApplication in 1.151 seconds (process running for 1.421)
2025-09-02T11:21:17.817Z  INFO 7 --- [hello-docker] [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2025-09-02T11:21:17.818Z  INFO 7 --- [hello-docker] [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2025-09-02T11:21:17.818Z  INFO 7 --- [hello-docker] [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
  • hello-k8s 애플리케이션의 로그를 확인한다.

배포 삭제

C:\Development\Workspace\hello-docker>kubectl delete -f k8s/
deployment.apps "hello-deployment" deleted
service "hello-service" deleted
  • 불필요한 애플리케이션인 경우, 확인 후 “k8s” 폴더에서 정의한 파일들을 참조하여 관련 앱을 제거한다.

정리

  • Spotify는 과거 Helios라는 오픈 소스 자체 컨테이너 오케스트레이션 시스템을 사용하였으나, 쿠버네티스의 활성화된 커뮤니티와 기술력을 기반으로 모든 서비스를 전환하고 CPU 최적화 등 다양한 이점을 얻었다고 알려져있다.
  • 이렇게 기술의 변화에 따라서 서비스 운영 환경에 더 적합한 서비스를 학습하고, 더 안정적인 서비스를 고객에게 적용하는 것은 산업의 발전을 넘어 기술과 사회에 더 좋은 이점으로 나타날 것이다.

Reference

※ Sample Code는 여기에서 확인 가능합니다.

댓글남기기