IT일상

docker, 한번 써볼까요?

  • 인프라
Profile picture

Written by solo5star

2021. 5. 23. 03:33

1

이런 그림을 보신 적 있으신가요? 바로 docker의 마스코트인데요, 사실 이름은 저도 잘 모르겠습니다.

docker 마스코트는 많이 봤는데 어떤 용도로 쓰이는지 잘 모르는 분들이 많더라구요.

그래서 이번 글에서는 docker를 한번 알아보려고 합니다. 서버와 관련된 일을 한다면 꼭! 알아두는 것이 좋습니다.

굳이 docker라는 것도 알아야할까요?

저는 위 사진과 같은 싱글 보드 컴퓨터(SBC)를 사서 24시간 전원을 인가해두고 서버로 사용하고 있습니다. 여기에 정말 다양한 서비스를 설치해서 사용하는데요. 서버 과부화 모니터링을 위한 Grafana, DB 사용을 위한 MySQL, MariaDB, 서브 도메인 관리를 위한 Nginx ...

이 많은 서비스들은 apt 명령어로 설치할 수 있어요. 물론 apt install 로 끝나는 것이 아니라, 자잘한 설정도 해주어야 하고, 설치된 후에는 가끔씩 서비스가 예기치 않게 종료되진 않았는지 확인도 해주어야 하고...

또 서비스마다 관리 방법도 다를거에요. 환경 설정 파일도 각자 다른 곳에 있을거고...

이들을 한달이 지나도 다 기억할 수 있을까요? 저는 못할거같아요. 그래서 바로, docker를 씁니다. docker를 쓴다면 이 모든 고민을 해결 가능합니다!

좋아요! 그럼 docker에 대해 좀 더 알려주세요.

docker는 "컨테이너" 기반의 가상화 플랫폼입니다. 컨테이너 안에 들어가는 것은 무엇일까요? 바로 위에서 언급한 서비스들입니다.

우리는 지금까지 서비스 별로 관리 방법을 숙지했었습니다. 그런데 컨테이너 단위로 추상화되면서, 서비스마다 달랐던 관리 방법을 잊어버려도 됩니다. 컨테이너를 관리하는 방법만 알면 되니까요.

3
사실 이 친구가 등에 업고 있던 것들은 모두 서비스입니다

docker를 한번 설치해볼까요? https://www.docker.com/get-started 에서 OS별로 docker 설치 파일을 받을 수 있습니다.

이 글에서는 라즈베리파이3 모델B (Ubuntu 64Bit) 기준으로 진행하겠습니다.

4
라즈베리파이3 모델B
$ sudo wget -qO- https://get.docker.com/ | sh

이 명령어를 실행하면 리눅스 배포판을 자동으로 인식하여 docker를 설치할 수 있습니다.

5
설치가 잘 되고 있네요!

진행이 끝나면 아래 명령어를 입력하여 docker 설치가 무사히 잘 되었는지 확인해주세요.

$ docker --version
6

root 권한이 없는 계정에서도 docker를 사용하려면 아래의 명령어를 입력해주세요. 저 같은 경우 ubuntu 계정에서 docker를 사용하기 위해 아래의 명령어를 실행해주었습니다. (실행 후 한번 로그아웃해야합니다.)

$ sudo usermod -a -G docker $USER
$ sudo service docker restart

그럼 바로 docker를 써봐야겠죠? 아래의 명령어를 한번 입력해볼까요?

$ docker run --rm python python -c 'print("Hello world!")'
7
python:latest 이미지를 다운로드하고 있습니다.
8

파이썬 코드가 실행되었어요. 이게 무슨 의미일까요?

docker run <image> 명령어는 주어진 이미지를 가지고 컨테이너를 즉석에서 만들고 실행할 때 사용해요.

--rm 이라는 옵션을 사용하면 컨테이너가 실행이 끝난 후 바로 제거되요.

docker run --rm python 은 python 컨테이너를 만들고 종료 시 바로 제거하라는 명령이 됩니다.

뒤따라 붙은 python -c 'print("Hello world!")' 는 컨테이너에서 실행할 명령어를 지정하는 것이구요.

python을 설치하지 않았는데도 python코드를 실행할 수 있었어요.

