Page tree
Skip to end of metadata
Go to start of metadata

도커의 적정한 배포단위란?

공식문서에 의하면 "컨테이너는 하나의 관심사에만 집중해야한다" 라는 입장을 밝히고 있다.

하나의 관심사란 한가지 역할이나 도메인(문제영역)에만 집중해야 한다는 의미이다.

전통적인 웹 어플리케이션 스택을 떠올려보면 웹서버(nginx), WAS(tomcat), DB(mysql)가 서로 독립적인 자기 역할을 수행하며 전체 시스템을 구성하고 있다.

역할이 적절히 분배되었다면 배치한 컨테이너들이 복제되어도 전체구조에서 부작용이 발생하지 않을것이다.

도커 이미지는 한번 만들면 정말 모든 곳에서 실행될까?

CPU 아키텍처 호환성

CPU 아키텍처란?

CPU 아키텍처에 대해서 간단히 설명하자면 프로그래밍 언어에 빗대어 이야기 할 수 있다.

각 프로그래밍 언어들이 결과는 동일하게 발생하더라도 그 내부적인 구조와 매커니즘은 판이하게 달라서 서로 직접적으로 호환되지는 않는다.

C로 작성한 프로그램을 자바에 JVM으로 직접 바로 올려서 실행이 가능한지 생각해보면 될 것이다.

프로그램은 CPU 아키텍처에 종속된다.

가장 잘 알려지고 많이 사용하는 CPU로는 PC에 인텔x86과 휴대폰에 ARM 아키텍처가 있다.

x86 CPU를 사용하는 컴퓨터에서 C언어로 간단한 프로그램을 작성해서 컴파일 했다고 가정해보자.

컴파일해서 생성된 실행파일을 ARM CPU를 사용하는 휴대폰 복사해서 실행한다면 실행되지 않는다.

그 이유는 컴파일러가 CPU 아키텍처에 종속되기 때문이다. 

자바에 경우에도 컴파일해서 나온 결과물인 Class파일은 CPU 아키텍처에 종속되지 않지만 Class파일을 읽어들이고 실행하는 프로그램이 CPU 아키텍처에 종속된다.

도커에 이미지는 CPU 아키텍처와 OS에 종속된다.

도커에 컨테이너는 특정 CPU 아키텍처 위에서 돌아가는 리눅스에서 실행되기 때문에 이미지를 생성한 컴퓨터에 CPU 아키텍처에 종속된다.
그래서 x86 CPU로 돌아가는 리눅스에서 만들어진 컨테이너 이미지는 ARM CPU로 돌아가는 리눅스에서는 실행되지 않는다.

그리고 윈도우 전용 컨테이너 이미지(VM기반이 아님)도 있는데 이것도 리눅스에서는 실행할 수 없다.
비록 동일한 x86 CPU를 기반으로 하지만 커널과 OS에 구조가 다르기 때문에 동작하지 않는다.

도커가 지원하는 플렛폼을 늘려가고 있지만 한번 만들어진 이미지가 모든 환경에서 동작하는 것은 아니기 때문에 주의가 필요하다.

라이브러리와 동적 링크 문제

이 문제는 단순히 이야기하면 컨테이너에 실행되는 프로그램이 자신에게 필요한 모든 것을 가지고 있지 않기 때문에 발생한다.

책에서 다루는 내용은 C를 기준으로 이야기하는데 이것을 Java 플랫폼에 맞추어 이야기하면 이렇게 된다.

자바에서 주로 사용하는 Gradle이나 Maven을 이용하여 빌드를 하면 보통 의존성이 있는 모든 라이브러리를 한번에 묶어서 패키지를 하게 된다.

이렇게 되면 패키지에 용량은 커지지만 어느 환경에서 실행하더라도 필요한 모든 라이브러리를 가지고 있기 때문에 문제가 없다.

하지만 만약에 실행되는 곳에서 미리 필요한 라이브러리가 준비되어 있다면 패키지 용량을 줄일 수 있을 것이다.

그러나 어떤 이유로 인해서 라이브러리가 누락되었다면 프로그램은 제대로 실행되지 못한다.

도커로 이미지를 만드는 과정에서 위에 이야기한 문제까지 모두 알아서 해결해주는 것은 아니라는 것이다.

도커에 잘 맞는 애플리케이션을 만들려면?

