'15단계로 배우는 도커와 쿠버네티스' 기반으로 내용 정리하였습니다.
- 도커란?
docker는 컨테이너 기반 가상화 도구이다.
도커는 OS 전체를 가상화하지 않고 컨테이너라는 리눅스 커널 레벨에서 제공하는 격리된 가상 공간을 사용한다.
게스트 OS를 설치하지 않기 때문에 (하이퍼바이저가 필요 없음!) 호스트와 속도 차이도 거의 없으며 기존의 VM에 비해서는 월등한 속도로 동작한다.
2.1 컨테이너를 사용하는 이유
인프라의 사용률 향상
빠른 가동 시간
불변 실행 환경(Immutable Infrastructure)
2.2 가상 서버와 컨테이너의 차이점
가상 서버는 가상화 소프트웨어를 사용하여 하드웨어를 공유하는 형태로, 마치 한 대의 전용 서버가 있는 것처럼 이용할 수 있게 해준다. 이러한 가상화 소프트웨어를 하이퍼바이저(Hypervisor)라 부르며, Vmware, Xen, KVM, 버추얼박스, Hyper-V와 같이 상용 제품부터 오픈 소스까지 다양한 제품들이 있다.
한편, 컨테이너는 하나의 리눅스 프로세스가 마치 전용 서버에서 동작하고 있는 것 같은 분리 상태를 만들어 낸다. 이는 리눅스 커널의 네임스페이스와 컨트롤 그룹이라는 기술을 기반으로 한다.
[ 컨테이너와 가상 서버 비교 ]
컨테이너는 하이퍼바이저상의 가상 서버에서도 사용할 수 있어 퍼블릭 클라우드의 가상 서버나 온프레미스의 OpenStack 위에서 많이 활용된다.
2.3 도커의 아키텍처
Docker daemon(dockerd)
도커 데몬은 클라이언트의 명령을 REST API로 받아 컨테이너, 이미지, 네트워크 그리고 볼륨을 관리한다. (여기서 볼륨은 컨테이너에서 생성된 데이터들을 의미한다)
Docker client
위에서 언급했든 dockerd에 명령을 전달하기 위한 수단이다.
docker명령어를 사용하면 Docker API가 REST API형식으로 dockerd의 소켓에 전달된다.
Image
도커 컨테이너를 만들기 위한 읽기 전용 템플릿이다.
이미지는 직접 제작, Registry에서 다운로드 그리고 기존 이미지를 확장하여 사용할 수 있다.
이미지는 이미지를 만들기 위한 커맨드가 집합된 Dockerfile을 통해서 만들어질 수 있으며 이미지는 레이어 단위로 만들어지게 되는데 만약 Dockerfile에 어떤 부분을 수정했다면 해당 부분의 레이어만 교체하므로 재생성이 가볍게 되어 있는 구조이다.
Container
컨테이너는 이미지의 instance이며 독립적으로 프로세스를 실행할 수 있는 공간이다.
즉, 리눅스의 네임스페이스나 컨트롤 그룹을 통해 다른 프로세스들과 완전히 분리되어 실행되는 프로세스인 것이다. 하지만 컨테이너는 정지된 상태로도 관리되기 때문에 보다 명확하게 표현하자면 '실행 가능한 이미지의 인스턴스' 라고 할 수 있다.
registry
도커 레지스트리는 컨테이너의 이미지가 보관되는 곳이다.
레지스트리와 리포지터리는 이름이 비슷하여 헷갈리기 쉽다.
레지스트리는 리포지터리를 여러 개 가지는 보관 서비스다.
그리고 리포지터리는 하나의 이미지에 대해 태그를 사용하여 다양한 출시 버전을 함께 보관하는 곳이다.
[ 레지스트리 종류 ]
누구나 이용할 수 있도록 공개된 레지스트리다. 도커 허브의 경우, 무료로 공개 리포지터리를 사용할 수 있는 반면, 비공개 리포지터리를 사용하기 위해서는 돈을 내야한다.
예 : Docker Hub
퍼블릭 클라우드가 제공하는 레지스트리 서비스다. 접근 가능한 계정을 제한하여 비공개로 운영할 수 있다.
물론 인터넷에 공개하는 것도 가능하다.
예 : Amazon Elastic Container Registry / Azure Container Registry ..
회사나 팀 전용으로 레지스트리를 구축하여 운영하는 경우에 해당한다.
2.4 레지스트리와 쿠버네티스의 관계
쿠버네티스에서도 레지스트리에서 이미지를 다운받아 컨테이너를 실행한다.
2.5 도커와 쿠버네티스의 연동
쿠버네티스는 도커를 컨테이너의 런타임 환경으로 사용한다. 쿠버네티스를 설치할 때 제일 먼저 도커를 설치해야하는 것도 이 때문이다.
도커 데몬 프로세스인 dockered 와 연동하여 동작하는 containerd 프로세스는 원래 도커 기업이 개발하였다. 이후 CNCF에 기증되어 containerd는 다양한 플랫폼 위에서 동작하는 업계 표준 코어 컨테이너 런타임으로 간결하고 높은 이식성을 목표로 개발되었다.
containerd를 통해 이미지 보관 및 전송, 컨테이너 실행, 볼륨과 네트워크 연결ㄷ과 같은 컨테이너의 라이프 사이클을 호스트에서 완전히 관리할 수 있게 되었다.
containerd 버전 1.1 부터는 CRI(container runtime interface)에 대응하여 네이티브 kubelet도 연동할 수 있게 되었다.
- Dockershim
Dockershim는 Docker과 Kubernetes API를 잇는 다리 역할을 한다.
Kubernetes가 만들어진 당시에는 Docker 가 가장 범용적으로 사용되고 있었기 때문에 Dockershim을 폭넓게 사용한다.
containerd 런타임
containerd 는 Kubernetes와 같이 CNCF 프로젝트 하나로 CRI 를 준수하면서 Docker 의 다양한 기능을 제공합니다. 런타임은 Docker 동작에 필요한 기능을 제공한다.
지금까지 Kubernetes에서 런타임에 Docker를 사용해 온 이용자들에게는 큰 변화 없이 도커에서 전환 할 수 있었다.
하지만, 쿠버네티스 : KUBERNETES 1.20 부터 DOCKER 사용을 중단한다.
[쿠버네티스 표준 컨테이너 런타임]
Kubernetes 는 kubectl 명령을 사용하여 Pod를 만든다.
이때 Kubernetes 내부에서는 etcd에 Pod를 만들기 위한 정보를 기록한다.
이후 스케줄러 등의 처리를 거쳐 특정 노드의 kubelet 에서 새로 생성할 Pod 정보를 가져온다.
kubelet는 가져온 Pod 정보를 CRI 통해 하이 레벨 런타임에 전달한다.
CRI 런타임은 그것을 JSON 구성 파일로 변환한다.
마지막으로 OCI 에서 로우 레벨 런타임을 실행하여 컨테이너를 만든다.
이 때 Linux 커널과의 커뮤니케이션은 OCI 런타임이 맡으며, CRI 런타임은 관리를 위한 인터페이스 역할을 한다.
컨테이너 내의 실행파일은 리눅스의 표준 규격(LBS)와 리눅스 ABI에 의해 실행이 보증된다.
그리고 컨테이너는 OCI가 정하는 업계 표준을 지킴으로써 이식성이 확보된다.