본문 바로가기

부스트캠프 AI Tech 3기/이론 : U-stage

[Day 18] AI 서비스 개발 4. Docker : 가상화, docker 실행, docker image build

Docker

docker가 나아가서 쿠버네티스까지 확장된다.

가상화

: 특정 소프트웨어 환경을 만들고, local&production 서버에 동일하게 그대로 활용

 

개발할 때는 local환경에서 하고, 개발이 완료되면, staging서버와 production서버에 배포하게 된다.

  • local 환경 != production 서버 환경
  • local 환경 = production 서버 환경

윈도우 -> Linux 이면 OS이기 때문에 라이브러리나 언어를 설치할 때 다르게 해야한다.

같은 OS이더라도, 환경변수, permission을 맞춰주어야 한다.

 

설정을 할 때 readme에 기록하고 실행하게끔 해야한다.

하지만 서버마다 설치하는게 번거롭고 사람이 하기 때문에 기존과 다른 점이 생길 수 있다. 또한 서버가 1개가 아니라 여러 개라면 복잡하다.

그래서 서버 환경까지도 한 번에 소프트웨어화하기 위해 나온 개념이 가상화이다.

특정 소프트웨어 환경을 템플릿처럼 만들어 개발과 운영 서버의 불일치를 해소하면 편리해질 수 있다.

VM : Virtual Machine

호스트 머신(내 실제의 컴퓨터)에 가상의 소프트웨어를 안에 두는 방식

운영체제 안에 다른 운영체제를 하나 더 두는 것이기 때문에 리소스를 많이 쓴다.

 

Docker

container로 VM을 가볍게 하면서 가상화를 빠르게 할 수 있게한 도구

VM과 비교했을 때 Guest OS가 없이 Host OS만 있어서 가볍게할 수 있다.

  • Docker Image
    container를 실행할 때 사용할 수 있는 템플릿(OS+설정)
    만든 이후에는 수정이 불가능하다(read only)
  • Docker Container
    docker image로 만들어진 인스턴스
    write 가능

Docker로 할 수 있는 일

  • 다른 사람이 만든 소프트웨어를 가져와서 바로 사용할 수 있다
  • 어느 OS에서나 가능하다
  • 개발환경도 docker로 해서 내 실제 컴퓨터에 설치하지 않고 관리
  • docker이미지를 저장하고 공유하려면 원격저장소(container registry)를 사용하면 된다.
    ->docker hub, GCR 등

Docker 실행하기

2022.02.16 - [개발] - Docker 설치/시작하기 먼저 docker를 설치하고 옵니다

MySQL 실행하기

windows terminal로 들어간다.

docker image를 container registry에서 가져오자

#docker pull image_name:tag
docker pull mysql:8 # version 8

git clone하듯이 image를 pull한다.

docker images

현재 다운받아서 가지고 있는 images를 확인할 수 있다.

 

 docker run --name mysql-tutorial -e MYSQL_ROOT_PASSWORD=1234 -d -p 3306:3306 mysql:8
 # 마지막 mysql:8은 해당 이미지를 가져오겠다는 의미이다.

다운받은 image기반으로 container를 만들고 실행한다.

  • --name : container의 이름, 지정하지 않으면 랜덤 설정
  • -e (environment) : 환경변수 설정
    mysql에 접속하려면 항상 비밀번호가 필요해서 생성한다.
  • -d : 데몬 모드 = 백그라운드 모드 : 컨테이너를 백그라운드 형태로 실행한다. 백그라운드 모드로 하지 않으면 container를 나갈시에 그냥 종료되서 날아간다.
  • -p : 포트 지정
    '로컬 호스트 포트':'컨테이너 포트' 
    로컬은 우리의 컴퓨터이고, 컨테이너는 그 안의 vm이다.
    컨테이너 포트가 3306이더라도 localhost 3306으로 연결해주고 컨테이너로 연결해줘야 컨테이너 포트 3306까지 연결된다.

Error response from daemon: Ports are not available: listen tcp 0.0.0.0:3306: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.

위와 같이 에러가 떴다. 전에 mysql을 사용한 적이 있어서 그런 것 같다. 그래서 이 블로그를 따라서 했다.

 

docker ps # 실행한 컨테이너를 확인할 수 있다.
docker ps -a # 현재 실행되는 것 뿐만 아니라 멈춘 container까지 모두 보여준다.

아까 mysql을 블로그를 따라하면서 중지시켜서 그런지 -a 옵션을 붙혀야지만 보이는 걸로 봐서 중지된 것 같다. 그래서

docker restart mysql-tutorial

로 재시작을 해줘서 ps만 쳐도 목록에 나오게 했다.

 

docker rm container_name # 해당 컨테이너를 삭제한다.
docker rm container_name -f # 실행중이어도 강제로(force) 삭제한다.

