컨테이너 정의
새로운 서비스를 위해 개발하는 것도 중요하지만, 개발에 몰입할 수 있는 환경을 조성하는 것은 더욱 중요합니다. 테스트 환경에서 정상적으로 돌아가던 코드가 운영 환경에서는 실행되지 않는다면, 결국 많은 시간을 낭비할 수밖에 없는데요
개발 시간을 단축하고 어떤 환경에서나 실행할 수 있는 솔루션, 컨테이너에 대해 소개해 드리겠습니다.
컨테이너는 소프트웨어 서비스를 실행하는 데 필요한 특정 버전의 프로그래밍 언어 런타임 및 라이브러리와 같은 종속 항목과 애플리케이션 코드를 함께 포함하는 경량 패키지입니다.
독립된 컨테이너에 애플리케이션을 작동하기 위한 모든 것을 담아 사용할 수 있게 만든 것입니다.
코드, 라이브러리, CPU, 리소스 등 애플리케이션 실행에 필요한 모든 요소를 하나의 컨테이너에 모아 실행 환경(로컬, 테스트 환경 등)이 바뀌어도 안정적으로 실행할 수 있습니다.
컨테이너 특징
컨테이너를 사용하면 개발자는 업무를 수행하는 데 있어 다음과 같은 이점을 얻을 수 있습니다.
- 배포 및 관리
- 여러 개발자가 쉽게 복제하여 테스트, 개발 및 배포 간편화
- 다양한 운영 환경
- Linux, Windows, Mac 등 어느 환경에서나 구동
- 리소스 사용량 적음
- VM에 비해 사용하는 리소스가 적음
컨테이너 내부 구조
컨테이너는 1개 이상의 프로세스를 격리시켜 호스트 OS 환경에 대해 알 수 없게 만들어졌습니다.
예를 들어 컨테이너는 전용의 root directory를 부여받으며, 이 안에서는 root 계정 행세를 하지만 host의 파일에는 접근할 수 없습니다. 프로세스 ID도 자신만의 것을 가지고 있어 host에서 부여한 PID는 알 수 없습니다.
격리된 루트 디렉토리에는 런타임 환경(Runtime environment)을 넣는데요. 런타임 환경이란 프로그램이 정상적으로 실행되기 위한 환경을 말하며 넓은 의미에서는 운영체제나 하드웨어도 포함됩니다.
C언어의 libc 공유 라이브러리가 대표적인 런타임 환경입니다. 다른 예로는 자바 프로그램을 실행할 때 필요한 JRE가 있으며 보통 런타임 환경은
/bin
,
/usr/local
등 모든 계정이 공유하는 공간에 설치됩니다.
chroot
를 사용하면 이런 Directory에 접근이 불가능하기 때문에 호스트의 런타임 환경을 사용할 수 없고 새로 만들어야 합니다.
Java 소프트웨어 개발 환경 비교
호스트와 구분된 런타임 환경이 있으면 개발이나 배포가 쉬워지는데요.
OpenJDK Java 1.17로 개발한 프로그램과 Oracle Java 1.8 버전으로 개발된 프로그램을 동시에 실행한다고 가정하겠습니다.
컨테이너 없이 같은 호스트에서 실행하려면, 두 가지 자바를 모두 설치해야 하고 알맞은 버전으로 빌드 해야 합니다. 그러나 컨테이너로 격리해두면 하나의 자바만 설치되어 있으므로 정확한 자바 버전을 선택하느라 신경 쓸 필요가 없어집니다.
호스트 환경은 다른 용도로 사용하다 변해버리는 경우가 있지만 컨테이너는 특정 상태를 스냅샷 해서 이용하므로 설정 환경이 바뀔 걱정이 없습니다.
컨테이너는 격리되었다는 점을 제외하면 호스트의 다른 프로세스와 크게 다를 점이 없는데요. 중간에 OS 하나가 더 낀 것이 아니라
ps
로 조회할 수도 있고
kill
로 종료할 수도 있습니다. 중간에 게스트 OS가 끼지 않고 호스트의 커널을 그대로 사용하므로, 가상 머신보다 실행 속도가 빠르고 관리하기도 편합니다. 하지만 커널을 공유하는 만큼 Mac이나 Windows 전용 프로그램을 Linux에서 실행하는 등의 유연성은 없습니다.
파이썬 라이브러리 호환성
파이썬 라이브러리의 호환성 오류를 예시로 들어보려 합니다. 파이썬 프로그래밍 언어는 연 단위로 새 버전이 나오고 있는데요. 파이썬 2.7.18 버전을 마지막으로, 파이썬 3으로 전환되면서 일부 코드와 라이브러리에 호환성으로 인한 오류가 발생합니다. 파이썬 2에서 3로 넘어가는 수준의 큰 변화가 아니더라도 호환성 오류는 종종 발생합니다.
텐서플로우의 경우, 파이썬 3.6~3.9까지만 지원됩니다. 앞서 말한 버전에 속하지 않을 경우, 텐서플로우 모듈을 설치할 수 없게 됩니다.
구글에서 제공하는 jupyter notebook인 구글 코랩(colab)을 실행시켰을 때, 현재 파이썬 버전은 아래와 같이 3.8.10 버전임을 알 수 있습니다.
텐서플로우를 사용하는 개발자가 Parenthesized context managers 와 같은 새로운 기능을 사용해보기 위해 파이썬 버전을 3.10.0으로 업데이트 하는 상황을 가정해보겠습니다.
확인해 보면 파이썬 3.10.0으로 변경된 것을 확인하실 수 있습니다. 텐서플로우 모듈을 설치했을 때, 지원되지 않는 버전이므로 에러 메시지가 발생한 것을 알 수 있었는데요. 파이썬 3.10.0 버전과 호환되는 텐서플로우 버전이 아직 개발되지 않았기 때문입니다.
서로 호환되는 파이썬과 텐서플로우의 버전을 선택해서 메소드가 정상적으로 작동이 가능해야 하는데요. 각자 프로젝트 환경에 맞춰 선택해 사용해야 합니다. 만약 예시가 아닌 실제 상황이었다면 파이썬 버전을 다시 3.8로 롤백하는 과정을 거쳤어야 했을 것입니다. 대신 파이썬 3.8이 설치된 컨테이너를 베이스 이미지로 사용한다면 환경 설정에 드는 시간을 단축하고 개발에 집중할 수 있게 됩니다.
마무리
이번 콘텐츠를 통해 컨테이너 정의부터 특징, 그리고 자바와 파이썬 예시까지 알아봤습니다. 컨테이너 의미를 한 번 더 짚고 이해하는데 도움이 되셨길 바랍니다.