본문 바로가기
MLOps

MLOps - 15. Docker

by cocacola0 2022. 5. 30.

출처 : 변성윤님 블로그.
출처 : 부스트캠프 AI Tech.

1. Docker 소개

1.1 가상화란?

  • 도커에 대해 알기 전에 먼저 “가상화” 라는 개념을 잘 알아야 수월함
  • 가상화란 무엇이고, 왜 알아야 하는걸까요?
  • 개발할 때, 서비스 운영에 사용하는 서버에 직접 들어가서 개발하지 않음
  • Local 환경에서 개발하고, 완료되면 Staging 서버, Production 서버에 배포
  • 개발을 진행한 Local 환경과 Production 서버 환경이 다른 경우
    • 예) Local 환경은 윈도우 - 서버 환경은 Linux
      • OS가 다르기 때문에 라이브러리, 파이썬 등 설치할 때 다르게 진행해야 함
  • Local 환경과 서버가 같은 OS를 사용해도, 서버에서 올바르게 작동하지 않을 수 있음
    • 예)
      • Local의 환경 변수
      • Production 서버의 환경 변수(Env)
      • Production 서버의 사용자 그룹, Permission
  • 다양한 설정을 README 등에 기록하고, 항상 실행하도록 하는 방법
    • 사람이 진행하는 일이라 Human Error 발생
    • 매번 이런 작업을 해야 하는 과정이 귀찮음
    • 예)
      • Jupyter Notebook 서버를 만들기 위해 클라우드에서 클릭 - 이름 - 클릭 만들기 => 인스턴스로 접속해서 필요한 패키지 설치하는 과정
  • 운영하고 있는 Server가 100대라면?
    • 특정 서버 업데이트가 진행되었다면(윈도우, 스마트폰 OS 자동 업데이트 실행) => 나머지 서버에도 모두 접속해 업데이트 필요
  • 이 부분에서 생기는 고민 : 서버 환경까지도 모두 한번에 소프트웨어화 할 수 없을까? 밀키트처럼 만들어서 집에서도 사용하고 레스토랑에서도 사용하는 방법은?
    • 이런 고민을 해결하기 위해 나온 개념이 “가상화” (엄밀하게는 하드웨어 가상화 등 더 넓은 개념이지만, 여기선 소프트웨어 가상화로 한정)
  • 특정 소프트웨어 환경을 만들고, Local, Production 서버에서 그대로 활용
    • 개발(Local)과 운영(Production) 서버의 환경 불일치가 해소
    • 어느 환경에서나 동일한 환경으로 프로그램을 실행할 수 있음
    • 개발 외에 Research도 동일한 환경을 사용할 수 있음

1.2 Docker 등장하기 전

  • 가상화 기술로 주로 VM(Virtual Machine)을 사용
    • VM은 호스트 머신이라고 하는 실제 물리적인 컴퓨터 위에, OS를 포함한 가상화 소프트웨어를 두는 방식
    • 예)
      • 호스트 머신은 Window인데, Window에서 Linux를 실행
      • 호스트 머신은 Mac인데, Mac에서 Window를 실행
  • 그러나 OS 위에 OS를 하나 더 실행시키는 점에서 VM은 굉장히 리소스를 많이 사용
    • 이런 경우를 “무겁다” 라고 표현
  • Container : VM의 무거움을 크게 덜어주면서, 가상화를 좀 더 경량화된 프로세스의 개념으로 만든 기술
    • 이 기술의 등장으로 이전보다 빠르고 가볍게 가상화를 구현할 수 있음

1.3 Docker 소개

  • Container 기술을 쉽게 사용할 수 있도록 나온 도구가 바로 Docker
    • 2013년에 오픈소스로 등장
    • 컨테이너에 기반한 개발과 운영을 매우 빠르게 확장
  • Docker와 비슷한 느낌
    • PC방에서 특정 게임만 설치하고, 고객이 특정 프로그램을 깔아도 재부팅할 때 항상 PC방에서 저장해둔 형태로 다시 복구
    • Docker Image로 만들어두고, 재부팅하면 Docker Image의 상태로 실행
  • Docker Image
    • 컨테이너를 실행할 때 사용할 수 있는 “템플릿” - Read Only
  • Docker Container
    • Docker Image를 활용해 실행된 인스턴스 - Write 가능

1.4 Docker로 할 수 있는 일

  • 다른 사람이 만든 소프트웨어를 가져와서 바로 사용할 수 있음
    • 예) MySQL을 Docker로 실행
    • 예) Jupyter Notebook을 Docker로 실행
  • 다른 사람이 만든 소프트웨어 : Docker Image
    • OS, 설정을 포함한 실행 환경
    • Linux, Window, Mac 어디에서나 동일하게 실행할 수 있음
  • 자신만의 이미지를 만들면 다른 사람에게 공유할 수 있음
    • 원격 저장소에 저장하면 어디서나 사용할 수 있음
  • 원격 저장소 : Container Registry
    • 회사에서 서비스를 배포할 때는 원격 저장소에 이미지를 업로드하고, 서버에서 받아서 실행하는 식으로 진행

