컨테이너를 구글에 검색했을 때 가장 많이 나오는 내용은 역시 Docker와 쿠버네티스(이하 K8s)입니다.
Docker와 K8s의 역할은 다릅니다. Docker는 컨테이너를 띄워주는 역할이고, K8s는 그 띄워진 컨테이너의 안정적인 운영을 위해 여러가지 기능들을 추가한 container orchestration입니다.
(조금 의미가 없는 말입니다. Docker는 Docker swam을 이용해 K8s를 대체할 수 있고, K8s에서도 알아서 컨테이너를 띄울 수 있기 때문입니다.)
그리고 여기서 컨테이너를 띄워주는 역할을 할 수 있는 도구 즉, 컨테이너 런타임은 여러가지가 있습니다. docker, CRI-O, containerd 등이 있는데요.
최근 K8s가 컨테이너 런타임으로서 더 이상 docker를 지원하지 않는다고 발표하였습니다. 더 이상 도커를 지원하지 않는 이유가 무엇인지를 알아보고자 합니다.
1. VM과 컨테이너
서버가 단순히 한대라면 그 서버안에 Web, DB, cache, MQ 등 여러가지 프로세스를 띄워야하는 문제가 생깁니다. 이를 위해 VM 기술이 만들어졌고, 저희는 주로 VMware를 이용해 하나의 물리서버의 자원을 쪼개 여러 대의 VM을 생성하여 서비스를 운영하고 있습니다.
이런 VM 기술도 불편함은 있었습니다. 여전히 Hypervisor는 무거웠고 새로운 OS를 설치해야 하고, 인증도 다시 받아야 하고, 초기 셋팅도 다시 해줘야하는 작업들이 계속 필요했습니다.
또 하나의 서버에 2개 이상의 프로세스를 띄울 때, 이 프로세스들끼리 서로 영향을 주지 않고 독립적으로 구성되야 하는 필요도 있었습니다. 그리고 이런 부분들을 해결해준 것이 컨테이너 기술입니다.
컨테이너 기술하면 떠오르는 것은 docker입니다. 그런데 사실 docker보다도 더 대단한 건 리눅스 OS라고 보는 사람도 있습니다.
컨테이너 자체에 대한 기술은 docker가 만들어 낸 것이 아닌 리눅스에서 제공하는 cgroup과 namespace의 기술을 잘 조합해 사용하기 쉽게 커맨드로 만든 것이기 때문입니다.
(다시 말하면 docker를 설치하지 않고 cgroup과 namespace를 이용해 프로세스를 격리시킬 수 있다는 뜻입니다.)
어쨌든 컨테이너 생태계가 구축이 되었고, 이 컨테이너를 더 안정적으로 쓰고자 container orchestration으로 K8s가 만들어졌습니다.
그리고 오랫동안 Docker+Kubernetes 조합으로 컨테이너 환경을 구성해왔는데요, 최근 쿠버네티스에서 docker를 더 이상 컨테이너 런타임으로 지원하지 않겠다는 발표가 있었습니다.
2. 왜 쿠버네티스는 컨테이너 런타임으로서 Docker를 더 이상 지원하지 않을까?
쿠버네티스가 Docker를 더 이상 지원하지 않는다는 말은, Docker로 띄운 컨테이너들이 쿠버네티스의 관리를 받지 못한다 라는 뜻 보다는,
Docker와 연결되는 불필요한 과정을 거치지 않고, 쿠버네티스만으로 컨테이너와 관련된 모든 내용들을 컨트롤 한다는 뜻입니다.
(쿠버네티스로 컨테이너를 띄우고, Auto scaling, 리소스 관리, Configmap, 네트워크 관리 기술 등 컨테이너 관련된 모든 것을 한다고 이해하면 될 것 같습니다.)
(1) 그렇다면 지원 중단 이후 어떤 문제점이 생길까?
사실 쿠버네티스가 Docker 지원을 중단했다고 해서 Docker+K8s 조합으로 사용하고 있는 사용자들에게 엄청난 패닉을 주는 것은 아닙니다.
K8s에서 제공하는 컨테이너 런타임은 CRI-O, containerd이 있는데 docker는 containerd를 기반으로 컨테이너를 실행하기 때문입니다.
Docker로 빌드한 이미지들 역시 OCI(Open Container Initiative) 이미지 스펙을 기반으로 하고 있기 때문에 K8s에서 다른 컨테이너 런타임을 사용하더라도 이미지를 그대로 사용할 수 있습니다.
(2) 그럼 쿠버네티스는 Docker 지원을 왜 중단하는 것일까?
“컨테이너를 실행/관리하는 구조를 쿠버네티스가 직접할 수 있도록 하기 위함” 이라고 이해하면 빠를 것 같습니다.
그림처럼 기존 K8s는 docker를 컨테이너 런타임으로 사용하기 위해 dockershim과 같은 도구를 kubelet에 구현하여 Docker engine의 인터페이스 변경에 맞게 수정해 사용했습니다.
하지만 이러한 방식은 kubelet에 대한 깊은 이해가 필요할 뿐 아니라, 컨테이너 런타임의 유지보수를 각각 관리해주어야 하는 어려움이 존재합니다.
(Docker 버전이 새로 나올 때마다 K8s가 영향을 받고 대응을 해주어야 한다는 뜻)
결국 K8s에서는 이러한 어려움을 해결하기 위해 컨테이너 런타임과 kubelet이 쉽게 통합될 수 있도록 정의한 것이 CRI(Container Runtime Interface)이고, kubelet이 새롭게 구현된 인터페이스를 통해 containerd, CRI-O와 통신하여 컨테이너를 생성, 종료, 관리를 직접할 수 있게 변경한 것입니다.
그러니까 K8s는 굳이 docker를 사용할 필요가 없었다는 뜻 입니다.
심지어 docker를 사용하는 것과 containerd를 사용하는 것은 같은 container를 사용하는 것이나 다름없지만 pod를 실행하는 데 있어서 latency, CPU, MEM의 성능차이도 존재한다고 합니다.
3. 정리
- K8s는 kubelet을 통해 컨테이너 런타임(containerd, CRI-O)과 직접 통신하여 컨테이너를 실행할 수 있도록 변경했다.
- 이렇게 되면서 굳이 docker를 쓸 이유가 없어졌고, 이로 인해 docker 지원을 중단했다
- Docker는 이미 containerd를 컨테이너 런타임으로 사용하고 있었고 Docker로 빌드한 이미지도 OCI 표준에 만족하기 때문에 Docker+K8s로 사용하는 개발자 입장에서는 크게 달라지는 것이 없다.
- 다만, 컨테이너를 운영하는 입장에서는 Docker로 한 번에 모든 것을 제어할 수 있었던 예전과는 달리 이젠 runc, containerd, ctr 등 낯선 라이브러리들과 익숙해져야 한다.
4. 참조
https://computingforgeeks.com/docker-vs-cri-o-vs-containerd/
https://kubernetes.io/blog/2020/12/02/dont-panic-kubernetes-and-docker/
https://kubernetes.io/blog/2018/05/24/kubernetes-containerd-integration-goes-ga/#performance
'Operating System' 카테고리의 다른 글
SSL 통신과 인증서 검증 (0) | 2024.08.21 |
---|---|
Max user processes & Open files (0) | 2022.10.18 |
[Linux] 메모리 재할당 (0) | 2022.01.10 |
[Linux] TCP KeepAlive에 대한 고찰 (0) | 2021.12.13 |