dev-course day74

2rlokr·2025년 6월 20일

dev-course

목록 보기
43/43
post-thumbnail

오늘 배운 것

Docker

도커는 컨테이너 기반의 가상화 기술을 제공하는 플랫폼으로, 애플리케이션의 배포와 실행을 간소화하기 위해 개발되었다. 도커는 경량화된 컨테이너를 사용하여 애플리케이션과 필요한 모든 의존성을 하나의 단위로 패키징하고, 이를 어디서나 동일한 환경에서 실행할 수 있도록 한다.

  • 애플리케이션과 그 실행에 필요한 라이브러리, 설정 파일 등을 포함한 컨테이너(Container)를 생성하고 관리할 수 있는 플랫폼이다.
  • 여기서 컨테이너는 리눅스 컨테이너(LXC)를 의미한다.
  • 즉, 도커는 리눅스 컨테이너 기술을 보다 효율적으로 이용할 수 있도록 기능을 제공하도록 출시된 일종의 제품이다.

구성

  • 크게 도커 엔진(Docker Engine), 이미지(Image), 컨테이너(Container), 도커 레지스트리(Docker Registry), 그리고 네트워크(Network)와 볼륨(Volumne)으로 구성되어있다.

도커 엔진 (Docker Engine)

도커 엔진은 도커의 핵심 구성 요소로, 도커에서 컨테이너를 생성하고, 이미지를 빌드하고, 네트워크 및 스토리지를 관리하는 모든 작업을 수행한다.

  • 도커엔진은 클라이언트-서버 아키텍처를 기반으로 설계되어있다.
  • 도커 엔진은 대략적으로 도커 데몬, 도커 CLI, REST API로 구성되어 있다.


도커 데몬 (Docker Daemon)

  • 도커 엔진의 중심이 되는 프로세스로서, 직접적으로 컨테이너 및 이미지를 생성, 실행 관리하는 역할을 수행한다.
  • 백그라운드에서 실행되며, 클라이언트가 CLI를 통해 명령을 전달하면 API를 통하여 전달받은 요청을 처리하는 식으로 동작한다.

도커 CLI (Docker CLI)

  • 클라이언트가 도커 데몬과 상호작용할 수 있도록 지원하는 명령행 도구이다.
  • 클라이언트는 도커 CLI를 통해 컨테이너 생성, 이미지 빌드, 네트워크 관리 등을 도커 데몬에게 API로서 명령을 전달할 수 있다.

REST API

  • 도커 데몬과 외부 클라이언트 간의 통신을 가능하게 하는 인터페이스이다.
  • REST API를 이용하면 애플리케이션에서 직접 도커 데몬과 통신하는 것이 가능하다.

도커 이미지 (Docker Image)

도커 이미지는 도커 컨테이너의 실행 환경을 정의하는 템플릿 역할이다. 이미지는 컨테이너를 생성하는 데 필요한 모든 정보를 포함하고 있으며, 애플리케이션 코드, 런타임, 라이브러리, 환경 변수, 구성 파일 등을 포함한 독립적이고 재사용 가능한 단위로 설계되어 있다.

불변성

  • 도커 이미지는 불변성을 띄는 읽기 전용 상태의 템플릿이다.
  • 도커는 도커 이미지를 이용해서 컨테이너를 실행하는 방식으로 동작한다.
    • 다만, 도커 이미지는 컨테이너 실행에 필수적인 내용을 포함하고는 있지만 상태값은 갖지 않는다.

계층화 구조

  • 계층화된 구조(Layered Structure)를 가지며, 변경 사항만 추가하는 방식으로 관리된다.
  • 도커 이미지 내부에서 이러한 계층(읽기 전용)을 쌓아가며 하나의 전체적인 이미지를 생성하는 방식이다.
  • 새로운 변경 사항이 있으면 기존 계층을 수정하는 대신 새로운 계층이 생성된다.
    -> 이러한 방식은 이미지가 변경될 때마다 전체를 다시 빌드할 필요 없이, 변경된 부분만 추가하는 방식으로 동작할 수 있도록 한다.

도커 허브

  • 이미지는 일반적으로 도커 허브와 같은 레지스트리에 저장되고 관리된다.
  • 전 세계 개발자들이 이미지를 공유하고 다운로드할 수 있는 중앙 저장소 역할을 한다.

도커 레지스트리 (Docker Registry)

도커 이미지를 저장하고 관리하는 저장소 역할을 한다. 애플리케이션을 컨테이너화할 때 생성한 도커 이미지를 다른 환경에서 재사용하기 위해 필요한 배포 공간이며, 이러한 이미지를 효율적으로 관리하고, 네트워크를 통해 접근할 수 있도록 지원하는 시스템이다.

  • 도커 허브와 같은 공개 레지스트리(Public Registry)와, 사내망 같은 별도의 환경에서 운영되는 개인 레지스트리(Private Registry)로 나뉜다.
  • 도커 레지스트리는 이미지의 태그(Tag)를 통해 버전별로 구분하여 이미지를 관리할 수 있도록 도와준다.
    • 도커 이미지를 태그를 이용하여 버전으로서 관리하고 이미지를 이용하는 클라이언트는 이러한 태그를 통하여 특정 시점의 이미지를 다운로드 받고 이용하는 것이 가능해진다.

