[Docker] 도커를 처음 공부한다면

Sungjin Cho·2024년 3월 19일

Docker

목록 보기
1/3
post-thumbnail

Docker


Docker란?

컨테이너 기반의 오픈소스 가상화 플랫폼이다. 다양한 프로그램, 실행환경을 컨테이너로 추상화하고 동일한 인터페이스를 제공하여 프로그램의 배포 및 관리를 단순하게 해준다.

백엔드 프로그램, 데이터베이스 서버, 메시지 큐 등 어떤 프로그램도 컨테이너로 추상화할 수 있고 어디에서든 실행할 수 있다.

Container

격리된 공간에서 프로세스가 동작하는 기술이다. 기존의 가상화 방식과의 차이점이라면 기존에는 OS를 가상화하였고 컨테이너는 프로세스를 격리 하였다는 것이다.

Image

이미지는 컨테이너 실행에 필요한 파일과 설정값 등을 포함하고 있는 것으로 상태값을 가지지 않고 변하지 않는다.

컨테이너는 이미지를 실행한 상태라고 볼 수 있고 추가되거나 변하는 값은 컨테이너에 저장된다. 가은 이미지에서 여러 개의 컨테이너를 생성할 수 있고 컨테이너의 상태가 바뀌거나 컨테이너가 삭제되더라도 이미지는 변하지 않고 그대로 남아 있다.

ubuntu 이미지는 ubuntu를 실행하기 위한 모든 파일을 가지고 있고 MySQL 이미지는 debian을 기반으로 MySQL을 실행하는데 필요한 파일과 실행 명령어, 포트 정보등을 가지고 있다.

따라서 더 이상 의존성 파일을 컴파일하거나 이것저것 설치할 필요가 없다!

새로운 서버가 추가되면 미리 만들어 놓은 이미지를 다운 받고 컨테이너를 생성만 하면 된다.

레이어 저장 방식

도커 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 수백MB의 용량을 가진다. 기존 이미지에 파일 하나 추가했다고 새로 다운 받기엔 비효율적 → 레이어 개념 사용하고 유니온 파일 시스템을 이용하여 여러 개의 레이어를 하나의 파일 시스템으로 사용할 수 있게 해준다.

이미지는 여러 개의 읽기 전용 레이어로 구성되고 파일이 추가되거나 수정되면 새로운 레이어가 생선된다. ubuntu 이미지가 A + B + C 의 집합이라면 ubuntu 이미지를 베이스로 만든 niginx 이미지는 A + B + C + nginx 가 된다.

이미지 경로

이미지는 url 방식으로 관리하며 태그를 붙일 수 있다. ubuntu 14.04 이미지는 [docker.io/library](http://docker.io/library)/ubuntu:14.04 또는 docker.io/library/ubuntu:trusty 이고 docker.io/library 는 생략 가능하여 ubuntu:14.04 로 사용할 수 있다.

Docker 사용해보기

버전 확인

docker version

클라이언트와 서버로 나뉘어져 있는 이유?

도커는 하나의 실행파일이지만 실제로 클라이언트와 서버 역할을 각각 할 수 있다. 도커 커맨드를 입력하면 도커 클라이언트가 도커 서버로 명령을 전송하고 결과를 받아 터미널에 출력한다.

이러한 설계가 mac이나 windows의 터미널에서 명령어를 입력했을 때 가상 서버에 설치된 도커가 동작하는 이유이다.

컨테이너 실행

도커 실행 명령어

docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]
옵션설명
-ddetached mode 흔히 말하는 백그라운드 모드
-p호스트와 컨테이너의 포트를 연결 (포워딩)
-v호스트와 컨테이너의 디렉토리를 연결 (마운트)
-e컨테이너 내에서 사용할 환경변수 설정
–name컨테이너 이름 설정
–rm프로세스 종료시 컨테이너 자동 제거
-it-i와 -t를 동시에 사용한 것으로 터미널 입력을 위한 옵션
–link컨테이너 연결 [컨테이너명:별칭]

ubuntu 16.04 컨테이너 생성 및 확인

docker run ubuntu:16.04

run 명령어를 사용하면 사용할 이미지가 저장되어 있는지 확인하고 없다면 다운로드한다.

