기타

Docker의 개념과 사용법 핵심정리

서히! 2025. 2. 28. 17:07

Docker란

Docker는 컨테이너 기반 가상화 플랫폼으로, 응용 프로그램과 종속성을 격리된 환경인 컨테이너로 패키징하여 실행하는 기술

→ Container: 가상화 기술을 이용하여 어플리케이션과 개발 환경을 격리된 공간에서 실행하는 단위

 

📌 Virtual Machine vs Docker

 

  • Virtual Machine
    • Hypervisor(하이퍼바이저)를 이용하여 여러 개의 운영체제(=가상 머신이라는 단위로 구별)를 하나의 호스트에서 생성해서 사용하는 방식
    • 시스템을 가상화하고 독립된 공간을 생성하는 작업은 하이퍼바이저를 거치므로 성능 손실 증가
    • 게스트 운영체제를 사용하기 위한 라이브러리, 커널 등을 전부 포함하기 때문에 배포하기 위한 이미지의 크기도 커짐
      • Guest OS(게스트 운영체제): 하이퍼바이저에 의해 생성되고 관리되는 운영체제
         각 게스트 운영체제는 다른 게스트 운영체제와는 완전히 독립된 공간과 시스템 자원을 할당받아 사용 
        ex. VirtualBox, VMware
  • Docker Container
    • 리눅스 자체 기능인 chroot, namespace, cgroup을 사용하여 프로세스 단위의 격리 환경을 만드므로 성능 손실 X
    • 가상머신과 달리 커널을 공유해서 사용 + 컨테이너에는 라이브러리와 실행 파일만 존재 → 이미지 용량 축소
💡 배포하는 시간이 가상 머신에 비해 빠르고, 사용할 때의 성능 손실도 거의 없기 때문에 Docker를 사용

 

Docker 구성 요소

  • Docker Client: Docker 설치한게 client이며, build, pull, run

Image, Container

이미지와 컨테이너는 1:N 관계로, 운영체제에서의 프로그램 ↔ 프로세스, 객체지향 프로그래밍에서의 클래스 ↔ 인스턴스의 관계와 비슷하다고 생각하면 편함

  • Docker File → Docker Image: Docker File은 도커 이미지를 만들 때 사용하는 파일 (docker build)
  • Docker Image→ Docker Container: Docker Image 실행 (docker run)
Image

 

컨테이너를 생성하기 위한 파일 시스템과 실행할 어플리케이션의 소스 코드, 라이브러리, 환경 설정 등의 모든 것을 포함하는 템플릿

  • 읽기 전용
  • 여러 레이어로 구성되어 있는데, 각 레이어는 변경사항이 있는 파일 또는 설정을 포함하여 최종 이미지를 구성
  • 이런 이미지는 
[저장소 이름]/[이미지 이름]:태그
- 저장소 이름: 이미지가 저장된 장소, 저장소 이름이 명시되지 않은 이미지는 도커 허브의 공식 이미지를 의미
- 이미지 이름: 해당 이미지가 어떤 역할을 하는지 나타내며 필수로 설정 ex. pytorch:1.7.1-cuda11.0-cudnn8-devel
- 태그: 이미지의 버전을 의미, default는 latest (위 예시에서는 1.7.1 버전)

 

Container

 

이미지를 실행한 격리된 프로세스 환경으로, 도커 이미지를 실행하면 컨테이너가 됨

  • 이미지는 컨테이너의 파일 시스템과 어플리케이션 코드 등을 제공 → 컨테이너는 이 이미지를 기반으로 생성
  • 가상화된 환경에서 동작하며, 호스트 운영체제의 리소스와 격리된 리소스를 사용
  • 각 컨테이너는 독립된 환경에서 실행되어 다른 컨테이너에 영향 X
  • 컨테이너가 실행되면 읽기/쓰기가 가능

[ 존재하는 이미지로 container 생성 ]

docker run --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES={GPU_번호} --volume ~/workspace:/workspace -it --rm --name {컨테이너_이름} {이미지_이름}

 

  • --rm이 있으면 container 종료시 삭제가 됨
  • ctrl+p+q 사용해서 컨테이너 삭제 안하고 나가기
  • docker exec -it 컨테이너 이름 /bin/bash 하면 접속 가능

docker logs -f 컨테이너 이름: 컨테이너 로그를 실시간으로 다 볼 수 있음

 


Docker 이미지 다운로드 + 컨테이너 실행

  • 도커 이미지 명령어
    • 이미지 검색: docker search 이미지_이름
    • 이미지 다운로드: docker pull 이미지_이름:태그
    • 이미지 목록 보기: docker images
    • 이미지 삭제: docker rm 이미지_이름:태그
  • 도커 컨테이너 명령어
    • 컨테이너 생성 및 실행: docker run 이미지_이름:태그
    • 컨테이너 목록 보기: docker ps
      • '-a' : 모든 컨테이너 목록 보기 (stop된 것까지)
    • 컨테이너 중지: docker stop 컨테이너_ID 또는 컨테이너_이름
    • 컨테이너 시작: docker start 컨테이너_ID 또는 컨테이너_이름
    • 컨테이너 재시작: docker restart 컨테이너_ID 또는 컨테이너_이름
    • 컨테이너 삭제: docker rm 컨테이너_ID 또는 컨테이너_이름
    • 컨테이너 로그 보기: docker logs 컨테이너_ID 또는 컨테이너_이름
  • run 명령어 옵션
    • 컨테이너 이름 설정: --name 컨테이너_이름
    • 컨테이너 백그라운드 모드로 실행: -d (또는 --detach)
    • 호스트와 컨테이너 간의 포트 매핑 설정: -p (또는 --publish) 호스트_포트:컨테이너_포트 (ex. -p 5000:5000)
      →  호스트의 특정 포트를 컨테이너 내부의 포트와 연결하여 외부와 컨테이너 간 통신
    • 호스트와 컨테이너 간의 볼륨 매핑을 설정: -v (또는 --volume) 호스트_경로:컨테이너_경로
      호스트의 경로와 컨테이너의 경로를 연결하여 데이터를 공유하거나 저장
    • 컨테이너 내부에서 사용할 환경 변수를 설정: -e (또는 --env) -e 변수=값
       컨테이너 내부의 프로세스에서 환경 변수를 사용
    • 컨테이너와 상호 작용하는 대화형 모드로 컨테이너 내부의 터미널에 접속: -it (또는 --interactive와 --tty)
      컨테이너 내부에서 명령어를 실행하고 터미널 세션을 유지

      💡 프로세스가 종료되지 않게 컨테이너를 생성
  • docker exec 명령어
    • 이미 실행 중인 컨테이너의 터미널에 현재 터미널 세션을 연결
    • 컨테이너 내부에서 실행되고 있는 프로세스의 표준 입력(stdin), 출력(stdout), 에러(stderr)를 현재 터미널에 연결
    • 컨테이너의 터미널에 종속되며, 컨테이너 터미널에서 나오면 현재 터미널 세션이 종료됨 
      docker exec -it 컨테이너_ID 또는 컨테이너_이름 /bin/bash

       

       
  • docker attach 명령어
    • 이미 실행 중인 컨테이너 내에서 새로운 명령을 실행하기 위해 사용
    • 터미널 세션을 연결하지 않고, 새로운 명령을 실행한 결과만을 보여줌
    • -it 옵션을 사용하여 인터랙티브 모드와 가상 터미널을 사용할 수 있음
    • 컨테이너 터미널과는 독립적으로 동작하며, 명령 실행 후에도 컨테이너가 종료되지 않는다
    • docker attach 컨테이너_ID 또는 컨테이너_이름