Cloud Native

  1. 글로벌 스케일로 서비스가 이루어지고 그리고 이용자의 위치에 상관없이 최적화된 레이턴시, 가용성을 제공할 수 있어야함

  2. 수천명의 동시 이용자도 감당할 수 있게 스케일링이 가능해야함. 병렬화랑은 약간 다른 개념으로 수평적인 스케일링이 가능해야한다는 뜻임

  3. 특정 인프라 구조에 의존하면 안됨. 그리고 인프라는 언제나 망가질 수 있다는 것을 가정하고 구성되어야 함.

  4. 업그레이드와 테스트가 무중단으로 가능해야함.

  5. 보안 또한 반드시 중요하게 여겨져야함. 많은 cloud native application이 굉장히 많은 작은 컴포넌트들로 구성되고 이 컴포넌트들이 각자 모든 인증정보를 가지고 있을 수 없는 만큼 단순한 방화벽을 넘어서 정교한 접근 제어 시스템이 필요함

처음엔 IaaS 스타일로 시작. 그러나 여전히 스케일링이나 보안요소들이 어려움. 특히 클라우드 기반의 데이터 저장소나 이벤트 서비스, 디버깅 수단이 존재하지 않아 많은 오픈 소스 컴포넌트들을 어떻게든 조합해서 써야만 했음.

이후 구글의 연구문서나 야후의 하둡같은게 나와서 데이터를 분산 관리하는건 좀 나아졌지만 신뢰성 있는 스케일링은 여전히 어려웠음.

마이크로서비스 패턴 나오면서 이야기가 좀 달라지는데 마이크로서비스의 특성 상 컨테이너화 하기가 쉽기 때문임. 이 컨테이너화에 더불어 쿠버네티스와 같이 각 컴포넌트를 감시하고, 배포 및 재시작 등을 해주는 컨테이너 오케스트레이션 툴들이 나옴. 거기에 구글, 아마존과 같은 회사들이 각자 플랫폼을 출시하고 오픈스택같은 오픈소스 플랫폼들도 나와 이전보다 훨씬 쉬워진 편

Cloud-native Foundation에서 말하는 정의는 다음과 같음

  1. 컨테이너화가 되어야 함. 어플리케이션의 각 파트가 모두 컨테이너로 패키징되어야 함.

  2. 컨테이너들은 리소스 효율화를 위해 능동적으로 스케쥴링되고 관리되어야함.

  3. 마이크로 서비스를 지향해야 함.

처음에 Heroku에서 2012년에 12 Factors(https://12factor.net/)라는걸 만들어냄.

  1. Codebase: 코드는 반드시 버전 컨트롤 시스템을 통해 관리되어야 함. 하나의 코드베이스는 하나의 앱과 1:1 관계가 성립해야 함. 버전이나 환경에 따라 하나의 코드베이스에 대해 배포는 여러개가 될 수 있음.

  2. Dependencies: 모든 디펜던시는 명시적으로 선언되어야 함. 또한 이러한 디펜던시들을 엄격하게 분리해서 매번 실행할 때마다 특정 디펜던시의 버전이 바뀌거나 하는 일들을 막아야 함.

  3. Configuration: 배포마다 달라질 수 있는 모든 것들은 코드에서 분리해서 별도의 configuration으로 관리해야 함. 이 설정값들을 각 그룹으로 나눠 정리하고 가능하다면 환경 변수에 저장하도록 해야 함.

  4. Backing Services: 백엔드 서비스들을 앱에 연결된 리소스로 취급해야 함. 필요에 따라 코드 수정 없이 이 리소스들을 자유롭게 전환할 수 있어야 함.

  5. Build, release, run: 코드베이스가 빌드, 릴리즈, 런타임 세 가지 단계를 엄격히 거쳐 배포되도록 해야 함. 빌드는 말 그대로 코드를 실행할 수 있게 빌드하는 것을 의미하고, 릴리즈는 이 빌드된 결과물과 하나의 configuration를 합쳐 즉시 실행가능한 상태로 만드는 것. 런타임은 특정 릴리즈를 선택하여 실행환경에서 돌아가도록 하는 것. 릴리즈는 항상 유니크한 아이디를 가져야함.

  6. Processes: 앱은 하나 이상의 stateless한 프로세스로 구성되어야 함. 여기서 프로세스라는 것은 앱의 각 기능을 구성하는 모듈들을 말하는 것. 프로세스 간에 어떤 데이터도 공유하면 안됨. 공유, 유지할 필요가 있는 모든 데이터들은 백엔드 서비스를 통해 저장되어야 함. 로컬에 생성, 저장된 데이터들은 항상 없어질 수 있다고 간주해야 함.

  7. Port binding: 앱은 포트 바인딩을 통해 외부에 노출되어야 함.

  8. Concurrency: 프로세스 모델을 통해 확장되어야 함. 기능 별로 프로세스를 쪼개서 앱을 구성했을 때 쉽게 수평 확장할 수 있음. 특정 프로세스가 지나치게 커지면 수평 확장에 어려움이 생길 수 있음.

  9. Disposability: 프로세스는 가급적 빠르게 시작할 수 있어야하고 graceful shutdown을 지원해야 함. 이를 통해 쉽게 프로세스를 늘리고 줄일 수 있게 되면서 안정성이 극대화됨. 단, 급작스럽게 프로세스가 죽더라도 거기에 대한 대비는 되어 있어야 함.

  10. Dev/prod parity: 개발 환경과 운영 환경의 차이를 최소한으로 줄여야 함. 배포 간격을 줄이고, 개발과 운영을 같은 사람들이 할 수 있게 하고, 개발 환경과 운영 환경의 각 백엔드 시스템들도 동일하게 맞춰야 함.

  11. Logs: 로그를 이벤트 스트림으로 간주해야 함. 앱은 로그를 특정 파일로 저장하거나 관리하려하지 않고 버퍼링 없이 stdout 에 출력해야 함. 대신 스테이징, 운영 환경에서는 앱의 동작과 상관없이 이 로그 스트림을 필요에 따라 특정 백엔드 시스템으로 전달, 관리할 수 있음.

  12. Admin processes: 디버깅이나 배치작업같은 관리, 유지보수 작업들은 일회성 프로세스로 실행되어야 함. 이 일회성 프로세스들은 앱의 다른 일반 프로세스들과 동일한 환경에서 실행되어야 함.

Last updated