Dockerfile

도커 이미지를 생성하기 위한 파일로서, 이미지 빌드 과정에서 필요한 명령어와 설정을 정의한다. 확장자 없이 Dockerfile이라고 명명하여 사용한다. (필요에 따라서 언더바_로 이름을 추가할 수도 있다.)

  • DSL(Domain Specific Language)로 작성된다.
    • 특정한 문제 영역을 해결하거나 특정 도메인에 특화된 작업을 수행하기 위해 설계된 프로그래밍 언어 또는 스크립트 언어
    • 즉, 어떠한 목적이 있고 그 목적만 달성할 수 있게 만들어진 일종의 스크립트 언어
  • Dockerfile 내 DSL로 작성된 각각의 명령행은 이미지를 실행하는 과정에서 해당하는 명령을 수행하여 레이어를 생성하는 데 사용된다.
  • 이 때, 이전 계층이 변경되지 않으면 캐싱된 결과를 재사용하는데, 이로 인해 명령어 순서가 빌드 성능에 영향을 미칠 수 있다.
  • Dockerfile이 파일 형태로서 도커 이미지를 관리할 수 있게 함으로서, VCS의 도움을 받아 이미지의 구성에 누구나 쉽게 참여할 수 있게 하고, 버전관리가 가능해지고 오픈소스 형태로 관리할 수 있도록 구성된다.
FROM			기초가 될 이미지로부터 하나의 레이어를 생성 

CMD 			컨테이너가 시작되는 시점에 기본적으로 실행할 명령어 지정 (명령어를 덮어쓴다.)

ENTRY POINT		컨테이너가 시작되는 시점에 기본적으로 실행할 명령어 지정 (명령어를 덮어쓸 수 없다.)

RUN				이미지를 빌드할 때 실행할 명령어 지정

WORKDIR			작업할 디렉토리 설정

COPY			호스트 환경의 파일을 레이어로 복사

도커 컨테이너 (Docker Container)

리눅스 컨테이너와 같이 애플리케이션과 애플리케이션의 실행 환경을 호스트 환경으로부터 격리하여 도커 이미지로부터 실행된 결과물이다. 도커 이미지로부터 생성되며, 이미지에 저장된 애플리케이션과 설정을 기반으로 동작한다. 컨테이너는 운영체제 수준에서 프로세스를 격리하여 실행하기 때문에, 가상머신처럼 별도의 운영 체제를 부팅할 필요없이 호스트 운영체제의 커널을 공유한다.

쓰기 계층

  • 컨테이너는 이미지의 읽기 전용 계층 위에 쓰기 가능한 계층을 추가하여 실행된다.
  • 컨테이너 실행 중 발생하는 모든 변경 사항은 쓰기 계층에 저장되지만, 이러한 구조는 컨테이너가 종료되면 변경사항이 사라진다.
  • 만약 컨테이너의 데이터를 유지하고 싶다면, 도커 볼륨을 사용하여 데이터를 영구적으로 저장할 수 있다.

격리 기능

  • 컨테이너는 호스트 운영 체제의 커널을 공유하지만, 네트워크, 파일 시스템, 프로세스 공간 등은 격리되어 있다.
  • 네트워크 격리를 통해 각 컨테이너는 고유한 네트워크 인터페이스를 가지며, 필요에 따라 포트를 매핑하여 외부와 통신할 수 있다.
  • 파일 시스템 격리를 통해 각 컨테이너는 독립적인 파일 시스템을 가지며, 호스트 파일 시스템과 공유하거나 격리된 환경에서 작동할 수 있다.

-> 이러한 격리 기능으로 컨테이너 간의 간섭을 방지한다.

컨테이너 관리

  • 도커 컨테이너는 도커 CLI를 통해 쉽게 관리할 수 있다.
  • docker run : 이미지 기반 컨테이너 생성, 실행
  • docker stop, docker rm : 컨테이너 중지, 삭제

도커 네트워크 (Docker Network)

컨테이너는 기본적으로 서로 격리된 환경에서 실행되지만, 도커 네트워크를 통해 서로 데이터를 주고받거나 외부와 통신할 수 있다.

  • 도커는 기본적으로 컨테이너가 시작될 때 자동으로 네트워크를 생성하고, 컨테이너를 이 네트워크에 연결한다.
  • 도커가 제공하는 네트워크 드라이버 중 가장 기본적인 것은 브리지 네트워크이다.
    • 브리지 네트워크 : 동일한 호스트 내에서 실행되는 컨테이너 간의 통신을 지원하며, 기본적으로 컨테이너는 이 네트워크에 연결된다.
  • 브리지 네트워크는 격리된 환경을 제공하기 때문에, 컨테이너는 네트워크를 공유하지 않는 한 외부 컨테이너와 통신할 수 없다.
Bridge Network		하나의 Host에서 여러 컨테이너 통신

