[워밍업 클럽: 쿠버네티스] #1. 컨테이너 한방정리 (1주차)
강의 수강 일자 : 25.05.27 (화)블로그 복습 일자(수정) : 25.05.27 (화), 25.05.28 (수) 인프런 워밍업 클럽을 통해 데브옵스 소프트웨어 중 하나인 쿠버네티스를 배울 수 있는 기회를 우연히 접하게 되었고,어느 새 첫 강의를 듣는 시간이 다가왔다! 나는 데브옵스에 대해 제대로 배워본 적도 없고, 설치나 실습해본 경험도 없다!아예 제로 베이스인 상태로 이 강의를 수강했고, 커리큘럼대로 4주간 꾸준히 진행한다면 이전과는 데브옵스에 대해 자신감있는 모습으로 달라질 미래를 꿈꾸며 그 첫 발걸음을 내딛었다! 가볍게 오늘 배운 이론 지식을 정리해보았다. 컨테이너 (Container)인트로 강의에서 나온 컨테이너의 정의이다. 전체만 봤을 땐 뭔가 어렵고 이해가 잘 안갔지만... 😅문장을 끊어서 차분히 분석하니 다음과 같이 정리해볼 수 있었다.OS 저장공간 일부를 분리해 컨테이너가 사용할 수 있는 공간을 준다.컨테이너는 이 공간에서 기존 OS의 영향을 받지 않는 독립된 프로세스를 실행한다.3. 이러한 독립된 공간은 하드웨어 아키텍쳐가 같은 (CPU, OS 동일) 다른 컴퓨터에서도 동일하게 동작하는 걸 보장한다. 강의 핵심은 컨테이너를 중심으로 여러 배경 흐름을 이야기하고 있다. 크게 기술적인 흐름 (각 영역 별로 어떤 소프트웨어들이 출시 되었고, 점유율의 변화가 어떻게 되는지),컨테이너 런타임의 흐름 (쿠버네티스의 kubelet의 버전 변화를 통해 컨테이너 런타임들이 어떤 변화가 생겼는지) 으로 구분됨.기술 흐름으로 쿠버네티스 배경 이해하기쿠버네티스를 이해하려면 위 그림의 6가지 카테고리를 이해해야 하는데, 차분히 흐름을 따라가보자. Linux OS쿠버네티스를 사용하기 위해선 설치해야 할 OS를 선정해야 하고, 그 중 하나가 리눅스 OS이다.리눅스 OS는 많은 배포판들이 있지만, 우리가 알아야 할 계열로는 1. Debian 계열, 2. Redhat 계열 두 가지다.무료판인 Debian 계열은 Ubuntu를 OS로 사용을 많이 하고, Redhat 계열은 예전엔 CentOS를 사용했지만 시장에서 종료가 되었기 때문에 😂현재로는 1. RHEL 로 전환하여 유료로 사용하는 방법 2. CentOS를 그대로 기술지원을 해주는 기업의 것을 사용하는 방법3. 타 OS로 마이그레이션 스크립트 제공 (다른 OS로 넘어가기)4. RHEL의 복제판인 Rocky, Alma Linux를 사용하기 (무료!)다양한 방법이 있지만, 이번 강의는 Rocky Linux를 OS로 채택하는 방법으로 했습니다. 그래서 Redhat계열로 설치 가이드를 따라가면 됩니다! ContainerLinux OS의 꾸준한 발전으로 격리 기술이 발전되었고, App을 독립적으로 돌릴 수 있게 됐습니다 (컨테이너 핵심개념).chroot(사용자격리, 파일격리, 네트워크 격리), cgroup(자원 격리 (cpu, memory)), namespace (프로세스 격리)위 주요 기술들을 집약하여 만든 Linux Container(LXC) , 최초의 컨테이너이다.LXC를 기반으로 만든것이 우리가 익히 들어본 Docker이다. 이 소프트웨어를 통해 누구나 쉽게 컨테이너를 설치할 수 있게 되었다 (편의성 GOAT). 이 외에도 다른 컨테이너를 보자면,rkt (docker의 보안 취약점을 강화한 컨테이너) , containerd (도커에서 컨테이너 생성만을 분리한 컨테이너), crio-o (redhat에서 만든 컨테이너) 가 있습니다. Container 와 Container Orchestration 비교기존에는 컨테이너만 단독 운영을 했습니다(좌측 그림). App의 버전을 바꿀 때마다 바뀐 App이 컨테이너에서 기동하는지 확인하려면 컨테이너 조회를 사용자가 일일이 확인해야 했고, 기동이 된 걸 확인한 후에 기존 버전으로 흘러갔던 사용자 트래픽을 네트워크 수정으로 바뀐 App으로 전환을 하고, 기존 App를 삭제하는 과정을 거쳐야 하고, 이 과정을 사용자가 직접 조작해야 했습니다.반면 Orchestration을 통해 App의 버전을 바꾸게 되면(우측 그림),사용자가 App의 버전을 바꾸면 쿠버네티스가 알아서 변경된 App의 컨테이너를 생성하고, 해당 컨테이너 기동이 완료되면 네트워크를 수정해 트래픽을 전환해주고, 기존 컨테이너 삭제를 쿠버네티스가 자동화로 처리합니다.App 버전을 바꾸는데 기존에는 컨테이너 생성과 트래픽 수정, 컨테이너 삭제를 사용자가 해야 했지만,App 버전 변경에 대한 명령을 쿠버네티스에 전달하면 앞에서 수행했던 과정들을 쿠버네티스가 알아서 해주는 편의성이 생겼습니다.정리하자면, Container Orchestration의 역할은 다음과 같습니다.1. App을 컨테이너에 담아서 배포한다.2. 시스템 운영 노하우를 많이 가지고 있다. (기존 트래픽 수정, 기존 컨테이너 삭제 등의 자동화)이러한 Container Orchestration에는 다양한 소프트웨어가 있지만(쿠버네티스, 노마드, 도커스왐 등),점유율로는 쿠버네티스가 넘사벽이게 되었고, 우리는 일단 쿠버네티스를 사용하면 됩니다!(굳) 이렇게 오케스트레이션에 쿠버네티스가 1황이 되면서, 이제는 컨테이너들이 쿠버네티스에 호환성이 좋아야 컨테이너를 선택하게 되었습니다. 정리:쿠버네티스는 현재 표준을 넘어 여러 분야에서 활용되고 있다.쿠버네티스는 컨테이너를 더 쉽게 사용할 수 있게 해준다(자동화).컨테이너는 쿠버네티스와의 인터페이스가 중요하다. 컨테이너 런타임으로 컨테이너를 이해하기컨테이너의 커널에는 컨테이너의 핵심 기술이 된 chroot, cgroup, namespace가 커널 레벨의 기술로 되어있고,컨테이너 런타임은 High level, Low level로 나뉘어 사용자 친화성에 따라 구분을 하고 있다.커널 레벨 기술로 만든 LXC는 Low level 컨테이너 런타임으로 되어있고, 도커가 LXC를 기반으로 libcontainer라는 Low level 컨테이너 런타임을 만들었다.libcontainer를 이용해서 사용자 친화적으로 만든 것이 도커이고, 많은 기능들이 들어있다. dockerd에는 컨테이너를 만들어주는 기능 외에 다양한 부가 기능이 많고, 사용자 편의가 좋게 되어있다.컨테이너를 만들어주는 건 containerd이고, containerd는 low level인 libcontainer를 이용하는 것이다.쿠버네티스에서는 도커의 기능 중 컨테이너를 생성해주는 기능만을 주로 사용해서, containerd를 사용한다. 도커가 LXC를 이용하긴 하지만, 둘에 차이점이 존재한다.도커는 App들을 독립적인 환경에 띄우기 위한 목적이고, LXC는 OS를 컨테이너 가상화로 나누기 위한 목적이다.즉, LXC는 기존 VM에서 OS를 가상으로 띄웠던 걸 컨테이너로 OS를 가상화하려는 목적이다. 쿠버네티스가 컨테이너 런타임을 쓰는 방법 쿠버네티스에는 kube-apiserver와 kubelet이라는 컴포넌트가 존재한다.쿠버네티스가 컨테이너를 Pod 단위로 생성하는 API를 호출하게 되면, kube-apiserver는 쿠버네티스로 보내지는 모든 API를 받아, API가 Pod 생성과 관련된 내용이면 kubelet으로 전달한다.kubelet은 Pod 생성에 관한 내용을 보고 컨테이너의 수를 확인해 컨테이너 런타임에 컨테이너 생성 명령을 보낸다.컨테이너 런타임은 요청받은 컨테이너 개수대로 컨테이너를 생성한다. Kubelet으로 보는 쿠버네티스와 컨테이너 런타임 간의 통신방법kubelet은 컨테이너 런타임이 받을 수 있는 API 호출을 하고, 컨테이너 별로 맞춤으로 보낸다(v1.0).컨테이너 런타임이 많아짐에 따라 kubelet의 명령처리도 다양화 되어, kubelet에 알맞는 interface 규격을 정해주고,규격에 맞도록 구현부를 따로 빼어 CRI(Container Runtime Interface)를 만들었다(v1.5).CRI에서 각각의 컨테이너 런타임을 호출하도록 만들었고,컨테이너 런타임 별로 dockershim -> docker , cri-containerd -> containerd, rktshim ->rkt로 구분했다.v1.23이후로는 dockershim이 없어지면서, v1.24에 cri-dockerd로 CRI에서는 지원을 하지 않지만, interface에 docker를 사용할 수 있게 한 미란티스 컨테이너 런타임도 만들어 졌다. 컨테이너는 OCI라는 컨테이너 표준이 정해져 있고, 컨테이너 런타임은 이걸 잘 지키고 있기 때문에, 기존 컨테이너에서 다른 컨테이너 런타임으로 교체를 하더라도, 기존에 만들었던 컨테이너 이미지를 다른 컨테이너 런타임에서도 다시 사용할 수 있게 된다. Kubelet과 CRI는 grpc로 내부 간 통신을 하고, 컨테이너 런타임의 기능이 바뀌면 쿠버네티스도 결국엔 CRI를 바꿔야 했다.그래서 컨테이너 런타임의 기술개발과 쿠버네티스의 기술개발을 별개로 구분하도록kubelet에서 컨테이너 런타임으로 바로 받을 수 있게 구조를 바꿉니다. 각 컨테이너 런타임은 이러한 구조를 지원하기 위해containerd는 CRI-Plugin 기능을 추가하고, cri-o는 해당 구조 규격에 맞게 만든 런타임이고, docker는 cri-dockerd로 되면서 v1.27부터 Pod 생성 시 해당 구조로 컨테이너 런타임과 통신 및 컨테이너 생성을 하게 되었다.