02. 클라우드 보안 공부/개념정리

✅ [개념정리] 파드, 컨테이너, 도커, 쿠버네티스: 핵심 관계 완전 정복!🏗️

taegi- 2025. 5. 23. 15:48

컨테이너 기술의 A to Z, 헷갈리는 용어들 한 방에 정리해 드립니다! 💡

[들어가며: 컨테이너 기술, 왜 이렇게 핫할까요? 🤔]

요즘 IT 업계에서 '쿠버네티스', '도커', '컨테이너' 같은 용어들을 정말 많이 듣게 되지? 이런 기술들이 등장하면서 애플리케이션을 개발하고 배포하는 방식이 혁신적으로 바뀌고 있어. 하지만 각 용어가 정확히 무엇을 의미하고, 서로 어떤 관계를 맺고 있는지 처음엔 좀 헷갈릴 수 있어.

그래서 오늘은 이 복잡해 보이는 용어들의 핵심 개념을 확실하게 잡고, 서로 어떻게 연결되어 돌아가는지 그 큰 그림을 이해하는 데 초점을 맞춰보려고 해!


Part 1: 쿠버네티스, 파드, 컨테이너, 도커의 관계 🔗 – 누가 누구를 관리할까?

마치 인형 속에 또 인형이 들어있는 러시아 인형 '마트료시카'처럼, 이 기술들도 계층적인 구조를 가지고 있어.

1. 기본 단위: 컨테이너 (Container) 📦

  • 정의: 하나의 운영 체제(OS) 안에서 커널은 공유하지만, 마치 독립된 컴퓨터처럼 자신만의 실행 환경(CPU, 메모리, 네트워크, 파일 시스템, 프로세스 ID 등)을 격리해서 사용하는 공간이야.
  • 특징: 각 컨테이너 안에서 실행되는 애플리케이션들은 서로 영향을 주지 않고 독립적으로 작동해. 가볍고 빠르게 실행할 수 있다는 큰 장점이 있지.

2. 컨테이너의 집: 파드 (Pod) 🏠

  • 정의: 쿠버네티스에서 생성하고 관리할 수 있는 가장 작은 배포 단위로, 하나 이상의 컨테이너 그룹이야.
  • 역할:
    • 파드 단위로 IP 주소를 할당받아서, 파드 내의 컨테이너들이 외부와 통신할 수 있는 경로를 제공해.
    • 파드 내의 컨테이너들은 네트워크 네임스페이스나 저장 공간(볼륨)을 서로 공유할 수 있어.
    • 컨테이너들이 정상적으로 작동하는지 감시하고 관리하는 역할도 해.
  • 효과: 파드라는 환경 덕분에 여러 컨테이너들이 마치 하나의 논리적인 호스트(서버)에 함께 존재하는 것처럼 긴밀하게 협력하며 작동할 수 있어.

3. 파드의 일터: 워커 노드 (Worker Node) 🏭

  • 정의: 실제로 파드(즉, 그 안의 컨테이너들)가 배치되어 실행되는 물리적 또는 가상 머신이야. 쿠버네티스 클러스터의 '일꾼'이라고 생각하면 돼.

4. 총괄 사령탑: 쿠버네티스 클러스터 (Kubernetes Cluster) 🌟

  • 정의: 여러 대의 워커 노드들과, 이 워커 노드 및 전체 클러스터를 관리하고 통제하는 **마스터 노드(Master Node)**들이 모여 이루는 하나의 큰 시스템이야.
  • 흥미로운 사실: 쿠버네티스의 두뇌 역할을 하는 마스터 노드 역시, 그 내부 구성 요소들은 파드(컨테이너) 형태로 실행된다는 점! 스스로를 컨테이너화해서 관리하는 거지.

결국, 이런 관계가 성립돼:

컨테이너를 돌보는 것이 파드이고, 파드들을 돌보는 것이 쿠버네티스 워커 노드이며, 워커 노드들을 포함한 클러스터 전체를 지휘하는 것이 쿠버네티스 마스터다!

