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” 설정하면 모든 준비는 완료된다.
이미지 빌드
- 해당 이미지는 이전 포스트인 Custom JRE로 경령화된 Dockering II에서 만든 이미지로 대체하므로, Custom JRE로 경령화된 Dockering I과 함께 참고 바란다.
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는 여기에서 확인 가능합니다.
댓글남기기