재시작하지 말고 아예 삭제하고 새로 시작해도 될 것 같다.

 

디버깅이나 문제가 생기면 container안에 들어가서 작업을 해야한다.

docker exec -it mysql-tutorial /bin/bash # mysql-tutorial 대신에 각자의 컨테이너 이름을 넣으면 된다.
# 컨테이너에 진입

들어와서 mysql의 root에 진입한 것을 알 수 있다.

 

mysql -u root -p

mysql에 들어가서 아까 설정한 비밀번호 1234를 입력하면 성공적으로mysql에 완전히 들어온 것을 볼 수 있다.

(다시 원래 docker로 돌아가려면 exit을 치면 된다)

Volume Mount

docker container를 실행했을 때 사용한 파일들은 컨테이너를 삭제할 때 삭제된다.

host와 container의 파일공유가 되지 않는데, 파일을 유지하고 싶다면

host와 container의 저장소를 공유하게 해야한다. 그게 volume mount이다.

docker run -it -p 3306:3306 -v /documents/host_folder:/home/docs/container_folder
# -v 호스트 폴더:컨테이너 폴더 로 묶어주면 volume mount를 할 수 있다.

지금까지 한 것을 정리하면 이렇게 될 것 같다

 

Docker Image 만들기

직접 docker image를 이제 만들어보자

FastAPI 애플리케이션을 실행하는 서버를 여는 docker이미지를 만들 것이다.

 

windows terminal->wsl로 들어간다

 

python3 -V
>>>Python 3.8.10

파이썬 버전을 확인한다.

 

python3 -m venv .venv

안되서

sudo apt install software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa

좀 오래 설치한다.

sudo apt-get install python3-venv

다시 sudo apt-get install python3-venv을 시도했더니 이제 된다.

source .venv/bin/activate

이렇게 .venv로 들어가진다.

그상태에서

pip install pip --upgrade
pip install "fastapi[all]"

을 하면 많은 것을 설치한다.

 

FastAPI 코드 작성

github에서 예시 코드를 받아서 같은 폴더에 넣어준다.

 

이제 지금까지 어떤 package를 사용하고 있었는지를 저장해야 docker image를 통해 다른 docker container를 만들 때에도 같은 설정을 유지할 수 있다.

 

pip freeze # 설치한 모든 라이브러리를 보여준다.

쭉쭉 밑에 출력된다

이 내용들을 저장하자

pip freeze > requirements.txt

이렇게 저장된다.

pip list --not-required --format=freeze

이 코드도 설치된 라이브러리들도 보여주는데, 그 라이브러리를 사용하기 위해서 필요한 하위의 라이브러리들은 보여주지 않는다.

Docker file 만들기

docker image는 보통 Dockerfile이라는 파일을 필요로 한다. 그래서 Dockerfile을 만들어준다.

코드는 github에서 가져왔다.

docker image를 빌드하기 위한 정보를 담고 있다.

이미지 빌드에 필요한 베이스 이미지 위에서 새로운 설정들을 추가한다.

파란 줄 하나하나가 layer가 된다. run은 2개가 묶여서 하나의 layer가 된다.

파일유형을 지정하지도 않았는데 알아서 고래모양으로 바뀌는게 신기하다.

 

docker build . -t my-fastapi-app  # . : 현재 폴더 # -t : 태그. 태그 미지정시 lastest로 채워진다.

현재폴더를 my-fastapi-app이라는 이름을 가진 이미지로 빌드한다.

근데 오류가 나서

 

맨 밑의 설정은 켰는데 비활성화 된건 windows home을 쓰면 안 켜진다고 해서 알아봤다.

 

내 windows가 홈인지 오늘 처음 알게 되었다 ㅎㅎ

그래서 안될 줄 알았는데  팀원 분들이

여기에서 Ubuntu 켜면 될거라고 하셨다. 그래서 켜고 다시 시도했는데

executor failed running [/bin/sh -c pip install pip==21.2.4 &&     pip install -r requirements.txt]: exit code: 1

이렇게 에러가 났다.

아까 만든 requirements에서 pkg_resources==0.0.0을 삭제하고 저장하면 된다고 하셔서 했더니 드디어 빌드 성공!!

 

docker images

존재하는 image들을 살펴보면 my-fastapi-app으로 잘 만들어진 것을 볼 수 있다.

 

이제 방금 만든 이미지를 실행한다.

docker run -p 8000:8000 my-fastapi-app

아까 main.py fast api에서 포트를 8000으로 지정해주었기 때문에 8000번 포트를 사용한다.

다른 터미널을 열어서 되나 실행해본다.

나는 지금 windows terminal을 사용하고 있기 때문에 cmd를 열었다

curl localhost:8000/hello

성공적으로 메세지를 받았다