카일 스쿨 10회차

Hits

  • #1. Docker 큰 개념
  • #2. 따라치며 배우는 도커
  • #3. Dockerfile 만들기
    • Dockerhub와 GCR 이해하기
  • #4. 도커 이미지를 사용해 인스턴스 띄우기
  • #5. 도커를 사용해 Superset / Metabase 띄우기

Docker 큰 개념

오늘 이것만은 꼭!

  • Docker란 무엇인지 이해한다
  • Docker Image Pull하기
  • Docker Container를 실행
    • 로컬에서 Jupyter Notebook을 띄워보기
  • 서버에 Jupyter Notebook 띄우기
  • Dockerfile 작성하기

Docker란 무엇인가

  • Docker는 환경을 격리해 이미지를 만들고, 실행해줌
    • 피시방에서 재부팅해도 다시 그대로 프로그램이 그대로!
    • 애플리케이션 + 환경 모두 같이 저장
    • 도커 파일을 빌드 => 도커 이미지 : 명령어를 모두 실행한 결과
    • 1년 사이에 특정 도구가 사라져있을 수 있다면? 도커 이미지는 특정 도구까지 품어서 만듬
    • A 서버에선 라이브러리 설치, B에도 설치?
    • GPU 환경설정 등을 쉽게 가능함
    • 내 로컬에 파이썬 안깔고 깔끔하게 유지 가능
  • 도커가 등장하기 전 세상
  • 1) 배포
    • 서버를 운영한다
    • 배포한다!
    • 파일을 ftp 등으로 보내고 인스턴스를 껐다 킴
    • 서버가 50대라면..?
  • 2) 환경
    • 우리에겐 pyenv, virtualenv도 있지만.. 리눅스 환경 자체를 원한다면?
    • 인스턴스 실행하고 터미널 명령어 계속 치는 방식?
  • 3) 이런 적 있지 않나요
    • GPU 엔비디아 설치...
    • 뭔가 안된다 => 스택오브플로우 => 음 다시 하래 => 음
  • 도커 관련 용어 설명
    • 이미지 : 일종의 템플릿
    • 컨테이너 : 이미지를 가지고 실행
    • 도커 허브 : 템플릿 창고
    • 호스트 : 시스템의 핵심이 되는 PC

따라치며 배우는 도커

  • 도커 명령어
    • docker
    • docker image pull
    • docker image ls
    • docker run
    • docker exec
    • docker container
    • docker build
  • docker image pull

    • docker image를 땡겨오는 명령어

      docker image pull jupyter/minimal-notebook
  • docker image ls

    • 현재 있는 도커 이미지를 출력
    • -a 조건을 주면 전체 이미지 출력

      docker image ls
  • docker run

    • docker image 기반으로 컨테이너 실행
    • 실행할 때 포트 정보를 같이 인자로 넘겨야 함

      docker run -p 8888:8888 jupyter/minimal-notebook
    • -p host_port:container_port

    • -d 옵션을 주면 백그라운드에서 실행
  • docker container ls
    • 현재 실행중인 컨테이너 출력
  • docker exec
    • 컨테이너 안에 명령을 날리고 싶은 경우
      • 1) 컨테이너 안에 들어가서 명령을 날려도 되고
      • 2) exec을 써도 됨 : 이 방법
    • docker exec b8314275379e pip install tensorflow
  • docker 컨테이너 안으로 들어가기

    • docker exec
    • -it : interactive tty 접속한다는 뜻. 일단 -it를 많이 쓴다고 알아두어도 좋아요

      docker exec -it container_id /bin/bash
  • docker run 취소
    • docker run 했던 터미널을 취소(command c)하고 다시 실행해봅시다
    • tensorflow를 import하면?
    • 안됩니다
    • docker run은 한번만 일회성으로 띄우고, 끄는 순간 꺼집니다
  • Volume mount

    • 호스트와 컨테이너끼리 파일 공유가 안됨 => 삭제됨
    • 볼륨 마운트로 진행
    • v option을 주면 가능함

      docker run -it -p 8888:8888 -v /some/host/folder/for/work:/home/jovyan/workspace jupyter/minimal-notebook
  • 자 여기서 실습
    • jupyter notebook(jupyter/minimal-notebook) 띄우기
    • 컨테이너로 직접 들어가서 라이브러리 설치하기
    • Docker Volume 싱크 확인하기(컨테이너 종료해서 다시 켜볼 때 공유되는 폴더가 있는지?)

