Docker 100% 사용법

Ji_min·2021년 5월 23일
0

CS 공부

목록 보기
7/9

(100프로는 아니고 한 10프로 정도 사용법..?)

1. 도커란?

WHAT

"Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly."

도커는 인프라 리소스로부터 어플리케이션을 분리해서 개발할 수 있는 환경을 제공해주는 오픈 소스 플랫폼이라고 할 수 있다.

WHY

"With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production."

프레임워크나 라이브러리의 버전이 일치하지 않아서 개발 서버에서 실행된 프로그램이 프로덕션 서버에서는 실행되지 않는 문제에 대한 솔루션을 제공한다.

HOW

"Docker provides the ability to package and run an application in a loosely isolated environment called a container. The isolation and security allow you to run many containers simultaneously on a given host. Containers are lightweight and contain everything needed to run the application, so you do not need to rely on what is currently installed on the host. You can easily share containers while you work, and be sure that everyone you share with gets the same container that works in the same way."

  • 리소스로부터 어플리케이션을 격리시킬 수 있는 컨테이너 환경을 제공한다.
  • 컨테이너는 독립적인 환경이기 때문에 특정 호스트의 리소스에 의존할 필요가 없다.
  • 반대로 말해, 어느 호스트에서든 동일한 개발 및 실행 환경을 보장해준다.

가상 머신 vs. 컨테이너

가상 머신(Virtual Machine)

  • CPU와 같은 하드웨어 자원을 가상화해서 새롭게 컴퓨터 한 대를 만드는 것
  • OS 위에 새로운 OS를 만들어서 독립적인 환경을 구축함
  • 참고 가상화란? 물리 리소스를 추상화하는 것. 추상화한다는 말의 의미는 간단히 말해 구체적인 실체를 가진 자원에서 기능이나 특징만을 뽑아내 재사용하기 위해 개념 단위로 함수화하는 것이라고 할 수 있음

컨테이너(Container)

  • 리눅스의 컨테이너 기술을 이용해서 하드웨어 자원을 가상화하지 않고 프로세스만 격리해서 빠르게 실행시키는 것
  • 기존의 운영체제 안에서 프로세스를 격리시켜서 마치 가상 머신을 설치하는 것과 동일한 효과를 냄
  • 컨테이너는 기존의 시스템 자원을 공유하기 때문에 가상 머신이 아니라 리얼 머신에서 돌아감
  • 하나의 OS상에서 여러 컨테이너가 돌아갈 수 있기 때문에 리소스를 한 곳에서 관리하기 쉬움
  • 용량이 크고 느린 가상 머신의 단점을 보완할 수 있음

도커 이미지와 도커 허브

도커 이미지는 어플리케이션 실행 환경을 구축해주는 파일이라고 생각하면 되고, 도커 허브는 그런 이미지들을 업로드해놓고 받아서 쓸 수 있는 플랫폼이라고 할 수 있다.

쉽게 말해서 깃과 깃허브의 관계처럼, 파일을 만들어서 클라우드에 올려놓고 다른 곳에서 파일을 가져다 쓸 수 있게 해놓은 것이라고 생각하면 된다.

작업 플로우 : 도커 이미지 파일 작성 → 도커 허브에 업로드(push) → 도커 허브에서 도커 이미지를 받아와서(pull) 사용

도커가 컨테이너 기술을 개발했다기 보다는, 리눅스 자체에 이미 있던 컨테이너 기술을 활용하면서 이를 도커 허브와 연계시켜서 좀 더 편하게 컨테이너를 사용할 수 있게 한 것이라고 할 수 있다.

이미지 vs. 컨테이너

  • 이미지 : 개발 환경을 구축하는 실행 파일
  • 컨테이너 : 그 이미지를 실행한 상태, 즉 프로세스
  • 하나의 이미지로 여러 개의 컨테이너를 만들 수 있음

2. 도커 사용법 : 설치부터 실행까지

도커 설치하기

WSL2 환경에서 도커를 설치하는 법을 설명하려고 한다.

  1. 도커 데스크탑을 다운받아 설치한다. 이 때 Install required Windows components for WSL 2 옵션을 선택하도록 한다.
  2. 설치가 완료되면 도커 데스크탑을 실행시키고 Settings → General에서 다음과 같이 되어 있는지 확인해보고 체크가 안 되어 있으면 체크한 후 Apply & Restart 한다.
  3. 명령 프롬프트에서 docker를 입력해서 커맨드 옵션이 뜨면 설치 완료이다.

도커 기본 명령어

이미지 관련 명령어

docker images : 가지고 있는 이미지 확인하기 → 참고로 TAG는 버전을 의미

docker image push image_name:tag : 도커 허브의 저장소에 이미지 올리기

docker pull image_name:tag : 저장소에서 이미지 받아오기

docker search TERM : 이미지 검색하기 → 이미지 이름 앞에 아이디가 없으면 공식 이미지이고 아이디가 있으면 사용자 커스터마이징 이미지