5. 컨테이너와 도커(Docker)는 무슨 사이? 🤝

  • 컨테이너 기술의 대중화: 사실 리눅스나 유닉스에는 예전부터 운영 체제 안에서 자원을 분리하고 프로세스를 격리하는 기능(cgroups, namespaces 등)이 있었어. 하지만 이걸 직접 설정하고 관리하는 건 너무 복잡해서 일부 전문가들만 활용했지.
  • 도커의 등장: **"도커는 이런 복잡한 컨테이너 생성 및 관리 과정을 명령어 몇 줄로 아주 쉽게 만들어 준 도구"**라고 생각하면 돼. 개발자들이 컨테이너 기술에 훨씬 쉽게 접근하고 활용할 수 있도록 길을 열어준 일등 공신이지! 도커를 사용하면 사용자가 일일이 신경 쓰지 않아도 컨테이너를 만들 때 개별 실행 환경을 분리하고 필요한 자원을 할당해 줘.

Part 2: 다양한 컨테이너 관리 도구 🛠️ – 도커만 있는 게 아니야!

컨테이너를 다루는 기술 표준으로 **CRI(Container Runtime Interface)**라는 것이 있어. 쿠버네티스는 이 CRI 표준을 따르는 다양한 컨테이너 런타임(관리 도구)과 함께 작동할 수 있어. 도커가 가장 유명하지만, 다른 선택지들도 있다는 걸 알아두자!

  • 컨테이너디 (containerd): 원래 도커의 핵심 런타임 부분이었는데, 이게 분리되어 독립적인 오픈소스 프로젝트가 됐어. CNCF(Cloud Native Computing Foundation)의 졸업 프로젝트이기도 하고, 쿠버네티스와 잘 통합돼. 도커를 설치하면 내부적으로 이 컨테이너디를 사용해.
  • 크라이오 (CRI-O): 레드햇(Red Hat)이 쿠버네티스와의 긴밀한 통합을 목표로 개발한 컨테이너 런타임이야. 다른 부가 기능 없이 CRI 규격만 딱 맞춰서 구현했기 때문에 가볍고 단순하다는 장점이 있어.
  • 카타 컨테이너 (Kata Containers): 이건 좀 독특한데, 컨테이너마다 아예 독립적인 커널을 제공해. 각 컨테이너를 위한 초경량 가상머신(VM)을 만들고 그 위에서 컨테이너를 실행하는 방식이지. 그래서 일반적인 컨테이너보다 격리 수준이 높아서 보안에는 더 유리하지만, 대신 자원 사용량은 좀 더 많아.
  • 도커 (Docker): 앞서 말했듯이 컨테이너 기술 대중화의 아이콘! 컨테이너 실행뿐만 아니라, 컨테이너를 만들기 위한 이미지를 생성하고, 이를 도커 허브(Docker Hub) 같은 저장소에 공유하는 등 강력하고 편리한 부가 기능들을 많이 제공해. 현재 많은 쿠버네티스 환경에서 여전히 기본 컨테이너 런타임으로 널리 사용되고 있어.

(각 도구마다 장단점과 특징이 있지만, 지금은 "아하, 쿠버네티스가 다양한 컨테이너 엔진과 함께 작동할 수 있구나!" 정도로 이해하고 넘어가도 충분해! 책에서는 현재 쿠버네티스 인프라를 구성하는 데 가장 적합한 도구로 도커를 선택했다고 언급하고 있네.)


Part 3: 도커 컨테이너 핵심 개념 짚어보기 🐳

도커를 이용해 컨테이너를 다룰 때 꼭 알아야 할 핵심 개념들을 살펴보자.

1. 컨테이너 이미지 vs. 컨테이너 🖼️➡️🏃‍♂️

  • 컨테이너 이미지 (Image): 컨테이너를 실행하기 위한 모든 정보(애플리케이션 코드, 라이브러리, 실행 환경 설정 등)를 담고 있는 읽기 전용 템플릿이야. 마치 프로그램 설치 파일이나 VM 이미지와 비슷하다고 생각할 수 있어. 이미지 자체는 실행 상태가 아니야.
  • 컨테이너 (Container):이미지를 기반으로 실제로 메모리에 로드되어 실행되고 있는 인스턴스를 말해. 하나의 이미지로 여러 개의 동일한 컨테이너를 만들어 실행할 수 있어.
  • 중요!: 컨테이너를 삭제한다고 해서 이미지가 자동으로 삭제되지는 않아. 디스크 용량을 완전히 확보하려면, 실행 중인 컨테이너를 삭제한 후 원본 이미지도 별도로 삭제해 줘야 해.