Host Network		Host와 동일한 네트워크에서 컨테이너 연결

None Network		네트워크 없이 컨테이너의 IO만 사용

네트워크 구성

  • 컨테이너 간의 네트워크 연결은 IP 주소나 도메인 이름을 통해 이루어진다.
  • 도커는 컨테이너에 고유한 IP 주소를 할당하며, 기본적으로 도커 컨테이너 내에서 DNS 서비스를 제공하여 컨테이너 이름을 IP주소로 변환한다.
    -> 사용자가 복잡한 IP 주소를 기억하지 않아도 되고, 컨테이너 이름을 사용하여 간단하게 통신할 수 있다.

도커 볼륨 (Docker Volume)

컨테이너가 생기고 삭제되는 동안에도 데이터를 지속적으로 저장하고 관리할 수 있도록 도와주는 도커의 스토리지 기능이다. 일반적으로 컨테이너는 가상화된 파일 시스템 위에서 동작하며, 컨테이너 내부에 저장된 데이터는 컨테이너가 삭제되면 함께 사라진다.

  • 도커의 볼륨은 컨테이너와 독립적으로 관리되며, 컨테이너가 삭제되더라도 데이터를 영속성을 보장한다.
  • 도커 볼륨은 도커가 관리하는 파일 시스템 경로에 데이터를 저장한다. 도커 볼륨은 도커 데몬이 관리하기 때문에 사용자는 볼륨을 쉽게 생성하고 삭제하며, 여러 컨테이너에서 동일한 볼륨을 공유하 수 있다.
  • -v 옵션을 사용하여 볼륨을 컨테이너에 마운트할 수 있다.
  • 도커 컴포즈(Docker compose)를 사용하면 YAML 파일에서 볼륨을 정의하고 관리할 수 있다.

실습

이미지 풀

docker pull {이미지 이름}
  • docker hub에서 가져온다.

이미지 리스트 보기

docker images
docker image list
docker image ls

이미지 리스트 중에 찾기

docker images --filter reference=hello-world
docker images --filter reference="my*"
docker images -f reference=hello-world
docker images | grep hello

이미지 삭제

docker rmi nginx
docker rmi alpine:tag1 alpine:tag2
docker rmi alpine:tag1 && alpine:tag2 # 앞에 것이 성공해야 뒤에 걸 실행함.
  • tag가 특별히 명시되어있지 않으면 알아서 자동으로 latest를 붙여준다.
  • 공백을 두고 지우고 싶은 이미지를 복수개 넣을 수 있다.

태그 다르게 이미지 만들기

docker tag alpine:latest alpine:tag1

도커 컨테이너 만들기

docker container create {이미지 이름}

컨테이너 리스트

docker container list
docker ps # 실행 중인 컨테이너 프로세스
docker ps -a # 전체

컨테이너 필터링

docker ps -a --filter "name=peaceful"

컨테이너 시작

docker start peaceful_hugle

컨테이너 실행

docker run docker.io/library/ubuntu:24.04
docker run --name exp-ubt-1 ubuntu:24.04

docker run \
--name exp-ubt-3 \
--interactive \
ubuntu:24.04 \
bash

docker run -it --name exp-ubt-5 ubuntu:24:04 bash
  • 로컬에서 ubuntu:24.04를 찾고 없으면 pull 당긴다.
  • 컨테이너에 이름을 지어줄 수 있다.
  • 우분투 배시가 실행되게 된다.

컨테이너 중지

docker stop exp-ubt-6

컨테이너 정지

docker [container] pause
docker unpause exp-ubt-7
  • 정지하면, 여전히 status는 Up으로 남아있고, unpause를 할 시 다시 재개할 수 있다.

컨테이너 삭제

docker rm exp-ubt-8
docker rm -f exp-ubt-8
docker container prune # Stopped 된 컨테이너들 다 지움.

네트워크 리스트

docker network list

네트워크 필터링

docker network list --filter driver=bridge

네트워크 생성

docker network create net_1
docker network create -d bridge net_2

docker network create -d host net_3
  • default로 bridge 로 만들어준다.
  • d로 지정해줄 수도 있다.
  • host 네트워크는 한 개만 가지고 있을 수 있다.

네트워크 삭제

docker network rm net_2

볼륨 리스트 조회

docker volume ls
docker volume list

볼륨 필터링

docker volume ls | grep vol_1
docker volume ls -f driver=local

볼륨 생성

docker volume create vol_2

느낀점

으아.. 어렵다 ! 막 이해가 안된다 어렵다는 아니고, 개념이 헷갈려서 계속 돌아가서 확인하고, 정리하고 이래야 하는 느낌이다. 리눅스 컨테이너가 뭔지, 컨테이너가 뭔지 개념을 확 머리에 넣어야 할 것 같다.

그래도 궁금했던 파트인데, 도커를 자세히 배워볼 수 있어서 너무 좋은 것 같다 !! 가상화 이런 건 누가 생각해냈을까.. 진짜 멋있다.. 대단하네.. 뇌도 가상화가 안되려나?

0개의 댓글