애플리케이션 동작이나 환경변수에 대한 부분을 이미지 생성시에 하드코딩하는 것이 아닌 컨테이너가 실행되는 시점에 주입할 수 있는 방식으로 작성한다.

만약에 도커 이미지 안에 상황에 따라서 변화해야하는 값이 고정되어 있다면 각 상황에 따라 도커 이미지 버전을 달리 생성해야 하는데 일반적으로는 불필요하다.

애플리케이션에 동작을 제어하는 방법

  • 실행시 인자 사용
  • 설정 파일 사용
  • 애플리케이션 동작을 환경 변수로 제어
  • 설정 파일에 환경 변수를 포함

컨테이너가 파기되더라도 데이터를 지키는 방법

데이터 볼륨

컨테이너에 특정 위치를 호스트에 특정위치와 연결하는 방식이다.

컨테이너는 파기되어서 데이터는 사라지더라도 데이터 볼륨으로 지정된 호스트에 특정위치에 파일은 지워지지 않는다.

단 이 방식은 호스트에 특정위치에 대해서 종속되기 때문에 지정한 위치가 존재하지 않거나 접근/쓰기 권한이 없을 경우 문제가 발생한다.

또는 컨테이너가 아닌 다른 프로그램이나 사용자가 데이터를 조작 할 경우 문제가 발생 할 수도 있다.

데이터 볼륨 컨테이너

컨테이너와 데이터를 저장하는 것만을 목적으로 하는 컨테이너를 연결하는 방식이다.
데이터 볼륨을 사용하는 컨테이너는 자신이 사용할 데이터 볼륨이 호스트 어딘가에 위치하는지 알 필요가 없다.
그리고 컨테이너에 어플리케이션과 데이터의 결합이 더 느슨해져서 애플리케이션 컨테이너와 데이터 볼륨을 따로 구성할 수 있다.
예를 MySQL 컨테이너에 개발용 데이터 볼륨 컨테이너를 연결해서 사용한다고 가정해보자.
개발용 데이터가 바뀌었을 경우 MySQL 컨테이너는 그대로 사용하고 개발용 데이터 볼륨 컨테이너만 교체하여 실행할 수 있다.

도커들에 모임 스웜

도커 스웜은 여러 도커 호스트를 클러스트로 묶어주는 컨테이너 오케스트레이션 도구의 한 종류다.

컴포즈가 경우 단일 호스트에서 여러개의 컨테이너로 구성된 도커 애플리케이션을 다루었다면 스웜은 여러 호스트에 나누어져 있는 컨테이너들을 관리 하는 것이 주요 목적이다.

Docker In Docker (dind)

도커로 실행되는 컨테이너 안에서 다시 도커 관련 명령들을 사용하는 상황을 이야기한다.

호스트에서 젠킨스를 Docker를 통해서 실행하고 젠킨스가 다시 Docker 이미지를 생성하거나 하는 상황에서 자주 언급된다.

교재로 활용 하는 책에서는 이 기능을 이용하여 별도에 가상머신들을 생성하지 않고 예제들을 진행하는데 가상머신을 사용했을 경우와 대비해서 어떤 장점이 있는지 설명한다.

가상머신을 사용하는 경우

  • 가상 머신을 필요한 만큼 일일이 생성해야한다. 이는 docker-machine이라는 툴에 도움을 받을 수 있다.
  • 가상 머신이 실행되면 설정된 만큼 메모리를 점유하고 있다. 컴퓨터 메모리가 4G라면 1G짜리 가상머신 2개만 실행해도 2G에 메모리를 선점하고 있다.
  • 가상 머신들의 네트워크통신 방법들을 선택해야함(상황에 따라서 제대로 동작하지 않을 수 있음)

DinD를 사용하는 경우

  • 도커 컴포즈를 이용하여 여러개의 Docker 컨테이너를 생성할 수 있음
  • 실행되는 컨테이너가 사용하는 만큼만 메모리를 소비한다
  • 호스트 도커에서 관리하는 네크워크를 이용한다.

도커 스웜에 구성요소

  • 스웜
    • 클러스터 구축 및 관리
  • 서비스
    • 스웜에서 클러스터 안의 서비스(컨테이너 하나 이상의 집합)를 관리
    • 컨테이너 수(레플리카 수)를 조절해 스케일 아웃을 할 수 있다.
  • 스택
    • 스웜에서 여러 개의 서비스를 합한 전체 애플리케이션을 관리

도커 스웜 실습 및 결과 토의

  • 도커 레지스터리
  • No labels