컨테이너는 Application을 포함하여 Application을 실행하기 위한 모든 요소를 포함하고 있는 하나의 격리된 프로세스이다.
컨테이너 자체가 어플리케이션의 실행환경을 담고 있기 때문에, 호스트 OS에 의존하지 않고 혼자 독립적으로 실행되는 프로세스인 것처럼 작동한다.
어플리케이션 별로 게스트 OS가 필요한 가상 머신과 달리 하나의 호스트 OS 위에서 작동하므로, 호스트 OS의 커널 하나를 공유하여 사용한다. (컨테이너 간 통신이 용이)
다만 컨테이너가 종료되면 내부 데이터가 소멸되므로, 필요시 별도 스토리지나 클라우드 등을 이용해 데이터를 저장한다.
가상 머신에서 Hypervisor가 독립된 환경을 구성해주는 것 처럼 컨테이너에서는 Container Engine을 통해 각각의 Application을 격리한다.
Container Engine의 가장 대표적인 소프트웨어 플랫폼이 바로 도커(Docker)이다.
동일한 개발환경을 사용하고, End2End 테스트가 쉽다는 등의 장점이 있다.
그러나 여러개의 서비스를 운영하는 단일 서버에서 서비스 하나의 장애가 서버 전체의 장애로 이어질 위험이 존재하며, 분산 시스템 운영이 어렵다는 단점이 있다.
각 서비스를 하나의 독립적인 서버로 구성하는 구조이다.
컨테이너를 통해 구현할 수 있다.
Monolithic Architecture의 단점을 보완할 수 있지만, 관리해야하는 서버의 수가 많다보니 이를 관리하는 것에 어려움이 있다.
이를 해결하기 위해 컨테이너화된 어플리케이션의 배포, 관리, 확장을 쉽게 자동화하여 관리해주는 시스템을 오케스트레이터라고 한다.
가장 대표적인 오케스트레이터로는 쿠버네티스(Kubernetes, k8s)가 있다.
도커는 오픈소스 컨테이너 엔진이다.
도커 허브라는 공개된 저장소를 제공하여 컨테이너 자료를 관리할 수 있다.
Dockerfile이라는 도구를 통해 Docker Image라는 이미지를 생성하여 이를 바탕으로 컨테이너를 쉽게 생성 및 복제할 수 있다.
Dockerfile은 Docker Image를 생성하기 위해 필요한 과정을 문법에 따라 작성한 스크립트 파일이다.
특정 행동을 취해야하는 컨테이너(이미지)를 만들거나 특정한 실행환경이 필요할 때 명령어를 Dockerfile에 작성하는 것을 통해 자동화할 수 있다.
Dockerfile을 바탕으로 build
명령어를 실행해 도커 이미지를 생성할 수 있다.
도커 이미지의 파일 크기로 인해 공유가 어려울 경우 Dockerfile 형태로 배포하기도 한다.
서비스 운영에 필요한 프로그램, 소스코드, 라이브러리를 모두 묶어 놓은 형태의 이미지이다.
도커 이미지로 run
명령어를 실행하면 쉽게 원하는 만큼 컨테이너를 생성할 수 있다.
도커 허브는 도커 이미지를 저장하고 쉽게 불러올 수 있는 저장소이다.
Public 저장소는 url을 통해 쉽게 접근이 가능해 필요한 어플리케이션을 설치할 수 있다.
도커 허브의 도커 이미지를 지칭하는 방법은 다음과 같다.
<Namespace>/<ImageName>:<Tag>
docker.io/library/nginx:latest
docker.io/library
: 도커 허브의 public 저장소로 생략이 가능하다. pirvate 저장소를 이용할 경우 저장소 주소를 명시해야한다.nginx
: 컨테이너화할 어플리케이션 이름을 지칭한다.latest
: 어플리케이션의 버전이며, 생략이 가능하다. 생략할 경우 기본값은 latest
이다.build
: Dockerfile을 바탕으로 이미지를 생성run
: 이미지를 바탕으로 컨테이너 생성 및 실행pull
: 저장소에서 이미지 다운로드push
: 이미지를 저장소로 전송그외 다양한 명령어가 있으니 도커를 사용할 때 알아두면 좋을 것이다.
컨테이너형 어플리케이션의 배포, 확장, 관리를 자동화해주는 오픈 소스 관리 시스템이다.
배포되어 작동중인 쿠버네티스를 클러스터라고 부르며, 쿠버네티스 환경을 가져올때는 항상 클러스트 형태로 가져온다.
클러스터는 Master Node(control plane)와 Worker Node(node, data plane)로 구성된다.
https://www.redhat.com/ko/topics/containers/kubernetes-architecture
마스터 노드 또는 컨트롤 플레인은 총 4개의 구성 요소로 나눌 수 있다.
사용자나 다른 구성요소가 전송한 요청·명령을 처리하는 API와 같은 역할을 한다.
요청 및 명령이 유효한지 검사하고, 처리를 위해 올바른 대상에 전송하는 역할을 한다.
스케줄러는 pod(container) 생성 명령이 있을 경우 어떤 노드에 배포할 것인지를 결정한다.
pod의 리소스 요구사항, 현재 노드들의 정보 등을 고려하여 결정한다.
pod를 관리하는 컨트롤러를 생성 및 배포한다.
컨트롤러는 pod의 자동화 관리를 수행하며, 클러스터의 상태를 조절한다.
클러스터의 모든 구성 데이터를 저장하는 저장소이다.
데이터는 장애 발생 시 장애 복구에 이용되며, scheduler가 pod 생성 시 참조하는 등 매우 중요한 역할을 한다. (pod에 대해서는 조금 있다 다뤄보자)
높은 시스템 안정성을 위해서는 etcd 고가용성을 보장하는 것이 중요하다. (이중화, 주기적 백업 등)
워커 노드 또는 노드는 말 그대로 실제 컨테이너가 동작시키며 일을 하는 노드이다.
컨테이너 구조에서 Container engine의 역할을 한다.
pod 내부의 컨테이너를 실행하고, 컨테이너 이미지를 관리하는 역할을 한다.
쿠버네티스는 도커, CRI-O, containerd, rkt 등의 다양한 컨테이너 런타임을 지원한다.
container runtime에서 실행되고 있는 컨테이너의 상태를 주기적으로 점검하여 api server에 전송한다.
api server로부터 전송된 명령을 필요한 다른 구성 요소에 전달한다.
워커 노드별로 한 개씩 존재하며, 각 노드간의 통신 및 외부의 네트워크 통신을 처리한다.
사실 쿠버네트스의 배포 형태를 결정하고, 설치 도구를 설정하는 등 복잡한 과정이 필요하지만 필요한 개념만 설명하면 다음과 같다.