여기서는 이미지를 다운로드 한 후 컨테이너가 정상적으로 실행되었지만 뭘 하라고 명령어를 전달하지 않았기 때문에 컨테이너는 생성되자마자 종료된다.

docker run --rm -it ubuntu:16.04 /bin/bash

/bin/bash 명령어를 입력해 컨테이너 실행

컨테이너 내부에 들어가기 위해 bash 쉘을 실행하고 키보드 입력을 위해 -it 옵션 설정. 프로세스가 종료되면 컨테이너도 자동으로 삭제되도록 —rm 옵션도 설정함

exit 로 bash 쉘을 종료하면 컨테이너도 종료되며 삭제된다.

MySQL 컨테이너 생성 및 확인

-e 옵션을 통해 환경변수 설정, —name 옵션을 이용하여 컨테이너에 읽기 어려운 ID 대신 이름 부여

docker run -d -p 3306:3306 -e 
MYSQL_ALLOW_EMPTY_PASSWORD=true
 --name mysql-docker1 mysql:8.0.25

기본 명령어

  • 컨테이너 목록 확인하기 ps
docker ps [OPTIONS]

옵션 없을 때

ps 명령어는 실행중인 컨테이너 목록을 보여준다. detached mode 로 실행중인 컨테이너들 확인

-a 옵션을 추가하면 종료된 컨테이너도 확인할 수 있다.

  • 컨테이너 중지 stop
docker stop [OPTIONS] CONTAINER [ CONTAINER... ]

실행 중인 컨테이너를 중지하는 명령어이다. 실행 중인 컨테이너를 하나 또는 여러 개(띄어쓰기로 구분) 중지 할 수 있다.

stop 을 통해 컨테이너를 중지 시킨 후 ps 를 했을 때 실행 중인 컨테이너에서 없어진 것을 확인할 수 있다.

  • 컨테이너 제거하기 rm

종료된 컨테이너를 완전히 제거하는 명령어

docker rm [OPTIONS] CONTAINER [CONTAINER...]

determined_lehmann 과 mysql-docker1 컨테이너를 제거했다.

  • 이미지 목록 확인하기 images

도커가 다운로드한 이미지 목록을 보는 명령어

docker images [OPTIONS] [REPOSITORY[:TAG]]

  • 이미지 다운로드 pull

이미지를 다운로드 하는 명령어

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

ubuntu:14.04 다운 받기

docker pull ubuntu:14.04

docker run을 쓰면 없던 이미지를 자동으로 다운 받지만 pull 을 통해 최신 버전으로 다시 다운 받을 수 있다.

  • 이미지 삭제 rmi
docker rmi [OPTIONS] IMAGE [IMAGE...]

images 명령어를 통해 얻은 이미지 목록에서 이미지 ID 를 입력하면 삭제 된다. 단, 컨테이너가 실행중인 이미지는 삭제되지 않는다.

ubuntu:14.04 이미지를 삭제해보았다.

Docker Buildx

Apple M1 기반의 맥북 등장, AWS 그라비톤 서버군의 등장으로 ARM64 기반의 서버들을 지원하기 위한 도커 이미지 빌드가 필수로 되가고 있다.

이를 위한 2가지 방법은

  • docker build 서버를 프로세서 별로 1개씩 만들어준다.
  • docker buildx를 이용하여 멀티 플랫폼 빌드를 한다.

첫 방법은 매우 쉽지만 프로세스가 늘수록 서버의 대수도 늘어나야 한다.

두 번째 방법은 쉬운데 리소스 증가도 없다. 간단하게 더 많은 플랫폼들을 위한 이미지를 만들어 둘 수 있다.

예를 들어 Mac OS 와 라즈베리파이는 각각 amd64와 armv7 으로 아키텍처가 다르다.

Mac OS 에서 이미지를 빌드하여 Docker Hub에 push 하고 라즈베리파이에서 해당 이미지를 pull 받아서 컨테이너를 실행시킬 수 없다.

이를 해결하기 위해 buildx 를 사용하는 나만의 builder 를 생성하여 사용할 수 있다.

Docker buildx로 멀티 아키텍처 플랫폼 image 만들기(2)

Dockerfile

DockerImage를 생성하기 위한 스크립트로서 여러가지 명령어를 토대로 Dockerfile을 작성한 후 빌드하면 Docker는 Dockerfile에 나열된 명령문을 차례대로 수행하며 DockerImage를 생성해준다.

