도커 (Docker)

소프트웨어 마에스트로 14기 팀 프로젝트에서 나는 백엔드 파트를 담당하여 Spring Boot를 통한 WAS 개발을 하게 되었다. Docker를 우리 프로젝트에 도입하게 된다면 우리 프로젝트에 어떠한 이점이 있는 지 학습 차 게시글을 작성하게 되었다.


사전 지식

가상화

  가상화에 대해 정리해놓은 게시글이 있으니 참고하면 좋을 것 같다.

https://jinlee1703.github.io/devops/2023-08-01-Virtualization/

컨테이너

  마찬가지로 컨테이너에 대해 정리해놓은 게시글이 있으니 참고하면 좋을 것 같다.

https://jinlee1703.github.io/devops/2023-08-01-Container/

리눅스 컨테이너

  Linux 기반 기술의 일종으로, 필요한 라이브러리와 애플리케이션을 모아서 마치 별도의 서버처럼 구성한 것이다. 컨테이너를 이루는 네트워크 설정, 환경 변수 등의 시스템 자원은 각 컨테이너가 독립적으로 소유한다. 결과적으로 프로세스를 격리된 환경에서 실행하도록 해주는 가벼운 가상화 기술이다.

리눅스 컨테이너 특징

  리눅스 컨테이너는 아래의 주요 구획화 기술을 사용하여 가상화를 제공하는데, 이러한 기술들은 컨테이너가 서로 독립적으로 실행되도록 보장하면서, 동시에 호스트 시스템의 리소스를 효율적으로 활용하는 데 도움을 준다. 결과적으로 컨테이너는 가볍과 빠르며, 강력한 격리를 제공하는 반면, 훨씬 적은 시스템 리소스를 사용하게 된다.

프로세스 구획화 (Process Isolation)

  컨테이너는 자체 PID 네임스페이스를 가지기 때문에, 각 컨테이너는 다른 컨테이너의 프로세스에 접근할 수 없으며, 자신만의 프로세스 ID를 갖게 되고 그 컨테이너 안에서만 액세스 할 수 있다. 즉, 각 컨테이너 내부에서는 해당 컨테이너가 전체 시스템의 일부인 것처럼 보인다.

네트워크의 구획화 (Network Isolation)

  컨테이너는 자체 network 네임스페이스를 가지기 때문에, 각 컨테이너에 고유한 네트워크 스택(IP 주소, 라우팅 규칙, 포트 등)이 부여된다. 이를 통해 컨테이너는 호스트 OS나 다른 컨테이너와 독립적인 네트워크 환경에서 실행될 수 있다. 또한 하나의 컴퓨터가 하나의 IP 주소만 가질 수 있다는 점을 극복할 수 있다.

파일 시스템 구획화 (File System Isolation)

  컨테이너는 자체 파일 시스템을 가지며, 그 위에서 동작한다. 컨테이너용 이미지는 컨테이너가 실행되기 위해 필요한 코드, 라이브러리, 설정 파일 등을 포함하고 있다. 이 파일 시스템은 읽기 전용으로 마운트되며, 컨테이너가 시작될 때 새로운 쓰기 가능 계층이 추가된다. 이로써 여러 컨테이너가 동일한 이미지를 공유하면서도 각각의 데이터를 독립적으로 유지할 수 있다.

컨테이너의 공유 자원과 격리 자원

공유 자원

  • CPU 성능 (하드웨어)
  • 메모리 (하드웨어)
  • 리눅스 커널 (호스트 OS)

격리 자원

  • 네트워크 (IP, Port)
  • 파일
  • 프로세스

Docker

Docker란

  Docker(이하 도커)는 Go언어로 작성된 리눅스 컨테이너 기반오픈소스 가상화 플랫폼이다. 도커를 통해 애플리케이션 실행 환경을 코드로 작성할 수 있고, 이를 통해 OS를 공유, 격리화하여 관리함으로써 개발자는 어떤 환경에서도 일관된 작동을 보장하는 애플리케이션을 빌드하고 배포할 수 있다.

특징 및 이점

이식성

  도커 컨테이너는 호스트 운영체제와 독립적으로 실행되므로, 개발 환경에서 빌드한 컨테이너를 그대로 스테이징이나 프로덕션 환경에 배포할 수 있다.

경량성

  Docker는 하이퍼바이저를 사용한 전통적인 가상화와 달리, 운영체제 수준에서의 가상화를 제공하므로, 각 컨테이너가 전체 운영체제를 구동하는 대신 호스트 시스템의 커널을 공유하면서 독립적으로 실행된다. 이는 매우 빠른 시작 시간과 적은 오버헤드를 가능하게 한다.