2. 컨테이너 이미지, 좀 더 자세히! 🔍

  • 레지스트리 (Registry): 컨테이너 이미지를 저장하고 공유하는 원격 저장소야. 가장 유명한 공개 레지스트리는 **도커 허브(Docker Hub)**이고, 회사 내부용 사설 레지스트리를 구축해서 사용할 수도 있어. docker search <이미지이름> 명령으로 이미지를 검색할 수 있지.
  • 태그 (Tag): 같은 이름의 이미지라도 버전이나 특정 환경(예: 운영체제, CPU 아키텍처)에 따라 내용이 다를 수 있는데, 이를 구분하기 위해 붙이는 꼬리표 같은 거야. 예를 들어 nginx:latest, nginx:1.21처럼 사용해. 태그를 지정하지 않고 이미지를 받으면 보통 latest 태그(가장 최신 버전)가 적용되는데, 안정적인 운영을 위해서는 배포 시 특정 버전의 태그를 명시하는 것이 좋아!
  • 레이어 (Layer) 구조: 컨테이너 이미지는 여러 개의 얇은 레이어들이 겹쳐져 있는 형태로 구성돼. 예를 들어 기본 OS 레이어 위에, 웹 서버 프로그램 레이어, 그 위에 내 애플리케이션 코드 레이어... 이런 식이지. 이 레이어 구조 덕분에 여러 이미지가 동일한 레이어를 공유할 수 있어서 디스크 용량을 매우 효율적으로 사용할 수 있어. (예: nginx:latest 이미지와 nginx:stable 이미지가 기본 OS 레이어를 공유)
  • 다이제스트 (Digest): 각 이미지마다 갖는 내용 기반의 고유한 식별자(SHA256 해시값). 이미지의 이름이나 태그는 사용자가 바꿀 수 있지만, 다이제스트는 이미지 내용이 동일하면 항상 같아. 그래서 이미지의 무결성을 검증하거나 정확히 동일한 이미지를 식별할 때 사용돼.

3. 컨테이너 실행의 기본 원리 🚀

  • docker run 명령으로 이미지를 컨테이너로 실행해. 이때 다양한 옵션을 줄 수 있는데, 몇 가지 중요한 개념만 짚어볼게.
    • 백그라운드 실행 (-d 옵션): 컨테이너를 화면에 붙잡아두지 않고 뒤에서 조용히 실행시키고 싶을 때 사용해. 서버 프로그램 같은 경우는 거의 필수지.
    • 재시작 정책 (--restart 옵션): 컨테이너가 예기치 않게 종료되었거나, 서버가 재부팅되었을 때 컨테이너를 자동으로 다시 시작할지 등을 정하는 정책이야. always로 설정하면 항상 재시작하려고 노력해.
  • 컨테이너는 불변성(Immutable)을 지향: 일단 컨테이너가 실행되면, 그 내부 설정을 직접 변경하는 것은 권장되지 않아 (변경 불가능한 인프라). 설정을 바꿔야 한다면, 기존 컨테이너를 삭제하고 변경된 설정으로 새로운 컨테이너를 만드는 방식을 선호해. 이렇게 하면 환경의 일관성을 유지하기 쉬워.
  • 포트 포워딩/노출 (-p <호스트포트>:<컨테이너포트> 옵션): 컨테이너는 기본적으로 자신만의 격리된 네트워크 환경을 가져. 그래서 컨테이너 내부에서 실행 중인 서비스(예: 웹 서버의 80번 포트)에 외부(호스트 PC나 다른 네트워크)에서 접속하려면, 호스트의 특정 포트와 컨테이너의 포트를 연결해주는 설정이 필요해. 이걸 '포트 포워딩' 또는 '포트 노출'이라고 불러. 예를 들어 -p 8080:80은 호스트의 8080번 포트로 들어오는 요청을 컨테이너 내부의 80번 포트로 전달하라는 의미야.

