컨테이너
여기서 말하는 컨테이너 개념은 도커에서 나온 게 아닙니다! C4 모델에서 컨테이너는 애플리케이션 또는 데이터 저장소를 나타냅니다. 컨테이너는 전체 소프트웨어 시스템이 작동하기 위해 실행되어야 하는 무언가입니다. 실질적으로, 컨테이너는 아래 항목에 적혀있는 것이 해당됩니다.
- 서버 측 웹 애플리케이션: Apache Tomcat에서 실행되는 Java EE 웹 애플리케이션, Microsoft IIS에서 실행되는 ASP.NET MVC 애플리케이션, WEBrick에서 실행되는 Ruby on Rails 애플리케이션, Node.js 애플리케이션 등.
- 클라이언트 측 웹 애플리케이션: Angular, Backbone.JS, jQuery 등을 사용하여 웹 브라우저에서 실행되는 자바스크립트 애플리케이션.
- 클라이언트 측 데스크톱 애플리케이션: WPF로 작성된 Windows 데스크톱 애플리케이션, Objective-C로 작성된 OS X 데스크톱 애플리케이션, JavaFX로 작성된 크로스 플랫폼 데스크톱 애플리케이션 등.
- 모바일 앱: Apple iOS 앱, Android 앱, Microsoft Windows Phone 앱 등.
- 서버 측 콘솔 애플리케이션: 독립 실행형(예: “public static void main”) 애플리케이션, 배치 프로세스 등.
- 서버리스 함수: 단일 서버리스 함수(예: Amazon Lambda, Azure Function 등).
- 데이터베이스: MySQL, Microsoft SQL Server, Oracle Database, MongoDB, Riak, Cassandra, Neo4j 등과 같은 관계형 데이터베이스 관리 시스템, 문서 저장소, 그래프 데이터베이스 등의 스키마 또는 데이터베이스.
- Blob 또는 콘텐츠 저장소: Blob 저장소(예: Amazon S3, Microsoft Azure Blob Storage 등) 또는 콘텐츠 전송 네트워크(예: Akamai, Amazon CloudFront 등).
- 파일 시스템: 전체 로컬 파일 시스템 또는 더 큰 네트워크 파일 시스템(예: SAN, NAS 등)의 일부.
- 셸 스크립트: Bash 등으로 작성된 단일 셸 스크립트.
- 등등
컨테이너는 본질적으로 실행 중인 코드나 저장 중인 데이터 주위의 런타임 경계입니다. “컨테이너”라는 이름은 그 컨테이너가 어떻게 실행되는지에 대한 물리적 특성에 대해 아무것도 암시하지 않는 이름을 원했기 때문에 선택되었습니다. 예를 들어, Apache Tomcat과 같은 단일 Java EE 서버는 단일 Java 가상 머신 내에서 여러 웹 애플리케이션을 실행할 수 있지만, 각 웹 애플리케이션은 본질적으로 다른 애플리케이션과 격리되어 있습니다. 개발 시에는 단일 Apache Tomcat 서버에서 세 개의 웹 애플리케이션을 실행할 수 있지만, 라이브 환경에서는 각 웹 애플리케이션이 전용 Apache Tomcat 서버에 배포될 수 있습니다. 이 상황에서 각 웹 애플리케이션은 “C4 컨테이너”이며, 배포는 별도의 문제입니다.
FAQ
왜 “컨테이너”인가요?
“프로세스”, “애플리케이션”, “앱”, “서버”, “배포할 수 있는 단위” 등과 같은 용어는 모두 연관된 의미를 이미 가지고 있습니다. 하지만, “컨테이너”라는 이름은 컴포넌트들이 담기는 무언가를 설명하기 위한 일반적인 표현이기 때문에 선택했습니다. 한편으로는, 컨테이너화 기술이 인기를 얻으면서 많은 소프트웨어 개발자들이 “컨테이너”라는 용어를 도커와 연결 짓게 된 것이 아쉽습니다. 그러나 다른 한편으로는, C4 모델의 컨테이너와 인프라(예: 도커) 컨테이너 사이에 실제로 유용한 유사점들이 존재하기도 합니다.
웹 애플리케이션은 단일 컨테이너일까요? 두 개일까요?
주로 정적 HTML 콘텐츠를 생성하는 서버 측 웹 애플리케이션(예: Spring MVC, ASP.NET, Ruby on Rails, Django 등)을 구축하는 경우, 그것은 단일 컨테이너입니다. 서버 측 웹 애플리케이션에서 상당한 양의 자바스크립트가 제공되는 경우(예: Angular를 사용하여 구축된 단일 페이지 애플리케이션), 그것은 두 개의 컨테이너입니다. 배포 시에 서버 측 웹 애플리케이션이 서버 측 및 클라이언트 측 코드를 모두 포함하지만, 클라이언트와 서버를 두 개의 별도 컨테이너로 취급하면 이들이 프로세스 간/원격 통신 메커니즘(예: JSON/HTTPS)을 통해 통신하는 두 개의 별도 프로세스 공간임이 명시적으로 표현됩니다. 또한 각 컨테이너를 별도로 확대하여 그 안의 컴포넌트를 보여주는 기반을 제공합니다.
Java JAR, C# 어셈블리, DLL, 모듈 등이 컨테이너인가요?
일반적으로 그렇지 않습니다. 컨테이너는 애플리케이션과 같은 런타임 구성입니다. 반면 Java JAR 파일, C# 어셈블리, DLL, 모듈 등은 해당 애플리케이션 내의 코드를 구성하는 데 사용됩니다.
데이터 저장 서비스를 소프트웨어 시스템으로 표시해야 하나요? 아니면 컨테이너로 표시해야 하나요?
Amazon S3, Amazon RDS, Azure SQL Database, 콘텐츠 전송 네트워크 등과 같은 서비스를 소프트웨어 시스템 또는 컨테이너로 표시해야 하는지 여부에 대해 자주 질문합니다. 결국, 이들은 대다수가 직접 소유하거나 운영하지 않는 외부 서비스입니다.
데이터를 저장하기 위해 Amazon S3를 사용하는 소프트웨어 시스템을 구축하는 경우, S3를 직접 실행하는 것은 아니지만, 사용 중인 버킷에 대한 소유권과 책임은 있습니다. 유사하게, Amazon RDS의 경우에도 생성하는 데이터베이스 스키마에 대해 (거의) 완전한 제어권을 가지고 있습니다. 이러한 이유로, 이들은 다른 곳에서 호스팅 되지만 소프트웨어 아키텍처의 필수적인 부분이므로 컨테이너로 취급합니다.