장점

  • 이미지가 어떻게 만들어졌는지 기록
    • 어떠한 애플리케이션을 담고 있는 이미지가 설치 되기 위한 과정은 어떠한지, 중간에 어떠한 과정을 수정해야 하는지 등을 알아야 하는경우 유용
    • raw한 상태의 우분투 이미지에서 자신이 원하는 애플리케이션을 담은 이미지를 만들어내기까지, 그 과정들을 기록하고 수정하며 바꿔나갈 수 있다!
  • 배포에 용이하다.
    • 어떠한 이미지를 배포할 때, 몇 기가씩이나 되는 이미지 파일 자체를 배포하기 보다는 그 이미지를 만들 수 있는 스크립트인 Dockerfile만을 배포하는 것이 매우 편리하다.
    • 사용자는 그 스크립트를 실행시키기만 하면 Dockerfile에 해당하는 이미지를 얻을 수 있다.
  • 컨테이너가 특정 행동을 수행하도록 한다.
    • 컨테이너 환경에서 애플리케이션을 개발하다 보면, 특정 행동을 취하도록 하는 컨테이너를 만들어야 할 때가 있다.

문법

FROM

  • 생성할 image의 베이스가 되는 image를 설정한다.
  • Dockerfile 작성시 필수로 설정해야 한다.
  • 멀티 스테이지 빌드 시 여러 개를 사용할 수 있다.
FROM mirror.gcr.io/library/alpine:3.16

LABEL

  • 생성할 image에 key=value 형식으로 metadata를 추가한다.
  • 다수의 metadata를 추가할 수 있다.
LABEL maintainer="hackerpark.tistory.com"
LABEL appversion="1.3.1"

ENV

  • 생성할 image에 추가할 환경변수 설정
  • ENV에 설정된 환경변수는 image를 통해 생성된 container 내부에서도 사용 가능
  • ENV가 설정된 image로 container를 생성할 때 옵션을 사용하여 Dockerfile에 설정한 ENV를 오버라이드 할 수 있다. (Default ENV 설정이라고 생각하자)
ENV CUSTOM_ENV value
ENV MY_ENV="custom_value"

ARG

  • Dockerfile 내부에서 사용할 변수를 key=value 또는 key 형태로 설정한다.
  • ARG를 key만 입력하면 build시 해당 key 값의 argument가 입력될 것이라는 명시를 나타낸다.
  • ARG를 key=value까지 입력한 경우 build시 argument가 입력되지 않아도 value로 적용된다.
  • ARG를 key=value로 입력한 상태로 build시 argument를 입력할 경우 오버라이드된다.
ARG ALPINEVER=3.16
FROM mirror.gcr.io/library/alpine:${ALPINEVER}

RUN

  • image를 만드는 과정(layer)에서 FROM으로 설정된 베이스 image에 추가로 실행할 명령어를 입력한다.
FROM mirror.gcr.io/library/alpine:3.16
RUN apk --no-cache add libc6-compat curl && \
  rm -rf /var/cache/apk/*

USER

  • image를 만드는 과정(layer)에서 사용할 사용자 계정을 설정한다.
    • USER 를 사용하기 위해서는 해당 USER가 기존 layer에 생성되어 있어야 한다.
  • USER 설정 이후 아래 Dockerfile(layer)에 모두 적용된다.
  • USER를 설정하지 않으면 슈퍼 유저로 진행된다.
RUN adduser hackerpark --disabled-password --gecos ""

WORKDIR

  • image를 만드는 과정(layer)에서 기본으로 작업할 디렉토리를 설정한다.
    • 쉘 스크립트의 cd와 유사하다.
  • WORKDIR 설정 이후 아래 Dockerfile(layer)에 모두 적용된다.
# create /tmp/test.txt

CMD

  • image를 통해 생성되는 container에서 실행할 command를 입력한다.
  • Dockerfile 내부에서 한 번만 사용 가능하다. (생략 가능)
  • container 실행 시 cmd를 입력하는 경우 CMD 내용은 오버라이드(override)된다.
  • ENTRYPOINT 설정 시 CMD의 내용이 ENTRYPOINT의 파라미터로 변경된다.
CMD ["/bin/sh", "-c", "ls /"]

0개의 댓글