이러한 문제로
모놀리스 애플리케이션을 마이크로 서비스라는 독립적으로 배포할 수 있는 작은 구성 요소로 분할했다.
마이크로 서비스 아키텍쳐의 구성 요소는 독립적인 방식으로 개발된다.
각 구성 요소를 개발하는 별도의 팀이 있는 것이 일반적인데
각각의 개발자가 자신의 노트북으로 애플리케이션은 개발 중인 상황을 떠올려보자.
각각의 어플리케이션은 서로 다른 라이브러리, 종속성 및 파일에 의존하고 있으며,
동시에 회사는 자체 설정과 지원 파일 세트에 준하여 표준화된 개발 및 프로덕션 환경을 갖추고 있다.
이때, 서버 환경을 재구축하는 부가적인 작업 없이 가능한 한 로컬에서 이러한 환경을 에뮬레이션하려고 한다. 그렇다면 이러한 환경 전체에서 애플리케이션이 작동되게 하고, 품질 검사를 통과하고, 큰 문제나 수정 없이 애플리케이션을 배포할 수 있을까?
동일한 호스트에 배포해야하는 구성 요소 수가 많을 수록 모든 종속성을 관리하기 매우 어려워진다.
개발, 배포하는 구성 요소의 수에 상관없이, 개발팀과 운영팀이 해결해야 하는 큰 문제가 있다.
애플리케이션을 실행하는 환경이 매번 다르다는 것이다.
개발자의 로컬 환경에서는 잘 운영되던 코드가
운영팀이 운영하는 프로덕션 환경에서는 오류가 생길 수도 있다.
프로덕션 환경에서만 나타나는 문제를 줄이기 위해
애플리케이션 개발과 프로덕션이 정확히 동일한 환경에서 실행돼
운영체제, 라이브러리, 시스템 구성, 네트워킹 환경 등 모든 것이 동일한 환경으로 만들어야 한다.
개발자와 시스템 관리자의 공통 목표
고객이 성공적으로 실행할 수 있는 애플리케이션을 제공하는 것
개발자는
새로운 기능을 만들고 사용자 경험 향상에 중요도를 둔다.
시스템 운영자는
개발자에게 우선순위가 낮은 시스템 보안, 사용률과 같은 측면에 중요도를 둔다.
앞서 언급한 문제 상황을
쿠버네티스가 어떻게 해결해주는지 살펴보자!🔍
[문제 상황 1] 마이크로 서비스의 단점! 에서
한 호스트에 마이크로 서비스 애플리케이션을 개발한다고 가정할 때,
구성 요소의 구성(라이브러리 버전 등)은 다를 수 있다는 종속성 차이에 대해 언급했다.
이에 대한 답은 바로 '컨테이너'를 사용하는 것이다.
애플리케이션을 실행하는 컨테이너는 각각의 필수 라이브러리, 종속 요소와 파일을 사용하므로
문제없이 원활하게 애플리케이션을 프로덕션으로 진행할 수 있다.
뿐만 아니라 이식성, 구성 가능성, 격리가 필요한 경우 리눅스 컨테이너를 다양한 문제에 적용할 수 있다.
컨테이너는 동일한 호스트 시스템에서
동시에 서로 다른 환경을 만들어주어 가상머신과 유사하게 격리한다.
하지만 가상머신보다 오버헤드가 훨씬 적은 기술이다.
가상머신 | 컨테이너 | |
---|---|---|
주요 차이점 | 단일 하드웨어 시스템에서 여러 운영 체제가 동시에 실행될 수 있도록 한다. | 호스트 OS에서 실행되는 커널을 공유하고, 동일한 커널에서 시스템 콜을 수행한다. |
동일한 하드웨어에서 실행할 수 있는 구성요소 양 비교 | 적다. 구성요소 프로세스 뿐만 아니라 시스템 프로세스를 실행하기 때문에 추가 컴퓨팅 리소스가 필요하기 때문이다. | 많다. 컨테이너는 모두 동일한 OS에서 실행되기 때문에 오버헤드가 낮기 때문이다. |
격리 수준 비교 | 가상머신은 자체 리눅스 커널을 실행하기 때문에 호스트와 완전한 격리를 제공한다. | 컨테이너는 동일한 OS의 커널을 호출함으로 완전한 격리를 제공하지 않는다. 따라서 보안 위험이 발생할 가능성이 있다. |
컨테이너는 동일한 호스트의 OS를 공유하고 있는데, 어떤 매커니즘으로 격리를 제공하고 있을까?
각 프로세스가 시스템(파일, 프로세스, 네트워크 인터페이스, 호스트 이름 등)에 대한 독립적인 뷰만 볼 수 있도록 한다.
현재 리눅스 커널에서는 다음 6가지 namespace를 지원하고 있다:
기본적으로 리눅스 시스템에 하나의 네임스페이스가 있다.
그러나 추가 네임 스페이스를 생성하고 구성할 수 있다.
프로세스를 실행할 때 네임스페이스 중 하나에서 프로세스를 실행한다.
(프로세스는 하나의 네임스페이스에만 속하는 것이 아니라 여러 네임스페이스에 속할 수도 있다.)
프로세스가 사용할 수 있는 리소스의 양을 제한하게 해주는 리눅스의 기능이다.
cgroups는 다음 리소스를 제어할 수 있다:
/dev/
)프로세스는 설정된 양 이상의 리소스를 사용할 수 없다.
이런 방식으로 프로세스는 다른 프로세스 용으로 설정된(예약해 놓은) 리소스를 사용할 수 없으며
이는 프로세스가 별도의 시스템에서 실행될 때와 비슷하다.
도커는 애플리케이션을 패키징, 배포, 실행하기 위한 플랫폼이다.
애플리케이션에 필요한 전체 환경을 패키지화 하여,
중앙 저장소로 전송할 수 있으며,
도커를 실행하는 모든 컴퓨터에서 사용할 수 있다.
이러한 도커의 세가지 주요 개념은 다음과 같다.
쿠버네티스를 이용하면
개발자는 특정 인프라 관련 서비스를 애플리케이션에 구현하지 않아도 된다.
따라서 실제 기능을 개발하는 것에만 집중할 수 있다.
또한 시스템 관리자는 쿠버네티스가 애플리케이션을 재배치하고 조합함으로 리소스를 훨씬 더 효율적으로 이용할 수 있게 된다.
뿐만아니라 고장 난 노드를 자동으로 처리하도록 함으로써 따라서 운영팀은 더 편하게 잠을 잘 수 있다...ㅎ
우선 쿠버네티스의 핵심적인 구조와 워크 플로우에 대해서만 정리했다.
쿠버네티스는 컨테이너화된 애플리케이션을 쉽게 배포하고 관리할 수 있게 해주는 소프트웨어 시스템이다.
다음 그림은 쿠버네티스의 구조이다.
크게 마스터 노드와 워커노드로 구성된다.
큰 워크 플로우는
개발자가 애플리케이션 매니페스트를 작성
➡️ 매니페스트를 마스터 노드에 배포
➡️ 쿠버네티는 해당 애플리케이션을 워커 노드 클러스터에 배포한다.
구조를 더 자세히 살펴 보자.
이 컨트롤 플레인의 구성요소는 클러 스터 상태를 유지하고 제어하지만 애플리케이션을 실행시키지는 않는다.
워커 노드는 컨테이너화 된 애플리케이션을 실행하는 시스템이다.
출처
- 책 - Kubernetes in action
- https://velog.io/@cclare/%EB%AA%A8%EB%86%80%EB%A6%AC%EC%8B%9D-%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4
- https://kubernetes.io/ko/docs/concepts/overview/what-is-kubernetes/
- https://www.redhat.com/ko/topics/containers/whats-a-linux-container
- https://tech.ssut.me/what-even-is-a-container/
- https://bcho.tistory.com/1256