물론 python 뿐만 아니라 Java, C#, Ruby, Rust 등 다른 언어도 가능해요.

python을 직접 깔고 실행하는거랑 뭐가 달라?

사실 앞서 설명한 것은 python을 직접 깔아서 해도 되는 것을 굳이 docker로 해보았는데, 이런 앱이 여러 개 있고 서로가 의존성을 가진다면 관리의 어려움이 커져요. 예를 하나 들어볼까요?

  • Spring으로 만든 웹 서비스
  • 채팅 기능 제공을 위한 Kafka
  • Kafka의 의존성인 Zookeeper
  • MySQL 데이터베이스

이들을 다 어떻게 관리할까요? 서비스가 늘어나는 만큼 관리 난이도도 올라갑니다. 이들을 모두 컨테이너로 생성하고 docker 명령어 하나로 관리한다면, 관리가 훨씬 편하겠죠?

위에서는 프로그래밍 언어만 언급하였지만 실제론 종류가 정말 많습니다. Ubuntu, MySQL, Redis, NodeJS, Nginx ...

9
docker에서 공식적으로 제공하는 이미지 목록

이들을 모두 docker 명령어로 생성하고, 실행하고 관리할 수 있습니다.

docker 명령어를 좀 더 알아봅시다

아까 위에서 docker run 명령어를 사용했어요. 입력된 이미지(위의 예시에선 python)로 컨테이너를 생성하는 명령어인데, 이것 말고도 여러가지 명령어가 있어요.

컨테이너 생성 및 시작

$ docker run [options] <이미지 이름>[:TAG] [명령어] [명령어 인자...]

컨테이너를 생성하고 즉시 실행하기 위해 사용됩니다.

  • -d, --detach
    컨테이너를 detached mode로 실행. 쉽게 말해 백그라운드에서 실행됩니다.
  • --name <이름>
    컨테이너의 이름을 지정. 이 옵션이 없으면 docker가 적당한 이름을 붙여줍니다.
  • -p, --port <호스트 포트>:<컨테이너의 포트>
    컨테이너의 포트를 포워딩합니다. 만약 컨테이너에서 80번 포트를 사용한다면, -p 80:80 을 추가해야 외부에서 80번 포트로 컨테이너에 접속할 수 있어요. 다른 포트로 지정하고 싶다면 -p 3000:80 와 같이 바꿀 수 있습니다.
  • -v, --volume <호스트 디렉토리>:<컨테이너 디렉토리>
    컨테이너에 마운트할 디렉토리를 지정합니다. 컨테이너 데이터를 외부에 저장하고 유지하기 위해 사용되요.
  • -it
    -i-t를 붙여놓은 옵션입니다. i는 interactive, t는 tty인데요, 컨테이너 생성과 동시에 터미널처럼 사용하기 위해 사용합니다.
  • --rm
    컨테이너 안에서 작동하는 프로세스가 실행이 끝나면 컨테이너를 제거하도록 하는 옵션입니다.
  • -e, --env <환경 변수>
    컨테이너 내부의 환경 변수를 설정할 수 있는 옵션입니다.
  • --env-file
    환경 변수들이 저장되어있는 파일을 읽어 컨테이너 내부에서 사용합니다.
  • --net <bridge|host|none>
    컨테이너의 네트워크 모드를 지정합니다.
    • bridge: 기본적으로 설정되는 모드이며 컨테이너의 네트워크는 호스트에 노출되지 않습니다. 포트를 사용하려면 -p 옵션을 사용해야 합니다.
    • host: 컨테이너의 네트워크를 독립적으로 사용하지 않고 호스트의 네트워크를 그대로 사용합니다. -p 옵션 없이 컨테이너의 포트가 노출됩니다.
    • none 네트워크 드라이버를 설정하지 않습니다.
  • --restart <no|on-failure:[max-retries]|unless-stopped|always>
    컨테이너 재시작 옵션을 설정합니다.
    • no: 컨테이너가 자동으로 재시작하지 못하게 설정합니다. 기본값입니다.
    • on-failure[:max-retries]: 컨테이너가 비정상적으로 종료(non-zero exit code)되었을 때, 자동으로 재시작합니다. max-retries를 입력하면 최대로 시도할 수 있는 횟수를 제한할 수 있습니다.
    • unless-stopped: 사용자가 직접 컨테이너를 정지하기 전까진 자동으로 재시작을 시도합니다. 컴퓨터가 꺼졌다 켜졌을 때 알아서 다시 재시작해주기 때문에 자주 사용하는 옵션입니다.

