Kubernetes 란?
컨테이너를 운영하는 자동화 시스템
기존의 전통적인 방식으로는 보통 WAS를 깔고, 그 위에 jar나 war 파일을 올려서 배포를 했다면,
이제는 컨테이너Docker
를 사용해서 배포를 한다.
컨테이너는 환경 차이 없이 어디서든 실행이 가능하기 때문에 사용한다.
그런데 컨테이너가 많아지면 몇 가지 문제가 생길 수 있다.
- 컨테이너가 죽으면? 누가 다시 띄워주지?
- 여러 서버에 걸쳐서 띄우면? 누가 로드밸런싱 해주지?
- 트래픽 많아지면? 컨테이너를 늘려야 하는데 어떻게?
- 버전 바꿔서 배포하려면? 수동으로 다 해야 하나?
Kubernetes는 이 문제들을 해소해준다.
쿠버네티스는 수많은 컨테이너를 효율적으로, 자동으로, 안정적으로 운영해주는 시스템이다.
- 컨테이너들의 관리자 역할을 하고,
- 컨테이너를 모아둔 클러스터를 만들고
- 어디에 몇 개 띄울지, 죽으면 어떻게 복구할지, 트래픽은 어떻게 분산할지 자동으로 처리해준다.,
- 설정은 YAML 파일에 선언적으로 관리한다.
WAS를 운영할 때와의 차이점
- WAS (Tomcat)를 직접 설치 및 운영하고
- Shell script 혹은 CI 서버에서
restart.sh
,deploy.sh
등으로 수동/반자동 방식 배포를 할 때 - 배포할 때 장애가 발생하면 롤백이 어렵고 다운타임이 발생할 수 있다. k8s 사용시 무중단 배포가 가능한데 말이다.
스케일링
- WAS운영시
- 트래픽 증가시 WAS 인스턴스를 수동으로 늘리고, 로드밸런서에 등록해야 한다.
- 고정된 리소스를 할당해놓고 사용률이 낮더라도 반영이 안된다.
- K8s 운영시
- Horizontal Pod Autoscaler나 Cluster Autoscaler로 자동 확장이 가능하고
- request limit 을 설정하여 리소스 격리 및 효율적 사용이 가능하다.
서비스 디스커버리 및 네트워크 정책
- WAS운영시
- WAS 인스턴스 간 통신은 IP, 포트 관리가 필요하고 수동으로 등록해야 할 때도 있음.
- 서비스 간 인증, 보안 정책은 별도 구성 필요.
- k8S 운영시
- Service, Ingress, NetworkPolicy 등으로 서비스 디스커버리와 보안 제어가 가능.
- DNS 기반으로 서비스를 찾고, 트래픽 제어 가능.
Docker 만 쓸 때와 차이점
Docker를 사용하면 아래 과정을 거친다.
- Dockerfile 만들어서 이미지 빌드
- docker run으로 로컬이나 서버에 컨테이너 실행
- 서버에 접속해서 직접 배포하거나, docker-compose up 같은 걸로 컨테이너 실행
이 때, 장애가 나면 직접 들어가서 재시돌르 해야하고, 배포할 때 직접 서버에 붙어서 해야한다. 서버가 죽으면 앱도 죽을 수 있다.
컨테이너는 자동화되어 있어도 운영은 수동인 상태다.
Kubernetes를 쓰면 ?
- 트래픽 많아지면 자동으로 pod
컨테이너를 감싸는 최소 단위
수를 늘릴 수 있음 (auto scaling) - 컨테이너가 죽으면 자동으로 다시 띄울 수 있음 (self-healing)
- RollingUpdate 가능 (예전 버전 잠깐 돌려두고 새 버전으로 천천히 바꿈)
- 배포는
kubectl apply -f
한 줄로 가능. 서버에 ssh로 들어갈 일이 거의 없다. - 컨테이너를 실행하려면 yaml 파일로 정의하면 된다.
인스턴스간 상태 관리 방법
여러 pod이 떠 있으면, 각각의 인스턴스가 같은 데이터를 바라볼 때 원자성은 어떻게 보장하지?
- 여러 pod이 뜨더라도 각각은 서버 내부에 상태를 두지 않도록 앱은 stateless 하게 설계
- 사용자 세션, 처리 상태, 누적 값 등은 DB나 Redis 같은 외부로 분리
- 원자성은 데이터베이스가 제공하는 ACID 트랜잭션을 이용해 중요한 처리의 원자성 확보 (트랜잭션과 락 사용)
- 특정 리소스에 대한 동시 접근이 우려된다면 락 / 분산락 / 큐로 보완
- DB 레벨 락 (비관적 락 / 낙관적 락)
- Redis 기반 분산 락 (Redlock, Lua 스크립트)
- MQ/Kafka 큐 기반의 순차 처리