Dockerfile

  • Docker 명령어 모음
  • 보통 도커파일을 많이 사용함
  • Dockerfile은 이미지를 만드는데 필요한 모든 명령을 순서대로 포함하는 텍스트 파일
  • 각 명령을 읽어서 이미지를 빌드함
  • FROM, COPY, RUN, EXPOSE, ENV, CMD, ENTRYPOINT, WORKDIR, USER, VOLUME 등을 사용함. 잘 설명된 링크
  • Dockerfile이란 파일을 사용하며, docker build -t dev/dev:v1 . 이런 식으로 자주 씀
FROM jupyter/minimal-notebook
RUN pip install tensorflow
  • RUN과 CMD, ENTRYPOINT의 차이
    • RUN은 이미지 빌드 과정에서 진행. 컨테이너 이미지에 커밋됨
    • CMD는 빌드된 이미지를 시작할 때 컨테이너가 실행하는 명령. docker run할 때 인자값을 전달해 실행하면 CMD는 무시됨
    • ENTRYPOINT: docker run시 실행되는 명령, 단 한번만 사용. RUN 또는 start 때 사용됨
  • 아래와 같은 Dockerfile을 만들어봅시다
FROM jupyter/minimal-notebook
RUN pip install tensorflow
RUN jupyter notebook --generate-config --allow-root -y  \
    && echo "c.NotebookApp.password = 'sha1:fee705da7ee3:39094efec15c2bc5f651b88fdd5536685b5fd229'" >> /home/jovyan/.jupyter/jupyter_notebook_config.py

EXPOSE 8888

ENTRYPOINT jupyter notebook --allow-root --ip=0.0.0.0 --port=8888 --no-browser
  • docker image 찾기 팁
    • Dockerhub 가입
    • 원하는 검색어를 사용하면 여러 도커 이미지가 나옴
  • Airflow 이미지 선택
  • Tags 확인
  • Dockerfile을 공개하는 이미지도 있음

GCR

  • Google Container Registry
  • Google Cloud Platform에서 만든 도커 허브라고 생각하면 편함
  • 여기도 Docker 이미지를 push하고 pull할 수 있음
  • sha1:~~~ 은 kyle을 암호화한 것
FROM jupyter/minimal-notebook
RUN pip install tensorflow
RUN jupyter notebook --generate-config --allow-root -y  \
    && echo "c.NotebookApp.password = 'sha1:fee705da7ee3:39094efec15c2bc5f651b88fdd5536685b5fd229'" >> /home/jovyan/.jupyter/jupyter_notebook_config.py

EXPOSE 8888

ENTRYPOINT jupyter notebook --allow-root --ip=0.0.0.0 --port=8888 --no-browser
  • Container Registry API 사용 설정
  • 빌드
    • gcloud builds submit --tag gcr.io/bigquery-definitive/simple_notebook .
      • bigquery-definitive엔 여러분의 project_id를 넣어주세요
    • 빌드된 이미지 확인
  • Compute Engine에서 쉽게 사용하는 방법
    • gcr 링크 복사하기 : gcr.io/bigquery-definitive/simple_notebook
  • VPC 네트워크 - 방화벽 이동
    • 8888 포트를 열어줘야 함
  • Compute Engine으로 이동하기
    • VM 인스턴스 만들기 - 이 VM 인스턴스에 컨테이너 이미지를 배포합니다 클릭
  • Volume Mount 설정
    • home/jovyan/workspace
  • 네트워크 태그에 위에서 만든 jupyter 네트워크 방화벽 설정
  • 인스턴스 확인
  • 인스턴스 ip를 사용해서 노트북 포트(8888)로 이동
  • 만약 도커 이미지에 이상이 있다면 다시 빌드 => 인스턴스 종료 후 다시 시작하면 최신 도커 이미지 사용함