4. 컨테이너와 데이터 관리 (파일 시스템 연결) 💾

컨테이너는 삭제되면 그 안의 데이터도 함께 사라지는 것이 기본 원칙이야. 하지만 데이터베이스 파일이나 사용자가 업로드한 파일처럼 영구적으로 보존해야 하는 데이터도 있겠지? 이럴 때 사용하는 방법들이야.

  • docker cp: 호스트 PC와 실행 중인 컨테이너 간에 파일을 간단하게 복사할 때 사용. 임시적인 파일 전송에 적합해.
  • Dockerfile의 ADD 또는 COPY: 컨테이너 이미지를 만들 때(Dockerfile 작성 시) 아예 특정 파일이나 디렉터리를 이미지 안에 포함시키는 방법이야.
  • 바인드 마운트 (Bind Mount): **호스트 PC의 특정 디렉터리나 파일을 컨테이너 내부의 특정 경로에 직접 연결(마운트)**하는 방식이야. 이렇게 하면 호스트에서 파일을 수정하면 컨테이너 내부에도 즉시 반영되고, 컨테이너에서 파일을 수정해도 호스트에 반영돼. (주의! 호스트의 빈 디렉터리를 컨테이너의 내용이 있는 디렉터리에 마운트하면, 컨테이너에서 기존 파일이 보이지 않게 될 수 있어. 호스트 내용이 우선시되는 경향)
  • 볼륨 (Volume): 이것도 호스트와 컨테이너 간의 데이터 공유 방법인데, 바인드 마운트가 호스트의 '아무 경로'나 지정하는 반면, 볼륨은 도커가 직접 관리하는 특별한 저장 공간을 만들어서 컨테이너에 연결해.
    • 보통 /var/lib/docker/volumes/ 같은 경로에 도커가 알아서 관리해.
    • 빈 볼륨을 컨테이너의 내용이 있는 디렉터리에 연결하면, 컨테이너의 기존 파일들이 볼륨으로 복사되어 보존되는 특징이 있어 (바인드 마운트와 다른 점!).
    • 이름을 붙여서 관리하기 쉽고, 여러 컨테이너 간에 안전하게 데이터를 공유하거나, 백업/복원 등의 관리가 바인드 마운트보다 용이할 수 있어. NFS 같은 공유 스토리지에 볼륨을 만들면 여러 호스트 간에도 데이터 공유가 가능해.

5. 깔끔한 뒷정리: 사용하지 않는 컨테이너와 이미지 삭제 🗑️

컨테이너를 계속 만들다 보면 사용하지 않는 것들이 쌓여서 시스템 자원을 차지하게 돼.

  • 컨테이너 정지 (docker stop <컨테이너ID 또는 이름>): 실행 중인 컨테이너를 멈춰.
  • 컨테이너 삭제 (docker rm <컨테이너ID 또는 이름>): 정지된 컨테이너를 삭제해. (실행 중인 컨테이너를 강제로 삭제하려면 -f 옵션)
  • 이미지 삭제 (docker rmi <이미지ID 또는 이름:태그>): 로컬에 받아둔 이미지를 삭제해. 단, 해당 이미지를 사용하고 있는 컨테이너가 하나라도 존재하면 이미지를 삭제할 수 없어. 반드시 관련된 컨테이너를 먼저 삭제해야 해.

[마무리하며: 컨테이너 기술, 이제 두렵지 않아요! 💪]

오늘은 쿠버네티스부터 도커, 파드, 컨테이너에 이르기까지 컨테이너 생태계를 이루는 핵심 요소들의 개념과 관계를 살펴봤어. 각 기술이 어떤 역할을 하고, 서로 어떻게 맞물려 돌아가는지 큰 그림을 그리는 데 도움이 되었으면 좋겠다!

이런 기본 개념들을 잘 이해하고 있으면, 앞으로 더 복잡한 클라우드 네이티브 기술들을 배우고 활용하는 데 훌륭한 밑거름이 될 거야. 😊