1.1 쿠버네티스와 같은 시스템이 필요한 이유
1.1.1 모놀리스 애플리케이션에서 마이크로서비스로 전환
모놀리스 애플리케이션에서 마이크로서비스로 서비스 패러다임이 전환하면서, 모놀리스 애플리케이션에서 신경쓰지 않아도 되었던 새로운 문제들이 생기기 시작했다.
마이크로서비스 배포
- 서비스 종류가 많아지면 배포 조합 수가 많아지면서 관리가 힘들다.
- 서비스 간 상호 종속성 수가 많아지면 배포 관련 결정이 어려워진다.
- 서비스끼리 서로 통신하면서 작업을 수행하게 되는데, 이 여러 서비스들이 하나의 시스템처럼 동작할 수 있도록 관리가 필요하다.
환경 요구 사항의 다양성
- 한 머신 위에 여러 서비스를 올리게 되면 서로 다른 버전의 종속성이 있는 경우에 종속성 관리가 힘들어진다.
1.1.2 애플리케이션에 일관된 환경 제공
- 개발 환경(개발자의 로컬 머신) 과 프로덕션 환경이 다른 것은 항상 문제가 되어왔다.
- 이 차이 때문에 디버깅이 힘들어서 이슈가 터져도 해결에 많은 시간이 걸렸다.
- 게다가 프로덕션 환경은 시간이 지나면 변화한다.
- 시스템 관리자는 프로덕션 환경을 최신 보안 상태로 유지하고 싶어하지만 개발자는 아니다. (서로 관심 사항이 다름)
- 그래서 운영체제, 라이브러리, 시스템 구성, 네트워킹 환경, 기타 모든 것을 동일하게 만들 수 있다면 이상적일 것
1.1.3 지속적인 배포로 전환 : 데브옵스와 노옵스
데브옵스의 장점
- 개발자가 운영 관련 업무도 하게 되면 실제 운영 환경에 대한 이해도가 높아진다.
- 인프라와 데이터 센터 구성 지식은 개발자가 애플리케이션을 배포하는데 필요하지만 당장 알고 싶어하지 않는다.
- 그래서 개발자와 시스템 관리자의 관점을 철저하게 나눠서 각자 최고로 잘하는 것에 더 힘쓰게 하는 것이 목표이다.
- 이런 분리가 더 극대화되면 하드웨어 인프라를 전혀 알지 못해도 개발자가 운영 팀을 거치지 않고 애플리케이션을 배포할 수 있게 된다.
- 이런 방식을 노옵스라고 한다.
1.2 컨테이너 기술 소개
쿠버네티스가 필요한 이유에 대해서 이해하기 위해서는 먼저 컨테이너 기술이 왜 나오게 되었는지를 이해해야 한다.
1.2.1 컨테이너 이해
- 서비스가 잘게 나눠질 수록 모든 서비스에 머신을 할당하는 것은 리소스 낭비가 된다.
- 또한 머신 수가 많아지기 때문에 관리하기가 더 힘들어진다.
리눅스 컨테이너 기술로 구성 요소 격리
- 동일한 호스트에서 서비스를 격리된 채로 실행할 수 있고, 리소스도 따로 할당할 수 있다.
- Guest OS가 필요 없기 때문에 VM에 비해 오버헤드가 훨씬 적다.
컨테이너와 가상머신 비교
컨테이너 격리를 가능하게 하는 메커니즘 소개
- 프로세스 별 독립된 뷰 제공
- 프로세스 별 리소스 제한
리눅스 네임스페이스로 프로세스 격리
프로세스의 가용 리소스 제한
1.2.2 도커 컨테이너 플랫폼 소개
1.3 쿠버네티스 소개
구글에서 MSA 해보니까 서비스 및 구성요소 수가 많아질 수록 관리가 너무 힘들었다. 그래서 많은 수의 소프트웨어 구성요소를 관리하고 비용 효율적으로 개발, 배포할 수 있는 솔루션을 만들게 된 것이다.
1.3.1 쿠버네티스의 기원
1.3.2 넓은 시각으로 쿠버네티스 바라보기
- 컨테이너화된 애플리케이션을 쉽게 배포하고 관리할 수 있게 해주는 소프트웨어 시스템
- 모든 노트가 하나의 거대한 컴퓨터인 것처럼 수천 대의 컴퓨터 노드에서 애플리케이션을 실행할 수 있다.
- 기본 인프라를 추상화하고 개발, 배포, 관리를 단순화한다.
- 클러스터 노드를 추가하는 것은 사용 가능한 리소스 양이 추가되는 것을 의미한다.
쿠버네티스 핵심 이해
- 마스터 노드와 워커 노드로 구성
- 애플리케이션 매니패스트를 마스터에 게시하면, 쿠버네티스는 워커 노드 클러스터에 배포한다.
- 특정 애플리케이션이 묶여서 함께 실행되도록 설정할 수 있다.
- 애플리케이션들은 클러스터에 걸쳐 분산되지만, 배포된 위치에 상관없이 동일한 방식으로 서로 통신할 수 있다.
개발자가 애플리케이션 핵심 기능에 집중할 수 있도록 지원
- 쿠버네티스는 클러스터의 운영체제로 생각할 수 있다.
- 특정 인프라 관련 서비스를 애플리케이션에 구현하지 않아도 된다.
- 서비스 디스커버리, 스케일링, 로드밸런싱, 자가 치유, 리더 선출 기능을 제공한다.
운영 팀이 효과적으로 리소스를 활용할 수 있도록 지원
- 컨테이너화된 애플리케이션을 실행하고, 구성요소 간 서로를 찾는 방법에 대한 정보를 제공한다.
- 애플리케이션을 재배치하고 조합하면서 수동으로 스케쥴링 하는 것보다 리소스를 효율적으로 사용할 수 있다.
1.3.3 쿠버네티스 클러스터 아키텍처 이해
- 마스터 노드는 전체 쿠버네티스 시스템을 제어하고 관리하는 쿠버네티스 컨트롤 플레인을 실행한다.
- 워커 노드는 실제 배포되는 컨테이너 애플리케이션을 실행한다.
컨트롤 플레인
클러스터를 제어하고 작동시킨다. 마스터 노드에서 실행하거나, 클러스터화 될 수 있다. 구성 요소는 다음과 같다.
- 쿠버네티스 API 서버 (사용자, 컨트롤 플레인 구성요소 간 통신)
- 스케줄러 (애플리케이션 배포)
- 컨트롤러 매니저 (구성요소 복제본, 워커 노드 추적, 노드 장애 처리)
- Etcd (클러스터 구성을 저장하는 분산 데이터 저장소)
노드
워커 노드는 컨테이너화된 애플리케이션을 실행하는 시스템이다. 구성 요소는 다음과 같다.
- 컨테이너 런타임 (docker, rkt ..)
- API 서버와 통신하고 노드의 컨테이너를 관리하는 Kubelet
- 애플리케이션 구성 요소 간 네트워크 트래픽을 로드밸런싱하는 쿠버네티스 프록시
1.3.4 쿠버네티스에서 애플리케이션 실행
쿠버네티스에서는 다음 순서로 애플리케이션 실행이 이루어진다.
- 애플리케이션을 컨테이너 이미지로 패킹
- 해당 이미지를 이미지 레지스트리로 푸시
- 쿠버네티스 API 서버에 애플리케이션 디스크립션을 게시
디스크립션으로 컨테이너를 실행하는 방법 이해
- API 서버가 애플리케이션 디스크립션을 처리할 때 스케줄러는 각 컨테이너에 필요한 리소스를 계산
- 해당 시점에 할당되지 않은 리소스를 바탕으로 워커 노드에 컨테이너 할당
- 노드의 Kubelet은 컨테이너 런타입에 필요한 컨테이너 이미지를 가져와서 컨테이너 실행
실행된 컨테이너 유지
- 애플리케이션이 샐행되면 쿠버네티스는 애플리케이션의 배포 상태가 사용자가 제공한 디스크립션과 일치하는지 계속해서 확인한다. 현재 상태를 체크해서 오류가 발생하면, 사용자가 설정한 상태와 맞추기 위해서 컨테이너의 인스턴스를 추가하거나 재시작을 한다.
복제본 수 스케일링
- 복제본 수를 수동으로 정할 수 있다.
- 또는 CPU, 메모리, 초당 요청 수, 기타 다른 메트릭에 따라서 복제본 수가 자동 조정되게 할 수 있다.
이동한 애플리케이션에 접근하기
- 쿠버네티스는 컨테이너를 클러스터 안에서 다른 노드로 이동키실 수 있다.
- 클라이언트에서 계속 이동하는 컨테이너를 쉽게 찾을 수 있도록, 쿠버네티스는 하나의 고정 IP 주소로 모든 컨테이너를 노출한다.
- 해당 주소를 통해 클라이언트에서 접근이 가능하고, 클러스터에서 실행 중인 다른 애플리케이션에서도 접근이 가능하다.
- kube-proxy는 서비스를 제공하는 모든 컨테이너에서 서비스 연결이 로드밸런싱되도록 한다.
1.3.5 쿠버네티스 사용의 장점
운영 팀이 더 이상 애플리케이션 배포를 처리할 필요가 없다. 개발자가 시스템 관리자의 도움 없이 바로 배포할 수 있다.
애플리케이션 배포의 단순화
- 개발자는 자체적으로 애플리케이션 배포를 할 수 있다.
- 클러스터를 구성하는 서버에 대해서 알 필요가 없다.
- 특정 종류의 하드웨어에서 실행이 필요한 경우, 배포될 머신을 지정할 수 있다. (eg. SSD 나 GPU)
하드웨어 활용도 높이기
- 애플리케이션의 리소스 요구 사항에 따라서, 실행에 가장 적합한 노드를 선택할 수 있다.
- 애플리케이션이 클러스터 간 자유롭게 이동할 수 있으므로, 리소스를 최대 활용하는 상태를 유지할 수 있다.
상태 확인과 자가 치유
- 노드 장애 발생 시 자동으로 애플리케이션을 다른 노드로 스케줄링한다.
- 이전엔 인프라에 장애가 발생하면 애플리케이션을 다른 머신으로 마이그레이션을 했어야 했다.
- 하지만 이제는 운영 팀 입장에서는 장애가 발생한 인프라만 조치하면 된다.
오토스케일링
- 애플리케이션에서 사용하는 리소스를 모니터링하고 실행 중인 인스턴스 수를 계속 조정할 수 있다.
- 클라우드 서비스 업체의 API를 이용하여 노드를 추가하면 클러스터 크기도 자동으로 조정할 수 있다.
애플리케이션 개발 단순화
- 개발과 프로덕션 환경 모두 동일하게 설정할 수 있기 때문에 문제 발견 및 해결이 쉬워진다.
- 일반적으로 구현해야 하는 기능이 줄어든다. (피어 검색, 리더 선출 등)
- 꼭 필요한 비즈니스 로직만 구현하게 되어 더 빠른 개발이 가능해진다.
- 신버전 배포 시 문제가 발생하면 자동으로 감지하고 롤아웃을 중지하여 신뢰성 증가에 도움이 된다.
- 조직 전체에 개발 가속화가 이루어지게 된다.