모든 강의 이미지 출처는 [인프런] 쿠버네티스 어나더 클래스(지상편) - Spring 1,2 입니다.
주로 사용하는 리눅스에는 debian 계열과 redhat 계열이 있다.
ubuntu는 debian 계열 배포판으로 무료로 사용할 수 있고 사용자 편의기능이 많이 포함되어 있어 시장에서 많은 점유율을 차지하고 있다.
redhat 계열로는 fedora, Redhat Enterprise Linux(RHEL), CentOS 등이 있으며 IBM 인수되기 전, 후로 배포 과정이 나뉜다.
Redhat Linux 배포 과정 (IBM 인수 전, 1995 ~ 2019)
Redhat Linux 배포 과정 (IBM 인수 후, 2019 ~)
Redhat 계열의 무료 배포판으로 시장의 많은 점유율을 차지 했던 CentOS가 2024년 6월부로 지원이 종료되며 CentOS를 사용하던 사용자들은 다른 대안이 필요했다.
대안 중 하나인 Rocky Linux는 CentOS 창립자 중 한 분인 Gregory M. Kurtzer가 만든 무료 배포판이다.
강의에서는 CentOS의 대안으로 Rocky Linux를 사용하며, 실습을 할 때 Redhat 계열의 OS를 사용하고 있음을 인지하면 된다!
컨테이너 기반이 되는 Linux 격리 기술은 다음과 같다.
위와 같은 격리 기술을 바탕으로 최초 Container인 LXC(Linux Container)가 탄생했고, LXC를 기반으로 docker가 만들어졌다.
LXC와 docker의 차이점을 먼저 보자면, LXC는 Low-Level, docker는 High-Level의 Container Runtime 기술로 docker가 좀 더 사용자 친화적인 기술이다.
또한,기술의 목적에도 차이가 있는데 LXC는 VM(Virtual Machine)과 같이 운영체제를 컨테이너 가상화로 나누기 위한 목적이고 docker는 애플리케이션을 독립적으로 컨테이너에서 띄우기 위한 목적을 갖고 있다.
High-Level 컨테이너 런타임인 docker의 구성을 자세히 보자면 다음과 같다.
즉, docker가 컨테이너를 만드는 것이 아닌 docker-engine에 구성된 containerd가 컨테이너를 만드는 역할을 수행한다.
docker에서 컨테이너 생성 기능이 분리된 프로젝트인 containerd는 현재 CNCF의 Graudated Project가 되었다.
CNCF Graduated and Incubating Projects
docker에는 보안 이슈가 있었는데, root 권한으로 컨테이너를 설치/사용하기 때문이었다. 이를 개선한 컨테이너 런타임이 rkt이다. 최근 docker도 보안 이슈를 대비해 rootless 기능을 선보이기도 했다.
여기서 rkt는 컨테이너 전용 Linux 배포판인 CoreOS의 대표 컨테이너 런타임였다. 그러나 CoreOS가 Redhat으로 인수가 되면서 Redhat에서 만든 Container인 cri-o가 rkt를 대신하게 되어 입지가 줄었다.
기존 Container만 사용할 때는 docker가 컨테이너를 생성해주었지만, 앱 버전 업그레이드가 필요할 때, 시스템 담당자가 신규 앱 전환 과정을 수기로 진행해야 했다.
그러나 Container Orchestration가 등장하며, 위와 같은 배포 과정을 담당자의 개입없이 자동화하게 되었고 다양한 Container Orchestration 기술들이 나오기 시작했다.
그 중 대표적으로 가장 널리 사용되는 쿠버네티스가 있고 Docker Swarm, Nomad, Apache Mesos 등이 있다.
또한, 쿠버네티스를 기반으로 배포, 모니터링, 로깅 등 편한 기능을 제공하는 기업 관리형 솔루션들도 생겨났다.
컨테이너를 생성만 하는 것이 아닌, 관리의 영역까지 자동화 되며 쿠버네티스는 많은 기업에서 사용하게 되었고, 점차 쿠버네티스와의 호환성이 컨테이너를 선택하는 결정적인 요소가 되었다.
쿠버네티스를 통해 Pod가 생성되는 과정을 잠시 알아보자.
kube-apiserver
가 Pod 생성 API 를 받아 kubelet
에 컨테이너 생성 명령을 전달한다. kubelet
은 Container Runtime에 컨테이너 생성 명령을 전달한다.kubelet이 Container Runtime에 컨테이너 생성 명령을 전달하는 과정에서 API 호출이 이루어지는데, 기존에는 Container Runtime 유형에 따른 분기처리가 이루어졌었다.
그러나, 유형이 늘어남에 따라 분기처리를 매번 추가할 수 없었기에 쿠버네티스 v1.5 부터는 CRI(Contaienr Runtime Interface) 인터페이스를 통해 호출하도록 변경되었다.
해당 인터페이스를 기반으로 Container Runtime마다 구현체를 생성하여 구현체를 쿠버네티스 프로젝트에 기여하는 형태로 전환되었고 Container Runtime 유형별로 각각 아래와 같은 구현체를 갖게 되었다.
따라서, 쿠버네티스 1.24 버전부터는 쿠버네티스 프로젝트가 구현체를 갖지 않고 kubelet이 CRI를 통해 Container Runtime을 바로 호출할 수 있게 구조가 변경되었다. 이러한 변화에 맞게 각 Container Runtime 은 아래와 같이 변경되었다.
Container Runtime으로써 보편적으로 사용되던 docker가 쿠버네티스에서 빠진다는 이야기가 돌면서 containerd와 같은 다른 컨테이너로 전환이 고려되었다. (결론적으로는 사실이 아니었다.)
기존에 docker로 생성된 컨테이너 이미지들을 conatinerd에서 활용할 수 있어야 했는데 이처럼 동일한 이미지를 다른 Container Runtime에서 사용할 수 있도록 컨테이너 표준 규약 관리를 위한 단체(OCI, Open Container Initative)가 생성되고 표준 규약을 맺게 되었다.
이 규약에 따르는 Container Runtime 간에는 컨테이너 이미지를 서로 활용할 수 있었으며, OCI 지원을 위해 docker의 Low-Level Container Runtime이 libcontainer에서 runC로 변경되었다.