도커(Docker)
이번 포스팅에서는 도커(Docker)에 대해서 알아보고자 한다.
도커를 알기 위해서는 먼저 가상머신에 대해서 알아야 한다.
가상머신(Virtual Machine)
가상머신이란, 소프트웨어로 가상의 하드웨어를 구현하고 그 위에서 운영체제를 작동시키는 기술이라고 할 수 있다.
가상머신을 사용하면 자신의 컴퓨터와는 별개로 또 하나의 운영체제를 사용할 수 있다.
예를 들면, Windows를 사용하고 있는 컴퓨터에 가상머신을 설치하고 Linux를 작동시키면 Windows가 설치된 컴퓨터에서 Linux를 사용할 수 있게 된다.
또한, 새로운 운영체제를 만듬으로써 독립된 또 하나의 작업 공간을 만들 수 있다.
많이 사용되는 하드웨어 가상머신 소프트웨어로는 VMware, VirtualBox 등이 있다.
도커(Docker)
도커를 사용하는 목적은 가상머신과 크게 다르지 않다.
하지만 OS 전체를 가상화하는 기존의 가상머신과는 다르게, 도커는 프로세스를 격리시킨다.
도커와 가상머신의 차이는 아래 그림처럼 표현할 수 있다.
가상머신은 host 운영체제 위에 또 다른 가상화된 운영체제를 작동시키지만 도커는 운영체제를 통째로 가상화하는 것이 아니라 프로세스만을 격리시키고 host 운영체제의 자원을 분리된 상태로 제공받는다.
이런 격리 단위를 컨테이너(Container)라고 한다.
이처럼 운영체제를 통째로 격리시키는 것이 아니라 컨테이너 단위로 격리시킴으로써 가상머신보다 더 가볍게 가상화를 사용할 수 있다.
컨테이너(Container)
컨테이너는 도커엔진(Docker Engine) 위에서 작동하는 가상화 단위이며 경량화된 가상머신이라고 생각할 수 있다.
실행중인 컨테이너에 접속해서 명령어를 입력할 수도 있고 프로세스를 실행시킬 수도 있다.
운영체제를 가상화시키는 가상머신보다 훨씬 가볍기 때문에 새로운 컨테이너를 만들어 작동시키는데 걸리는 시간은 몇 초 단위이다.
하나의 운영체제 위에 여러개의 컨테이너를 만들어서 서로 격리된 작업 공간을 만들 수도 있다.
또한, 컨테이너는 이식성이 뛰어나고 할 수 있다.
어플리케이션 컨테이너를 만들어서 배포하면 다른 시스템에서도 환경을 구축할 필요 없이 도커만 있다면 컨테이너를 작동해 어플리케이션을 실행시킬 수 있다.
하지만, 컨테이너는 기본적으로 저장이 되지 않기 때문에 컨테이너를 종료시키고 다시 실행시키면 정보가 손실된다.
데이터 볼륨(Volume)을 따로 만들어두고 컨테이너에 마운트 시키거나 독립적인 데이터베이스에 정보를 저장하는 방법으로 이러한 문제를 해결할 수 있다.
이미지(Image)
이미지는 컨테이너의 실행에 필요한 파일과 설정 등을 가지고 있으며 상태값을 갖지 않으며 변하지 않는다.
컨테이너를 만들어내는 틀이라고 생각할 수도 있으며, 반대로 컨테이너는 이미지를 실행한 것이라고 생각할 수 있다.
당연하게도, 하나의 이미지로 여러개의 컨테이너를 만들 수 있다.
이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 이미지를 다운 받으면 추가적인 설치 없이 컨테이너를 실행할 수 있다.
또한 Dockerfile이라는 파일에 명령어를 작성해서 새로운 이미지를 빌드할 수 있다.
빌드한 이미지는 Docker hub에 등록할 수 있으며 다른 사용자들이 등록한 이미지를 다운받아 사용할 수도 있다.
Github에 코드를 올리거나 다른 사용자들의 코드를 다운받는 것과 비슷하게 생각하면 된다.
컨테이너와 이미지의 관계는 아래 그림처럼 표현할 수 있다.
도커 이미지는 명령어로 간단하게 다운받을 수 있으며 이미지는 아래와 같은 포맷으로 저장된다.
[저장소]/[이미지 이름]:[태그]
ex) gusalsdmlwlq/ubuntu:16.04
도커 공식 이미지인 경우 [저장소]는 생략된다.
태그도 생략될 수 있으며, 이 경우는 자동으로 latest가 붙는다.
[이미지 이름]:latest
ex) ubuntu:latest
도커 기본 명령어
-
버전 확인
$ docker -v $ docker --version
-
이미지 검색
$ docker search [이미지 이름]
-
이미지 다운로드
$ docker pull [저장소]/[이미지 이름]:[태그] * 태그를 생략시, 자동으로 latest가 붙음 * 공식 이미지는 [저장소]가 생략됨
-
이미지 목록 확인
$ docker images
-
이미지 삭제
$ docker image rm [저장소]/[이미지 이름]:[태그]
-
컨테이너 생성 & 실행
$ docker run [옵션] [저장소][이미지 이름]:[태그] * -i: interactive한 컨테이너를 생성 * -t: tty를 활성화(bash를 실행) * --rm: 컨테이너가 종료되면 자동으로 제거 * --name [이름]: 컨테이너의 이름을 [이름]으로 설정 * -v [host 경로]:[컨테이너 경로]: [host 경로]를 컨테이너 내부의 [컨테이너 경로]에 마운트 * -e [변수]=[값]: 컨테이너 내부의 환경 변수, [변수]의 값을 [값]으로 설정 * -p [host port]:[컨테이너 port]: host의 [host port]와 컨테이너의 [컨테이너 port]를 바인딩
-
컨테이너 목록 확인
$ docker ps
-
컨테이너 중지
$ docker stop [컨테이너 이름] $ docker stop [컨테이너 id]
-
컨테이너 삭제
$ docker rm [컨테이너 이름] $ docker rm [컨테이너 id]
Dockerfile
Dockerfile은 이미지를 생성하기 위한 파일이다.
명령어들을 작성해두고 빌드하면 명령어대로 도커 이미지를 생성할 수 있다.
Python Flask 예시
hello_flask.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_flask():
return "Hello Flask!"
if __name__=='__main__':
app.run(debug=True,host='0.0.0.0')
Dockerfile
FROM python
COPY . /app
WORKDIR /app
RUN pip install flask
EXPOSE 5000
CMD ["python", "hello_flask.py"]
- python 이미지를 다운
- host의 현재 경로의 폴더를 /app에 복사
- 작업 directory를 /app으로 변경
- pip으로 flask를 설치
- 컨테이너의 5000번 port를 개방
- hello-flask.py를 실행
이미지 빌드
$ docker build -t hello-flask .
현재 경로의 Dockerfile로부터 hello-flask라는 도커 이미지를 빌드한다.
컨테이너 실행
$ docker run -p 5000:5000 hello-flask
빌드한 hello-flask 이미지를 컨테이너로 실행시키고 컨테이너의 5000번 port와 host의 5000번 port를 바인딩한다.
http://localhost:5000에 접속하면 아래와 같은 화면을 볼 수 있다.
Leave a comment