docker build -t image_name:tag . : 이미지 생성하기

  • -t : 이름 지정하는 옵션
  • . : 현재 디렉토리의 Dockerfile을 읽어서 이미지를 만듦
  • -f : 읽어올 파일을 알려주는 옵션. 디폴트로 Dockerfile이라는 파일을 찾아서 읽는데, -f this_file 이라는 옵션을 주면 해당 파일을 읽고 실행시킨다.

docker rmi image_name : 이미지 삭제하기

참고 alpine 이미지 : 일반적으로 우분투 같은 base image를 받으면 기본적인 기능이 포함되어 있는데, 따로 설치하지 않아도 되니까 편리하기는 한데 용량이 너무 커지는 문제가 있다. alpine 이미지는 이런 기본 기능을 전부 제외하고 오로지 우분투만 받아오는 것이다.

컨테이너 관련 명령어

docker ps : 컨테이너 확인하기

  • -a : 종료된 컨테이너까지 확인하기

docker run -it image_name:tag /bin/bash : 컨테이너 생성 및 실행하기

  • -i : --interactive. 사용자로부터 인풋을 받도록 하는 옵션
  • -t : --tty. 터미널을 여는 옵션
  • --name : 컨테이너의 이름을 지정하는 옵션
  • --rm : 도커 컨테이너가 실행을 끝내고 종료되면 컨테이너를 삭제하는 옵션
  • 마지막의 /bin/bash는 커맨드이다.
  • -d : 데몬(daemon, detached mode)으로 백그라운드에서 실행시키는 옵션
  • -p : 포트 넘버 지정하는 옵션 ex) -p 8000:80 : 외부에서(로컬에서) 8000번으로 들어왔을 때 도커 컨테이너의 80번 포트로 포트 포워딩을 해주겠다는 의미

docker start container_name : 도커 컨테이너 실행시키기

docker attach container_name : 컨테이너 안으로 들어가기

  • exit or ctrl+d : 컨테이너에서 나가기 + 컨테이너 종료
  • 컨테이너에 들어간 상태에서 컨테이너를 종료시키지 않고 빠져나오려면 ctrl + P + Q 를 입력하면 됨
  • 참고 run vs start : start 명령어는 이미 생성되어 있는 컨테이너를 실행시키는 것이고, run 명령어는 이미지를 가지고 새롭게 컨테이너를 만들어서 실행시키는 것. 여기에 -it 옵션까지 더하면 컨테이너 생성 + start + attach 라고 생각하면 됨.

docker stop container_name : 컨테이너 실행 중지시키기

docker rm container_name : 컨테이너 삭제하기

참고 : 하나의 이미지로 여러 개의 컨테이너를 실행할 수 있음. 그래서 컨테이너를 삭제하는 것과 이미지를 삭제하는 것은 완전히 다른 개념!

docker exec container_name COMMAND : 실행 중인 도커 컨테이너 밖에서 컨테이너 안으로 명령 하기 ex) docker exec container_name touch /hello.txt : 컨테이너에 hello.txt 파일을 생성해라 → docker attach로 들어가서 확인해보면 해당 파일이 생성되어 있음

도커 파일 작성하기

Dockerfile이란 빌드할 이미지에 어떤 패키지들이 들어갈 지에 대한 내용이 담긴 파일이다.

예를 들어, ubuntu:latest 이미지를 받아와서 컨테이너를 생성하면 해당 컨테이너에는 우분투 환경을 제외하고는 아무것도 설치되어 있지 않다. 여기에 git을 설치하고 싶다고 한다면 컨테이너에 들어가서 일일이 설치를 해줘야 하는데, 이런 수고로운 작업을 하나의 파일을 만들어서 거기에 설치할 패키지의 목록을 넣어둠으로써 자동화시키는 것이라고 할 수 있다.

따라서 위의 예시를 그대로 명령어로 표현해보면 다음과 같다.

$ docker run -it ubuntu:latest bash
>> apt-get update
>> apt-get install git 

얘를 아래와 같이 하나의 파일 안에 넣은 게 Dockerfile이다.

# Base Image 지정
FROM ubuntu:latest

# 명령어 
RUN apt-get update
RUN apt-get install git
# 위의 이미지 파일을 가지고 ubuntu:git-ver라는 이름의 이미지 만들기 
docker build -t ubuntu:git-ver .

VSCode에서 도커 사용하기

VSCode에서 도커를 GUI로 쉽게 사용하기 위한 익스텐션이 두 개 있다.

3. 도커 컴포즈란?

WHAT

도커 명령어 옵션들을 하나의 파일(docker-compose.yml) 안에 key : value의 형식으로 정리해놓고, 도커 컨테이너를 실행시킬 때마다 일일이 옵션을 입력할 필요 없이 docker-compose 명령어를 통해 컨테이너를 실행시킬 수 있도록 하는 것

