쿠버네티스란?
쿠버네티스(Kubernetes, 이하 k8s)는 컨테이너화된 애플리케이션을 자동으로 배포, 확장 관리해주는 오케스트레이션 플랫폼이다.
단순히 컨테이너를 실행하는 수준을 넘어서, 여러 서버에 분산된 컨테이너들을 하나의 시스템처럼 운영할 수 있게 해준다.
k8s에서의 핵심개념은 선언형 관리이다. 사용자가 “이 상태로 유지하겠다”라고 정의(Desired state)하면, 쿠버네티스는 계속 상태(etcd)를 감시하면서 목표 상태와 맞추도록 동작한다.
언제 K8s를 사용하는가?
작은 규모의 서비스라면 단순히 Docker만으로도 충분할 수 있다. 하지만 서비스가 점점 커지고, 여러 서버에 나누어 배포해야하거나 운영 자동화가 중요해지는 순간 k8s를 고려하게 된다.
- 서버 여러 대에 컨테이너를 분산 배포해야 할 때
- 장애가 난 컨테이너를 자동으로 복구해야 할 때
- 트래픽 증가에 따라 유연하게 확장해야 할 때
- 무중단 배포나 롤백이 중요할 때
- 운영 환경을 일관된 방식으로 관리하고 싶을 때
다만 k8s가 모든 상황에 적합한 것은 아니다. 배워야할 개념이 많고, 초기 구축과 운영 난이도도 높다. 그래서 작은 규모의 서비스나 소규모 팀에서는 오히려 운영 부담이 커져 병목이 될 수 있다.
결국 k8s는 복잡한 운영 문제를 해결할 필요가 분명할때 도입 가치가 커지는 플랫폼이다.
k8s의 기본 구성
파드 (Pod)
파드는 k8s에서 가장 작은 논리적인 배포 단위이다.
하나 이상의 컨테이너(한개의 메인 어플리케이션 과 이를 보조하는 사이드카 어플리케이션)를 묶는 단위이며, 같은 파드 안의 컨테이너들을 다음을 공유 한다.
- 네트워크(IP, 포트)
- 스토리지(볼륨)
즉, 단순히 컨테이너 하나가 아니라 함께 동작해야 하는 실행 단위이다
ReplicaSet
레플리카셋은 파드의 개수를 유지하는 역할을 한다.
예를 들어 파드를 3개 유지하도록 설정하면, 하나가 죽어도 자동으로 다시 생성해서 항상 3개를 유지한다.
Deployment
디플로이먼트는 레플리카셋의 상위 개념으로 애플리케이션 배포를 원활이 해주는 역할을 한다. 리비전을 지원하기 때문에 롤링 업데이트 및 유사시 손쉽게 롤백할 수 있다.
- 파드 개수 유지
- 롤링 업데이트
- 롤백
실제 운영에서는 Deployment를 주로 사용한다.
Service
파드는 재생성될 수 있다. 이렇게 되면 IP가 바뀐다. 그래서 IP로 직접 접근하면 불안정하다.
서비스는 이를 해결 하기 위해 고정된 접속 지점을 제공한다. 아래는 서비스들의 타입이다
- ClusterIP: 클러스터 내부 통신용
- NodePort: 노드 포트를 통해 외부 접근
- LoadBalancer: 외부 로드 밸런서를 통해 접근
Ingress
인그레스는 클러스터 외부에서 들어오는 HTTP/HTTPS 요청을 내부 서비스로 연결하기 위한 라우팅 규칙 이다.
예를 들어 다음처럼 경로나 도메인에 따라 서로 다른 서비스로 요청을 보낼 수 있다.
sungbinlee.dev-> 메인 블로그sungbinlee.dev/posts-> 게시글 페이지admin.sungbinlee.dev-> 관리자 페이지api.sungbinlee.dev-> 블로그 API 서버
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: blog-ingress
spec:
rules:
- host: sungbinlee.dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: blog-service
port:
number: 80
- path: /posts
pathType: Prefix
backend:
service:
name: post-service
port:
number: 80
- host: admin.sungbinlee.dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: admin-service
port:
number: 80
다만 인그레스 자체가 트래픽을 처리하는 것은 아니다. 실제 트래픽은 Ingress Controller가 담당하며, 대표적으로 NGINX Ingress Controller가 많이 사용된다.
즉, Ingress는 쿠버네티스 환경에서 리버스 프록시 설정을 추상화해서 관리하는 방식에 가깝다.
ConfigMap과 Secret
ConfigMap과 Secrect은 애플리케이션 설정을 코드와 분리하기 위한 오프젝트이다.
- ConfigMap: 일반 설정값
- Secret: 비밀번호, 토큰, 인증서 같은 민감 정보
둘 다 파트에 환경변수나 파일 형태로 주입할 수 있다.
다만 Secrect은 기본적으로 base64 인코딩일 뿐, 그 자체가 암호화 되어 있다고 볼 수 없다.
그래서 실무에서는 etcd 암호화, RBAC, Vault나 AWS Secrets Manager 같은 외부 비밀 관리 시스템을 함께 사용해 보안을 강화한다.
스토리지 (PV / PVC)
k8s에서 파드는 기본적으로 휘발성이다. 즉, 파드가 삭제되면 내부 데이터도 사라진다.
이를 해결하기 위해 사용하는 것이 영속 스토리지이다.
- PV (PersistentVolume): 실제 저장소
- PVC (PersistentVolumeClaim: 저장소 요청
영속 스토리지를 정의해서 사용하면 파드가 삭제되어도 데이터는 유지가 되고, 다른 노드로 이동해도 동일한 데이터를 사용할 수 있다.
네임스페이스 (Namespace)
k8s에서의 네임스페이스는 클러스터 안의 리소스를 논리적으로 구분해서 관리하기 위한 단위이다.
예를 들어 같은 클러스터 안에서도 개발 환경, 운영 환경, 팀별 서비스처럼 리소스를 나누어 관리할 수 있다.
- dev / stage / prod
- 팀별
- 프로젝트별
이렇게 나누면 같은 이름의 리소스라도 Namespace가 다르면 서로 구분할 수 있고,
권한(RBAC), 리소스 제한(ResourceQuota), 네트워크 정책(NetworkPolicy)도 범위별로 나누어 적용하기 쉬워진다.
개념적으로는 파이썬의 namespace와 비슷하게 이해할 수 있다.
같은 이름이라도 어느 Namespace에 속해 있는지에 따라 서로 다른 리소스로 취급된다.
스케줄링
쿠버네티스에서 스케줄링은 파드를 어떤 노드에 배치할지 결정하는 과정이다.
기본적으로는 쿠버네티스 스케줄러가 자체 알고리즘으로 노드 상태와 자원 상황을 보고 적절한 노드를 선택한다.
즉, CPU나 메모리 여유, 여러 제약 조건 등을 계산해서 가장 적합한 노드에 파드를 배치한다.
실무에서는 YAML 설정을 통해 원하는 배치 조건이나 우선순위를 함께 정의하는 경우가 많다.
대표적으로 사용하는 설정은 다음과 같다.
- nodeSelector: 특정 라벨이 붙은 노드에만 배치
- affinity / anti-affinity: 특정 조건의 노드나 파드와 가깝게 또는 멀리 배치
- taints / tolerations: 특정 노드에는 아무 파드나 올라오지 못하게 하고, 허용된 파드만 배치
오토 스케일링 (HPA)
쿠버네티스의 오토스케일링은 서비스 부하에 따라 파드 개수를 자동으로 조절하는 기능이다.
HPA(Horizontal Pod Autoscaler) 를 사용하며, CPU나 메모리 같은 메트릭을 기준으로 동작한다.
트래픽이 증가하면 파드 수를 늘리고, 부하가 줄어들면 다시 줄인다. 즉, 파드 하나의 성능을 키우는 수직 확장이 아니라 파드 수를 조절하는 수평 확장이다.
다만 HPA가 동작하려면 클러스터에서 메트릭을 수집할 수 있어야 한다. 보통은 Metrics Server가 각 노드의 kubelet으로부터 리소스 사용량을 가져와서, 쿠버네티스가 CPU나 메모리 사용량을 기준으로 스케일링할 수 있게 해준다.
쿠버네티스의 핵심 개념 정리
쿠버네티스를 이해할 때 중요한 핵심은 다음이다.
- 선언형 시스템
- 자동 복구 (self-healing)
- 확장성 (scaling)
- 분산 시스템 관리
결국 쿠버네티스는
컨테이너를 “잘 실행하는 도구”가 아니라
“대규모 서비스를 안정적으로 운영하기 위한 플랫폼”
Leave a comment