컨테이너 시작

$ docker start <컨테이너 ID 또는 이름>

종료된 상태의 컨테이너를 시작합니다.

컨테이너 종료

$ docker stop <컨테이너 ID 또는 이름>

컨테이너 재시작

$ docker restart <컨테이너 ID 또는 이름>

컨테이너 삭제

$ docker rm <컨테이너 ID 또는 이름>

컨테이너 목록 확인

$ docker ps -a

실행 중인 컨테이너 목록을 확인하기 위해 자주 사용하는 명령어입니다.

10

컨테이너 로그 확인

$ docker logs [options] <컨테이너 ID 또는 이름>

백그라운드에서 작동하고 있는 컨테이너의 로그를 보기 위해 사용하는 명령어입니다.

  • -f, --follow
    컨테이너에서 생성되는 로그를 실시간으로 계속 확인하기 위해 사용하는 옵션입니다.
  • --tail, -n <라인 수>
    로그의 끝에서부터 지정된 라인만큼만 표시합니다. 로그가 너무 많은 경우 유용한 옵션입니다.
  • -t, --timestamps
    타임스탬프도 같이 표시합니다.
  • --since <timestamp>
    지정된 시간 이후의 로그를 표시합니다.
  • --until <timestamp>
    지정된 시간 이전의 로그를 표시합니다.
11

위의 출력은 docker logs nginx -f --tail 10 을 실행한 결과입니다.

nginx 컨테이너의 로그를 끝에서 10개부터 실시간으로 출력합니다.

컨테이너 여러개를 한번에 묶어서 관리하고 싶은데... (docker-compose)

각종 서비스들을 컨테이너 단위로 관리할 수 있게 되어 정말 편리해졌어요. 그런데 서비스들을 하나로 묶어서 관리할 순 없을까요?

예를 들면, 채팅 서비스를 하나 운영하는데 nginx, django, mysql, redis를 사용합니다. 이들은 서로 연동되기 때문에 하나로 묶어 관리할 수 있다면 정말 편리할텐데요.

이를 위해 사용하는 것이 바로 docker-compose 입니다.

12
여러 서비스를 한번에 관리하자

docker-compose는 여러 개의 서비스를 docker-compose.yml에 정의해놓고 관리하게 해줄 수 있는 툴입니다.

사용할 서비스들을 docker-compose.yml에 적은 뒤 그걸 docker-compose 명령어로 한꺼번에 생성 · 실행 · 관리하는 방식입니다.

아래의 명령어를 입력하여 docker-compose를 설치할 수 있어요.

$ sudo apt install docker-compose
13
docker-compose --version 명령어로 설치되었는지 확인해보세요

아래의 docker-compose.yml 파일을 한번 볼까요?

docker-compose.yml
version: "3.7"
services:
  db:
    container_name: "awesome-chat-db"
    image: mysql
    restart: unless-stopped
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      - MYSQL_DATABASE=awesomedb
      - MYSQL_ROOT_PASSWORD=awesomepwd
      - TZ=Asia/Seoul
  
  web:
    container_name: "awesome-chat-web"
    image: awesomefront
    ports:
      - "80:8080"
    restart: unless-stopped
    volumes:
      - ./web:/data

실제로 작동하지는 않습니다. 예시를 위해 간단히 작성된 것입니다

docker run 명령어의 옵션과 비슷한 부분들이 많지 않나요? 맞습니다. docker run 명령어를 yml 파일로 작성한다 봐도 무방할 것 같습니다.

services 아래에 사용할 서비스를 정의할 수 있습니다. 위의 경우, MySQL과 Web Service가 정의되어 있네요.

이렇게 docker-compose.yml 파일로 저장해두면 터미널에서 docker run 명령어로 번거롭게 사용하지 않아도 되겠죠?

이들은 docker-compose 명령어로 한꺼번에 관리할 수 있습니다. 명령어를 한번 간단히 알아보겠습니다.

