글을 시작하기에 앞서 오늘 작성할 글은 도커 데스크탑의 실질적인 사용 예시로 도커에 대한 기본 개념과 설치 과정을 알아야한다. 만약 해당 내용에 대한 숙지가 없다면 앞서 작성한 글의 내용을 먼저 읽고 오는 것이 좋다.
https://taks-embdd.tistory.com/3
도커(Docker) 기본 개념 & 설치 방법
도커는 특정 응용 프로그램과 의존성(dependency)를 하나로 패키징하여 독립된 공간인 컨테이너(Container)에서 동작할 수 있도록 하는 '컨테이너 기반 플랫폼'이다. 독립된 공간이라하면 가상 머신(
taks-embdd.tistory.com
우리가 도커 이미지를 만들려는 근본적인 이유는 바로 '배포의 용이성' 때문이다.
AI 환경을 예로 들어보자.
AI를 프로젝트나 연구 목적으로 활용해본 사람들은 알겠지만 AI 개발을 위한 로컬 환경 구축은 정말 쉬운 일이 아니다. AI 모델 하나가 가지는 패키지는 수없이 많으며, 이 각각의 패키지가 서로 어떤 의존성을 가지는지는 개발 당사 혹은 팀이 아니고서야 모두 파악하기에는 어려움이 있다. 또한 사용자가 기존에 구축한 본인의 개발 환경과 해당 모델이 지향하는 환경이 서로 호환되지 않는 경우가 다반사인데, 정말 최악의 경우 특정 패키지 간의 버전이 상충하여 특정 모델 사용을 포기해야 하는 경우도 발생한다.
이뿐만 아니라 설령 환경 구축에 성공했을지라도 개발자의 실수로 패키지 업데이트 등과 같은 의존성에 문제를 야기할 수 있는 실수가 발생했을 경우, 이 환경에 대한 명세를 별도로 저장해두지 않았다면 이를 찾는데 시간이 소모되고, 설령 해당 조치가 되어있었다고 하더라도 모종의 사유로 환경 자체를 초기화 해야하는 경우도 있기 때문에 이러한 원시적인 방법 만으로는 불안감을 떨쳐낼 수 없다.
(작성자의 경우 실제로 위와 같이 패키지 버전 상충 문제로 프로젝트에 사용되기로 했던 모델의 로컬 환경 구성을 포기하고 결국 Colab 환경에서 개발을 진행했다)
이러한 문제점을 해결하기 위한 가장 좋은 방법은 '구축에 성공한 환경 자체를 하나의 집합으로 묶는 것'이다. 이렇게 할 수만 있다면, 설령 기존의 환경에 문제가 발생했을지라도, 백업해둔 이미지를 통해 환경을 초기화하고 다시 시작하는 것이 가능하다. 이전에는 이러한 환경 배포를 가상머신(Virtual Machine, 이하 VM)을 이용했었으나, 앞선 글에서 설명했던 바와 같이 느린 부팅 속도, VM 자체의 무거움 등의 문제가 있었다.
(물론 위의 문제점은 'Type1 Hypervisor'를 사용할 수 있다면 겪지 않아도 될 문제점이긴 하나 흔히들 사용하는 Type2 Hypervisor(ex. VMware Workstation)는 무료인 것과 달리 일반 사용자가 사용하기엔 터무니 없이 비싼 금액을 요구한다)
따라서 오늘은 앞선 장점을 가진 도커 이미지를 어떻게 만드는지 실질적인 예시를 보여주고자 한다.
도커 활용법을 설명하기에 앞서 주의해야할 점이 있다.
사용자마다 개발 환경이 다를 수 있는데, 어떤 CPU 아키텍처에서 이미지를 빌드 했는가에 따라 작동 여부가 달라진다. 만약 본인이 이미지를 빌드한 환경은 Intel 혹은 AMD사의 CPU를 기반으로 한다면, M시리즈 칩을 사용하는 mac OS 환경에서는 해당 이미지를 사용할 수 없다. 이는 Intel, AMD CPU의 경우 최근 제품의 경우 amd64 아키텍처지만, M시리즈 칩의 경우 arm64 아키텍처이기 때문이다. 따라서 본인이 빌드한 PC 환경에 대한 사전 파악이 필요하다.
이전 글을 통해 도커 데스크탑을 정상적으로 설치했다면, 먼저 로그인을 진행하고 나면 다음과 같은 인터페이스가 등장한다.
(작성자의 환경은 Mac OS이기 때문에 크로스 컴파일링(cross-compiling)을 진행하지 않는 이상 arm64 아키텍처 기반으로 이미지가 빌드된다)
이제 도커 이미지를 빌드할 준비가 되었다. 이미지 빌드를 위해선 'Dockerfile'라는 이름과 dockerfile 확장자를 가진 파일이 필요하다. 이는 VS Code에서 파일을 만들 당시 확장자 선택을 dockerfile로 지정해주면 된다.
# 1. Base image 설정 (Ubuntu 20.04 사용)
FROM ubuntu:20.04
# 2. 패키지 업데이트 및 필수 패키지 설치
RUN apt-get update && apt-get install -y \
curl \
vim \
git \
build-essential \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# 3. 작업 디렉토리 설정
WORKDIR /app
# 4. 애플리케이션 파일 복사 (현재 디렉토리에서 /app으로 복사)
COPY . /app
# 5. 컨테이너 시작 시 실행할 명령어 설정
CMD ["/bin/bash"]
1. 사용할 이미지를 선언한다 → { 이미지 이름 } : { 태그 (버전) }
보통 본인이 제공하고자 하는 애플리케이션을 지원하는 프레임워크를 기본 이미지로 설정한다.
(작성자는 예시를 보여주기 위해 Ubuntu 이미지를 사용했지만 React, Node js 등과 같은 프레임워크도 기본 이미지로 채택 가능하다)
2. 필요에 따라 설치해야할 패키지들을 설치하는 명령어를 작성한다.
이때 '&&'는 논리 연산자인 AND로 만약 && 이전의 명령어가 정상 실행되지 않았다면 뒤이은 명령어들 모두 실행되지 않는다.
3. 작업 디렉토리를 설정한다.
이는 본인이 이미지를 빌드하겠다고 선언한 현재 디렉토리의 모든 파일과 디렉토리를 컨테이너 환경의 /app이라는 디렉토리에 복사하기 위위해 컨테이너의 디렉토리를 생성하는 명령어이다. 이때, 컨테이너의 작업 디렉토리는 호스트 파일 시스템과 독립적이기 때문에 해당 파일이 이미지로 빌드되고, 그 이미지를 컨테이너화 하여 실행시키게 되면, 설령 컨테이너상에 작업 디렉토리가 없었을지라도 자동으로 생성된다.
4. 현재 디렉토리의 모든 파일과 디렉토리를 컨테이너 작업 디렉토리인 /app에 복사한다.
이때 만약 특정 애플리케이션을 실행시킴에 있어서 불필요한 파일이 존재한다면, 해당 파일을 제외하도록 코드를 작성하면 된다.
5. 컨테이너 시작 시 실행할 명령어이다.
위의 /bin/bash는 Bash shell을 실행시키는 명령어이다. 우리가 흔히 아는 터미널을 실행시키는 명령어이다.
다음으로는 빌드 명령어를 실행해야한다. 이때 빌드 명령어는 Window라면 Window Powershell, mac OS 라면 Terminal에서 다음 명령어를 실행시키면 정상 작동 시 다음 이미지와 같은 실행 과정이 출력된다. 물론 도커 데스크탑에서 지원하는 Terminal 기능을 사용해도 된다.
docker build -t { 원하는 이미지 이름 }:{ 태그 (버전) } { Dockerfile이 존재하는 디렉토리 }
작성자의 경우, 현재 디렉토리에 Dockerfile이 존재했기 때문에 마지막 옵션에 현재 디렉토리를 의미하는 ' . '를 작성했다.
이렇게 빌드가 정상적으로 완료된 후 하단의 명령어를 작성하면 이미지와 같이 본인이 만든 이미지 목록이 출력되는 것을 볼 수 있다. 물론 도커 데스크탑의 Images 카테고리를 클릭해도 빌드한 이미지의 목록이 나온다.
docker image list
이제 컨테이너 실행까지 거의 다 왔다. 다음의 명령어를 실행하면 터미널 기반의 Ubuntu 환경을 제공하는 컨테이너가 실행된다.
docker run -it { 이미지 이름 }:{ 태그 (버전) }
이미지를 보면 사용자가 작성자의 유저 네임인 hwt_wayne99가 root로 바뀌고, PC 이름인 han~이 알 수 없는 숫자로 바뀐 것을 알 수 있다. 이는 명령어 실행 시점을 기반으로 실행 이후에 컨테이너 환경으로 전환되었음을 의미한다.
1. docker run
컨테이너 생성 명령어인 'docker create'와 컨테이너 실행 명령어인 'docker start'를 하나로 합친 명령어이다. 해당 명령어를 실행하면 컨테이너를 생성하고 바로 실행시켜준다.
2. -it
컨테이너 실행 명령어의 옵션이다. 원래는 -i와 -t로 구분되어 있지만, 이와 같이 하나로 이어서 작성도 가능하다.
- -i : 'interactive'의 약자로 컨테이너와의 상호 입출력을 가능하게 하는 옵션이다. 즉, 사용자가 컨테이너와 대화형 개발이 가능하도록 하는 옵션이다.
- -t : 'tty'의 약자로, 터미널을 사용할 수 있도록 하는 옵션이다.
즉 이 둘을 합쳐 '상호 작용 가능한 터미널 환경을 컨테이너가 제공하도록 하는 옵션'이라고 이해하면 되겠다.
도커 데스크탑에서는 Containers 카테고리를 클릭하면 생성된 컨테이너를 확인할 수 있다.
이제 자신의 원격 레포지토리에 업로드 하는 일만 남았다. 여기서 말하는 원격 레포지토리는 '도커 허브(Docker Hub)'이다. 도커 허브의 경우, 도커 데스크탑에 사용했던 아이디와 비밀번호를 사용하면 된다.
도커 허브에 로그인하면 초기에는 아무런 레포지토리가 존재하지 않는다. 따라서 우측 상단의 'Create a repository'를 클릭해서 로컬 환경에서 푸쉬가 가능하도록 레포지토리를 만들어줘야 한다.
기본적으로 네임스페이스는 본인의 유저 네임으로 되어있고, 우리가 설정해줘야 할 부분은 'Repository Name'이다. 여기에 본인이 기존에 로컬에 만들었던 이미지의 이름을 작성하면 된다. 작성자의 예시로 설명하자면 기존에 이미지를 noru0817/example_ubuntu:1.0으로 만들었으니 유저 네임과 태그를 제외한 example_ubuntu만 작성해주면 되는 것이다.
이렇게 작성하는 이유는 도커가 이미지를 푸쉬할 때, 필요한 권한을 유저 네임과 레포지토리 이름이 로컬 환경에 작성한 이미지 이름과 일치하는지 확인하기 때문이다.
정리하자면, { 원격 레포지토리 네임스페이스 이름 } / { 원격 레포지토리 이름 } == { 로컬 환경 이미지 이름 } 관계가 성립해야만 한다.
이렇게 레포지토리를 만들고 나면, 다시 터미널 환경으로 돌아와 나머지 과정을 진행한다. 다음 명령어를 통해 도커 환경에 로그인한다.
docker login -u { 도커 유저 네임 }
위의 이미지처럼 로그인 성공 메세지가 출력되면 정상적으로 로그인된 것이다. 다음의 푸쉬 명령어를 통해 푸쉬를 진행하면 원격 레포지토리에 업로드된다.
docker push { 이미지 이름 }:{ 태그 }
오늘은 이미지를 빌드하고 배포하는 기본 과정을 알아보았다.
앞으로 오늘 글에서 다뤘던 내용을 기반으로 학과 예약 시스템을 온프레미스화 하기 위한 이미지를 빌드하고 배포하는 과정을 작성할 예정이다.
< 학과 예약 시스템 온프레미스화 시작 글 >
https://taks-embdd.tistory.com/1
온프레미스 K8s 환경 구축 - 개발 동기
최근 들어 개인뿐만 아니라 기업에서도 클라우드 환경을 기반으로 한 사업체 설계 및 구현이 만연해졌다.(출처: https://www.idc.com/getdoc.jsp?containerId=prAP52555024) 위의 그래프를 살펴보면 이러한 사회
taks-embdd.tistory.com
'도커' 카테고리의 다른 글
도커(Docker) 기본 개념 & 설치 방법 (6) | 2024.12.27 |
---|