버전 관리와 컴포넌트 재사용

  Docker는 Git과 비슷한 이미지 버전 관리 시스템을 제공하며, 이미지 레이어를 통해 컴포넌트를 재사용할 수 있다. 이를 통해 소프트웨어 업데이트와 배포가 간편해지게 된다.

CI/CD 지원

  Docker는 지속적인 통합(Continous integration)과 지속적인 배포(Continous Deployment)를 가능하게 한다. 즉, 개발부터 테스트, 스테이징, 프로덕션 환경으로 이어지는 파이프라인을 통해 소프트웨어를 더 빠르고 안정적으로 배포할 수 있다.

커뮤니티와 에코시스템

  Docker는 강력한 커뮤니티를 보유하고 있으며, 다양한 오픈 소스 프로젝트와 연동이 가능하다. 그 중 Docker Hub는 수백만 개의 컨테이너 이미즤를 공유하는 중앙 레포지토리 역할을 한다.

Docker를 사용하는 이유

환경 표준화를 통한 생산성 향상

  애플리케이션을 개발할 때, 개발하려고 하는 여러 개의 애플리케이션을 구동하는 운영체제가 다르다면 환경에 따라 조금씩 변경이 필요한 부분이 있을 수 있다. 환경이 다르다면 개발자들이 조정할 문제가 수도 없이 생기며, 이를 위해 수작업으로 환경을 맞추는 일은 매우 번거로운 작업이다. 다양한 환경에서 애플리케이션이 돌아가도록 빌드하고 테스트를 수행하기 위해선 그만큼의 비용이 발생한다. 이를 해결하기 위해 도커는 환경까지 패키징할 수 있기 때문에 생산성을 향상시킬 수 있다.

환경 구성 코드 제공을 통한 생산성 향상

  개발된 애플리케이션을 내 컴퓨터에 설ㄹ치해 사용하고자 할 때, 내 컴퓨터 혹은 내 사용 목적에만 맞는 설정이 따로 필요할 수 있을 것이다. 이를테면 환경 변수, 방화벽 설정 , 사용자 권한 설정, Port 설정 등이 있을 것이다. 이런 다양한 설정 작업을 수작업으로 하게 된다면, 많은 시간이 걸릴 뿐만 아니라 설정 간에 간섭이 일어나 최악의 경우에는 프로그램이 멈출 수도 있을 것이다. Docker를 사용하게 된다면 개발 환경에 대한 설정을 코드로 정의하여, 이러한 고민으로부터 벗어날 수 있을 것이다.

리소스 격리성을 통한 응용 프로그램 + 실행 환경 분리

  리소스 격리성이란 실제로는 하나의 컴퓨터를 사용하지만, 여러 개의 컴퓨터를 사용하는 것처럼 IP와 Port를 다르게 설정하는 방법이다. 리소스 격리성을 제공하는 기술로는 VM과 Docker 등이 있는데 이러한 기술을 통해 실행 환경을 분리할 수 있다. 에를 들어 A 응용 프로그램과 B 응용 프로그램이 있을 때 두 프로그램 모두 node.js 런타임이 필요하지만 A는 14버전, B는 16버전이 필요할 경우 각각의 응용 프로그램 및 환경을 격리시킬 수 있다.


Docker Compose

Docker Compose란

  Docker Compose란 다중 컨테이너 도커 애플리케이션을 정의하고 공유 및 실행하기 위한 도구이다. Compose에서는 YAML 파일을 사용하여 애플리케이션의 서비스를 설정하며, 이를 통해 서비스를 생성하고 시작하는 일련의 과정을 단순화할 수 있다. 궁극적으로 Docker Compose를 이용하여 여러 개의 컨테이너로 구성된 애플리케이션의 배포와 관리가 매우 간편해진다. 개발 환경 뿐만 아닌 테스트, 스테이징, 프로덕션 환경에서도 사용할 수 있다.

이점

  Docker Compose를 통해 복잡한 애플리케이션에 필요한 모든 설정을 한 곳에서 관리할 수 있다. 예를 들면, 웹 애플리케이션, 백엔드 API 서버, 데이터베이스 등을 포함하는 애플리케이션의 경우 이 모든 컴포넌트를 개별적인 Docker 컨테이너로 실행하고 이들을 Docker Compose를 사용해 관리할 수 있다.

주요 명령어

  • docker-compose up: Compose 파일에서 정의한 서비스를 시작하고 실행한다. 이 명령어는 필요한 모든 이미지를 pull하고, 필요한 네트워크, 볼륨 등을 생성한다.
  • docker-compose down: Compose 파일에서 정의한 모든 리소스를 삭제한다.
  • docker-compose ps: 현재 실행 중인 서비스의 상태를 보여준다.
  • docker-compose logs: 서비스의 로그를 출력한다.