2. Docker 실습하며 배워보기

2.1 설치하고 실행하기

  • 도커 공식 홈페이지에서 자신의 운영체제에 맞는 Docker Desktop 설치
  • 설치 후, 터미널에서 docker 커맨드가 동작하는지 확인

2.1.1 docker image 다운

- docker pull "이미지 이름:태그"
# docker pull mysql:8로 mysql 8 버전의 이미지를 다운
$ docker pull mysql:8

2.1.2 docker image 확인

- docker images
$ docker images

2.1.3 docker container 실행

- docker run "이미지 이름 :태그"
- name : container 이름
- e : environment : 환경변수설정 (비밀번호 설정)
- d : demon(background) mode : background 모드
- p : port 3306:3306 : local port/container port -> local 포트로 3306 접속시 container 연결되도록 설정
    - mysql default port : 3306
- mysql:8 : Docker Image 
$ docker run --name mysql-tutorial -e MYSQL_ROOT_PASSWORD=1234 -d -p 3306:3306 mysql:8

2.1.4 docker ps

- 실행중인 컨테이너 확인
- a : 모든 컨테이너 
$ docker ps -a

2.1.5 docker container 진입

- docker exec -it "Container Name, ID" /bin/bash
- it : interactive
- ssh 접속과 유사 
$ docker exec -it mysql-tutorial /bin/bash
root@c02eb58c9ee7:/# mysql -u root -p

2.1.6 docker container 진입 안될 경우 // docker logs 보기

  • docker 가 빌드 되다 망가졌을때
    • Error response from daemon: Container 81c07e4a69519c785b12ce4512a8ec76a10231ecfb30522e714b0ae53a0c9c68 is restarting, wait until the container is running
  • docker logs --tail 50 --follow --timestamps "Container Name, ID"
$ docker logs --tail 50 --follow --timestamps mediawiki_web_1
$ docker exec -it mysql-tutorial /bin/bash
root@c02eb58c9ee7:/# mysql -u root -p

2.1.7 docker rm "컨테이너 이름"

- 멈춘 컨테이너를 삭제
- f : 실행중인 컨테이너 삭제 
$ docker rm "mysql-tutorial"
$ docker rm "mysql-tutorial" -f

2.1.8 docker rmi "이미지 이름"

- 도커 이미지 삭제 
$ docker rmi mysql:8
$ docker rmi 8f6dd244e5bf

2.1.9 docker stop "컨테이너 이름"

- 실행중인 컨테이너 중지 
$ docker stop "mysql-tutorial"

2.1.10 docker start "컨테이너 이름"

- 중지 컨테이너 재시작 
$ docker start "mysql-tutorial"

2.1.11 docker restart "컨테이너 이름"

- 가동중인 컨테이너 재시작 
$ docker restart "mysql-tutorial"

2.1.12 Docker Volume Mount

- Docker Container 내부는 특별한 설정이 없으면 컨테이너를 삭제할 때 파일이 사라짐
- (Host Container 사이에 파일 공유 X)
- Host 와 Container 사이의 저장소 공유필요
- Volumne Mount 진행, Host/Container 폴더가 공유
- v : -p 와 유사 : -v Host_Folder:Container_Folder
$ docker run it -p 8888:8888 -v /path/to/the/host/directory:/home/path/to/the/container/directory

2.1.12 Docker Hub Registry

  • Dockerhub에 공개된 모든 이미지를 다운받을 수 있음
  • MySQL도 Dockerhub에서 다운로드
  • Dockerhub에 왠만한 오픈소스들이 공개되어 있고, 우리는 필요한 이미지를 찾아 실행!

2.2 Docker Image 만들기

2.2.1 Docker 환경 설정

  • 먼저 폴더를 하나 만들고, 여기에 가상환경 세팅과 FastAPI 패키지를 설치
  • GET /hello 로 요청하면, 메시지를 전달하는 간단한 코드를 작성
  • pip freeze : 설치한 라이브러리를 모두 보여줌
  • 또는 pip list --not-required --format=freeze : 의존성에 따라 설치된 라이브러리는 보이지 않음 pip로 설치한 라이브러리를 모두 requirements.txt에 저장

2.2.2 Dockerfile 작성

  • Dockerfile라는 파일을 만들어 다음처럼 작성(Docker Image를 빌드하기 위한 정보가 담김)

2.2.3 Docker Image Build

  • docker build “Dockerfile이 위치한 경로”
    • 이미지 생성(빌드라고 표현)
    • 아래 이미지에서 . 는 현재 폴더에 Dockerfile이 있음을 의미
    • t "이미지 이름:태그" 옵션으로 이미지 이름과 태그 지정할 수 있음 태그는 미 지정시 "latest"로 채워짐