주의! docker-compose.yml이 있는 디렉토리에서 실행해야 합니다.

docker-compose 실행

$ docker-compose up
  • -d, --detach
    컨테이너들을 백그라운드에서 실행합니다.

보통은 docker-compose up -d 명령어로 많이 사용합니다.

docker-compose 정지

$ docker-compose down

docker-compose 로그 확인

$ docker-compose logs
14
docker-compose logs -f --tail 2 명령어 실행 결과

Linux 모니터링 시스템 구축 (docker-compose)

15

예제로 멋진 모니터링 시스템을 구축해보려고 합니다. 사용할 서비스는 아래와 같습니다.

  • grafana: 시계열 데이터를 차트로 시각화해주는 서비스입니다. 데이터는 prom/prometheus에서 받아옵니다.
  • prometheus: 시계열 데이터를 수집하고 저장하는 서비스입니다.
  • cadvisor: 컨테이너의 정보를 수집하는 서비스입니다.
  • node-exporter: 시스템의 정보를 수집하는 서비스입니다.
  • script-exporter: smartmontools를 사용하여 S.M.A.R.T 데이터를 수집하기 위해 사용되는 서비스입니다. (arm64에서는 호환 불가로 인해 제외되었습니다)

복잡해보이지만 이 서비스들이 미리 정의되어있는 docker-compose.yml 파일을 받은 후 실행할겁니다.

아래의 명령어를 입력하여 solo5star/dashboard GitHub 레포지토리를 클론하세요.

$ git clone https://github.com/solo5star/dashboard
16

현재 디렉토리에 dashboard라는 폴더로 clone이 완료되었습니다. cd 명령어로 디렉토리를 이동해주세요.

$ cd dashboard

dashboard 폴더에는 모니터링 시스템 구축을 위한 docker-compose.yml 외 기타 설정 파일들이 준비되어 있습니다. 이제 docker-compose 명령어만 실행하면 됩니다!

본인이 사용하는 시스템의 아키텍처에 맞게 명령어를 실행해주세요. 저는 라즈베리파이를 사용중이기 때문에 arm64로 진행하였습니다.

x86_64

$ docker-compose up -d

arm64

$ docker-compose -f docker-compose.arm64.yml up -d
17

docker-compose logs -f 명령어를 입력하여 정상적으로 켜졌는지 확인해주세요.

18

이제 grafana로 접속합니다. grafana는 3000번 포트로 접속이 가능합니다.

19

성공적으로 설치 및 실행이 완료되었고, grafana로 접속하는데 성공하였습니다!!

처음 계정과 패스워드는 admin/admin입니다.

20

grafana 메인 화면입니다.

21

왼쪽의 메뉴를 통해 대시보드로 접근할 수 있습니다!

22

대시보드입니다. 라즈베리파이의 각종 정보와 기록이 표시되고 있습니다. 아쉽게도 arm64에서는 script-exporter가 작동하지 않아 S.M.A.R.T 데이터는 No data로 뜨는군요 ㅜㅜ 만약 x86_64로 사용하신다면 정상적으로 뜰 겁니다.

글을 마치며...

지금까지 docker, docker-compose, docker-compose를 사용한 모니터링 시스템 구축에 대해 알아보았습니다. 원래 다룰 내용이 많기 때문에 주제 하나당 글 하나씩 작성을 해야하는데 한꺼번에 정리를 하게 되었네요 😅

저는 docker를 알고 난 후 서버를 다루는 일이 즐거워진 것 같습니다. 어떤 서비스든 관리 방법을 계속 숙지하고 있는 것이 보통 힘든 일이 아니었는데요, docker 덕분에 정말 간단해진 것 같습니다.

괜히 사람들이 극찬하는게 아닌 것 같아요. 이 글을 읽고 계신 분들 중 서비스 관리가 어렵다 느낀적이 있다면, 꼭 한번 써보셨으면 좋겠습니다!! 🚀

끝까지 읽어주셔서 정말 감사합니다 😄


Profile picture

Written by solo5star

안녕하세요 👋 개발과 IT에 관심이 많은 solo5star입니다

  • GitHub
  • Baekjoon
  • solved.ac
  • about
© 2023, Built with Gatsby