Docker 이미지 레지스트리 서비스

  도커를 사용하는데 더불어, 컨테이너 이미지를 저장, 관리, 배포하기 위한 이미지 레지스트리 서비스를 함께 사용을 하는 것을 본 적이 있다. 그래서 이 서비스의 역할이 무엇이고 대표적인 서비스에는 어떤 것들이 있는 지 알아 보려 한다.

역할

표준화된 배포

  이미지 레지스트리를 사용하면 애플리케이션의 모든 인스턴스가 동일한 이미지를 사용하도록 보장할 수 있다. 이는 표준화된, 반복 가능한 배포를 가능하게 한다.

버전 관리

  도커 이미지는 태그를 통해 버전을 관리할 수 있다. 이는 특정 버전의 애플리케이션으로 롤백하거나 다양한 버전을 병렬로 실행하는 등의 운영에 유용하다.

공유와 협업

  레지스트리는 도커 이미지를 저장하고 공유하는 중앙 집중식 장소를 제공한다. 이를 통해 개발 팀이나 여러 환경 간에 쉽게 이미지를 공유할 수 있다.

보안

  프라이빗 도커 레지스트리를 사용하면 애플리케이션 이미지의 접근을 제한하고 보안을 유지할 수 있다. 이는 보안이 중요한 조직이나 애플리케이션에 특히 중요하다.

통합

  대다수의 컨테이너 오케스트레이션 플랫폼(Kubernetes, Amazon ECS 등)은 레지스트리와 통합되어 있으므로, 이미지를 쉽게 배포하고 관리할 수 있다.

자동화

  도커 이미지 레지스트리는 CI/CD 파이프라인과 통합되어, 애플리케이션의 빌드와 배포를 자동화하는데 도움을 준다. 코드 변경이 있을 때마다 새로운 도커 이미지를 빌드하고, 레지스트리에 푸시하며, 이를 바탕으로 애플리케이션을 업데이트 할 수 있다.

  위의 역할들을 통해 도커 이미지 레지스트리 서비스를 통해 컨테이너 기반 애플리케이션의 개발과 배포를 훨씬 쉽고 효율적으로 만든다.

대표적인 도커 이미지 레지스트리 서비스

Docker Hub

  Docker Hub는 Docker의 공식 컨테이너 이미지 저장소이다. 개인 사용자와 조직 모두 사용할 수 있으며, 수많은 오픈소스 프로젝트가 Docker Hub를 통해 자신의 이미지를 공유하고 있다.
  가장 큰 특징으로는 Docker Hub는 무료 계정을 제공한다는 것이다. 다만 무료 계정을 사용할 경우 일정 수준의 pull 요청 제한이 있다고 한다. 그리고 퍼블릭 레포지토리를 무료로 제공하며, 프라이빗 레포지토리를 사용하려면 유료 플랜을 구독해야 한다고 한다.
  Docker Hub는 Docker CLI와 바로 통합되어 있으며, 도커 이미지를 빌드하고 푸시하는데 있어 편리하다. 또한 Docker Hub는 이미지를 검색하고 다운로드하는 기능을 제공하며, 또한 자동 빌드, 웹훅 등 다양한 기능을 제공한다.

Amazon ECR

  Amazon ECR은 AWS의 일부로 제공되는 Docker 컨테이너 레지스트리 서비스이다. AWS 계정 안에서 완전히 관리되며, AWS의 보안, 암호화, 모니터링, 접근 제어 기능을 활용할 수 있다.
  ECR은 AWS의 다른 서비스와 잘 통합되어 있는데, ECS(Elastic Container Service) 또는 EKS(Elastic Kubernetes Service)에서 ECR의 이미지를 쉽게 사용할 수 있다.
  Amazon ECR은 사용량에 따라 비용이 발생한다. 저장된 이미지의 양과 데이터 전송량에 따라 요금이 청구된다. 또한 ECR은 모든 레포지토리를 프라이빗이기 때문에, AWS 계정 및 IAM 역할에 대한 접근 제어를 통해 보안을 강화할 수 있다는 장점이 있다.
  추가적인 기능으로는 라이프사이클 정책을 통해 오래된 이미지를 자동으로 삭제하는 기능을 제공하며, 이미지 스캔을 통해 보안 취약점을 탐지하는 기능도 제공한다고 한다.

결론

  간단하게 살펴본 결과, Docker Hub는 일반적인 사용자와 오픈 소스 커뮤니티에 적합하며, Amazon ECR은 AWS를 사용하는 기업 및 프로젝트에 적합할 것으로 판단된다.


Reference