특히 여러 개의 컨테이너를 동시에 띄워야 할 때, 하나의 파일 안에 각 컨테이너의 옵션들을 정의해놓고 한 번에 실행시킬 수 있어서 편리함

도커 파일(Dockerfile) vs. 도커 컴포즈 파일(docker-compose.yml)

  • Dockerfile : 이미지를 정의하는 파일 → 이미지 빌드가 목적
  • docker-compose.yml : 컨테이너 옵션들을 정의하는 파일 → 컨테이너 생성 및 실행이 목적

도커 컴포즈 파일 작성하기

# docker run을 사용할 경우
docker run -d \
       --name db \
       -p 5432:5432 \
       -v ./data/db:/var/lib/postgresql/data \
       -e POSTGRES_DB=postgres \
       -e POSTGRES_USER=postgres \
       -e POSTGRES_PASSWORD=password
       postgres
# docker-compose.yml 파일을 만들어서 실행시킬 경우
version: "3.9"
   
services:
  db:
    image: postgres
    volumes:
      - ./data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
    ports:
    - "5432:5432"
  djangoapp:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/backend  
    ports:
      - "8000:8000"
    depends_on:
      - db
  • version : 파일 규격 버전을 정의하는데, 레퍼런스를 참고해서 도커 버전에 맞게 적어 넣으면 된다.
  • services : 실행시킬 컨테이너를 정의하는 공간
  • volumes : 컨테이너를 실행시킬 때, 컨테이너 안에서 생성된 데이터는 컨테이너가 종료되면 함께 사라진다. 만약 데이터를 백업해두고 싶다면 로컬 경로와 컨테이너에서 데이터가 저장되는 경로를 심볼릭 링크시켜 컨테이너 안에서 생성된 데이터가 링크된 로컬 경로에 쌓이도록 하면 되는데, 이런 걸 volume이라고 한다. run 명령어와 함께 쓸 때는 -v--mount 옵션을 주면 된다.
    ex) -v host_dir:container_dir
    참고로 docker-compose 파일에서는 volume 경로를 상대 경로로 지정할 수 있다.
  • depends_on : 어떤 컨테이너를 먼저 띄울 지 알려주는 옵션. nginx가 web에 의존하고 있으므로 web을 먼저 실행시키고 nginx를 실행시키게 된다.

도커 컴포즈 명령어

docker-compose up : docker-compose 파일을 읽어서 컨테이너를 실행시키기

  • --build : 이미지를 빌드한 후 컨테이너를 생성해서 실행시키는 옵션

docker-compose down : 컨테이너를 전부 종료시키기

4. FAQ

도커를 사용하면 가상 환경을 안 써도 되나요?

PROS : 도커를 사용하면 가상 환경을 안 써도 된다.

📄 참고글

의존성 격리를 위해 사용하는 게 가상 환경인데, 그 역할을 도커가 하고 있으므로 도커 안에서 가상 환경을 사용할 필요가 없다.

만약 도커 안에서 여러 개의 앱을 돌리고 있다면, 그건 도커를 잘못 사용하고 있는 것이므로 앱을 각기 다른 컨테이너에 분리해라.

CONS : 도커를 사용해도 가상 환경을 써야 한다.

📄 참고글

가상 환경을 사용하면 패키지에 대한 전반적인 컨트롤을 더 용이하게 할 수 있고 디버깅도 쉽다.

또 계속 가상 환경에서 작업하다가 컨테이너 쓰면서 가상 환경을 사용하지 않게 된다면 오히려 그게 더 불편하다.

가상 환경을 사용한다고 해서 도커 컨테이너가 느려지거나 성능이 저하되는 것도 아니므로 그냥 가상 환경 써라.

도커 안에서 개발을 하는 건가요, 아니면 배포할 때만 사용하는 건가요?

PROS : 도커 안에서 개발 해라.

📄 참고글

도커를 배포용으로만 생각하지 마라. 도커로 개발하면 장점이 많다.

  • 팀원 전부가 동일한 환경에서 개발 가능
  • 개발 환경과 배포 환경을 완벽하게 동일하게 유지 가능 → 배포가 쉬워짐
  • 개발하는 데에 도커밖에 필요하지 않음 → 윈도우에서 안되는 것들이 많은데 도커 쓰면 바로 해결됨
  • IDE를 사용 가능 → 따라서 개발할 때 도커를 안 쓸 이유가 없음

CONS : 도커에서 개발하지 마라.

📄 참고글

도커 컨테이너 안에서 개발을 하면 추가적인 환경 설정 등 해줘야 할 게 많다.

특히 디버깅할 때 귀찮은 작업들을 해줘야 한다.

만약 규모가 작은 어플리케이션을 만들 생각이라면 개발할 때는 도커를 안 쓰는 게 훨씬 낫다.


더 알아보고 싶은 내용

  • 쿠버네티스란?
  • 도커 + CI/CD 사용하기

참고

profile
Curious Libertine

0개의 댓글