$ docker build . -t my-fastapi-app
  • 빌드를 마치면 docker images 명령어로 방금 빌드한 이미지를 확인할 수 있음
$ docker build . images

2.2.4 Docker Container 실행

  • docker run “이미지 이름:태그” 방금 만든 이미지를 실행!
  • 태그가 “latest” 인 경우 생략 가능
  • 다른 터미널을 열어 curl로 애플리케이션이 잘 작동하는지 확인할 수 있음

2.2.5 Docker Image 정리

  • 파이썬 환경 및 애플리케이션 코드를 작성
  • Dockerfile 작성
  • FROM으로 베이스 이미지를 지정
  • COPY로 로컬 내 디렉토리 및 파일을 컨테이너 내부로 복사
  • WORKDIR로 RUN, CMD 등을 실행할 컨테이너 내 디렉토리 지정
  • RUN으로 애플리케이션 실행에 필요한 여러 리눅스 명령어들을 실행
  • CMD로 이미지 실행 시 바로 실행할 명령어를 지정
  • docker build “Dockerfile이 위치한 경로” -t “이미지 이름:태그” 으로 이미지 빌드
  • docker run “이미지 이름:태그”로 빌드한 이미지를 실행
  • 그 외에 Dockerfile에서 사용하는 것
    • EXPOSE : 컨테이너 외부에 노출할 포트 지정
    • ENTRYPOINT : 이미지를 컨테이너로 띄울 때 항상 실행하는 커맨드
  • RUN vs CMD vs ENTRYPOINT 차이점
    • RUN : docker container 실행시 이미지 빌드를 위해 진행. 즉, 재실행되는 contiainer 의 경우에는 실행 안함
      • Base Image의 Layer를 추가하는 작업
      • Layer가 많아질수록 효율적이지 않으므로 한줄 작업 추천
    • CMD : docker container 실행시 default로 실행되는 프로세스 - docker 실행시 overriding 가능
    • ENTRYPOINT : dokcer container 실행시 default로 실행되는 프로세스 - docker 실행시 overriding 불가 (가능은 함)

2.3 Registry에 Docker Image Push

  • 도커 이미지를 인터넷에 업로드!
    • 이를 위해 이미지 저장소인 Container Registry에 Docker Image Push
    • Container Registry : Dockerhub, GCP GCR, AWS ECR 등
    • 별도로 지정하지 않으면 기본적으로 Dockerhub를 사용. 우리는 GCP의 GCR을 사용

  • 이제 로컬에서 GCR로 이미지를 Push할 준비
    • 먼저 gcloud를 로그인하고, 프로젝트 세팅
    • gcloud : 구글 클라우드 플랫폼 제품을 CLI로 쉽게 사용할 수 있도록 만든 도구
    • Cloud SDK Install 에서 OS를 확인한 후 다운로드 및 실행

3. Docker 이미지로 배포하기

3.1 Serverless Cloud 서비스(Cloud Run)

- [Product Serving] 3-2. Docker.pdf 참고 

3.2 Compute Engine에 Docker Image 배포하기(Streamlit)

- [Product Serving] 3-2. Docker.pdf 참고 

Error1 발생 - github action 에서 에러. ㅜㅜ

Error: Unable to resolve action `google-github-actions/setup-gcloud@master`, unable to find version `master`

Error1 Fix

Error2 발생 - github action 완료 but deploy failed

Error2.1. 발생 로그 check

  • GCP SSH에서 2.1.5 docker container 진입 하려고 했으나 아래와 같은 에러 발생
  • Error response from daemon: Container 81c07e4a69519c785b12ce4512a8ec76a10231ecfb30522e714b0ae53a0c9c68 is restarting, wait until the container is running
  • 2.1.6 docker container 진입 안될 경우 // docker logs 보기 보기 실행
  • gcp TypeError: Descriptors cannot not be created directly. ~

Error2.2. Fix

  • Boostcamp-AI-Tech-Product-Serving/part2/04-cicd/Dockerfile 에 PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION env 설정
FROM python:3.8.7-slim-buster
COPY requirements.txt ./requirements.txt
RUN pip install -r ./requirements.txt

COPY . /app  
WORKDIR /app

ENV PROTOCOL\_BUFFERS\_PYTHON\_IMPLEMENTATION python  
EXPOSE 8501  
ENTRYPOINT \["streamlit", "run", "app.py", "--server.port", "8501"\]

잘돌아감

3.3 Docker Compose

```

  • [Product Serving] 3-2. Docker.pdf 참고
    ```

'MLOps' 카테고리의 다른 글

MLOps - 17. MLFlow  (0) 2022.06.01
MLOps - 16.Logging  (0) 2022.05.31
MLOps - 14. FastAPI  (0) 2022.05.29
MLOps - 13. FastAPI  (0) 2022.05.28
MLOps - 12. FastAPI  (0) 2022.05.27

댓글