Docker Image 사용시 불편한 점

  • 옵션이 다양함
    • 실행시 작성해야 하는 명령어 옵션이 많고, 귀찮음
    • 미리 정의해둘 수 없을까?
  • 컨테이너의 순서를 제어할 수 없을까?
    • A 컨테이너를 먼저 띄우고, B 컨테이너를 실행해야 하는 경우
    • 예를 들어 Database 컨테이너를 먼저 띄우고 어플리케이션 컨테이너를 띄워야하는 경우
  • Docker Compose
    • 위에 나오는 이슈들을 해결하기 위해 나옴
    • 여러 컨테이너를 한번에 띄울 수 있음
    • 여러 컨테이너의 실행 순서, 의존도를 관리할 수 있음
    • docker-compose.yml 파일에 작성함
  • simple notebook docker-compose.yml 파일
version: '3' # 파일 규격 버전

services: # 컨테이너들을 정의
  notebook: # notebook 서비스
      image: jupyter/minimal-notebook # notebook 서비스에서 사용할 도커 이미지
      container_name: notebook # 컨테이너 이름
      volumes:  # --volume 옵션 사용해서 연결하는 부분
          - ./docker-volume:/home/jovyan/workspace
      ports: # ports 호스트:컨테이너
          - 8888:8888
      command:
        jupyter notebook --allow-root --ip=0.0.0.0 --no-browser
  • 백그라운드에서 실행하기(docker run -d와 동일) : docker-compose up -d
  • 서비스 중단(컨테이너, 볼륨 등 삭제) : docker-compose down
  • 실행 중 서비스 확인 : docker-compose ps
  • 로그 확인 : docker-compose logs <서비스명>
  • 참고 지식!
    • docker-compose.yml 파일을 수정했으면 => up을 하면 컨테이너 재생성 후 서비스 재시작함
  • Airflow Dockerfile 띄우기

      git clone https://github.com/puckel/docker-airflow
      cd docker-airflow
      docker-compose -f docker-compose-CeleryExecutor.yml up
  • 혹시 Bind for 0.0.0.0:5555 failed: port is already allocated 에러가 발생하는 경우

    • docker container ls로 실행된 컨테이너 중 포트 사용하는거 확인하고
    • docker rm -f <컨테이너 id>로 삭제
  • PostgreSQL Dockerfile

    • docker-compose up -d

      version: '3' # 파일 규격 버전
      
      services: # 컨테이너들을 정의
        postgresql: # postgresql 서비스
            image: postgres # postgresql 서비스에서 사용할 도커 이미지
            container_name: postgresql # 컨테이너 이름
            volumes:  # --volume 옵션 사용해서 연결하는 부분
                - ./postgresql/data:/var/lib/postgresql/data
            ports: # ports 호스트:컨테이너
                - 5432:5432
            environment: # 환경 변수
                POSTGRES_PASSWORD: "password"
                TZ: "Asia/Seoul"

Superset Docker

  • docker-airflow
    • localhost:8088에서 실행
    • id, password : admin, admin
docker-compose up -d
git clone https://github.com/abhioncbr/docker-superset


cd docker-files
docker-compose up -d
  • 만약 Bind for 127.0.0.1:5432 failed: port is already allocated 에러가 난다면 5432 포트에 이미 선점한 것이 있을 수 있음
    • 아마 postgre일 수 있음
    • docker container ls로 확인 후
    • docker rm -f <컨테이너 id>
    • 또는 아래 명령어 실행
docker-compose down
docker rm -fv $(docker ps -aq)
sudo lsof -i -P -n | grep 5432
sudo kill -9 <process id>
  • proxy: listen tcp 0.0.0.0:6379: bind: address already in use 이 에러가 뜬다면
docker-compose down
docker rm -fv $(docker ps -aq)
sudo lsof -i -P -n | grep 6379
sudo kill -9 6379

Metabase Docker

docker run -d -p 3000:3000 --name metabase metabase/metabase