on
Docker
Docker
컨테이너란
Linux 컨테이너는 실행에 필요한 모든 파일을 포함하여 전체 런타임 환경에서 애플리케이션을 패키지화하고 분리하는 기술입니다. 이를 통해 전체 기능을 유지하면서 컨테이너화된 애플리케이션을 환경(개발, 테스트, 생산 등) 간에 쉽게 이동할 수 있습니다.
기존 Virtual Machine과 차이
가상화는 하이퍼바이저(VMWare, VirtualBox)를 사용하여 하드웨어를 에뮬레이션하고 이를 통해 여러 운영 체제(Guest OS)를 동시에 실행하는데, Guest OS를 통해 실행되므로 매우 무겁습니다. Linux 컨테이너는 운영 체제(Host OS)에서 기본으로 실행되고 모든 컨테이너 전체에서 운영 체제(Host OS)를 공유하므로 애플리케이션과 서비스를 가볍게 유지할 수 있으며 빠른 속도로 동시에 실행할 수 있습니다. 기존 가상화기술은 Host OS, Guest OS 두 개의 커널을 지니며, 컨테이너는 한개의 Host OS을 지니기 때문에, 오버헤드가 적습니다.
docker란 무엇인가?
IT 소프트웨어인 “Docker”는 Linux 컨테이너를 만들고 사용할 수 있도록 하는 컨테이너화 기술입니다. 프로세스를 격리시켜서 사용하는 방식이기 때문에 가볍고 빠른 동작이 가능하며, 하나의 서버의 여러개의 컨테이너를 실행하면 서로 영향을 미치지 않고 독립적으로 실행되어 가벼운 VM을 사용하는 느낌을 줍니다. 실행중인 컨테이너에 접속하여 명령어를 입력할 수 있고 apt-get이나 yum으로 패키지를 설치할 수 있으며 사용자도 추가하고 여러개의 프로세스를 백그라운드로 실행할 수도 있습니다. CPU나 메모리 사용량을 제한할 수 있고 호스트의 특정 포트와 연결하거나 호스트의 특정 디렉토리를 내부 디렉토리인 것처럼 사용할 수도 있습니다.
Docker는 컨테이너뿐만 아니라, 도커 이미지와 레이어 저장 방식을 활용해 쉽고 간단하게 활용할 수 있게 만들어졌습니다. 컨테이너에 실행에 필요한 파일과 설정 값을 포함한 이미지를 생성하고, 그 이미지로 여러개의 컨테이너로 만들 수 있습니다. 컨테이너를 삭제해도 이미지는 남아 있기 때문에 언제든지 다시 컨테이너를 만들어 실행할 수 있습니다. 이미지 읽기 전용이며 Docker Hub에 공유하거나 내려받아 이용할 수 있습니다.
이미지에 추가데이터를 넣을 때, 매번 이미지를 처음부터 생성하거나, 다운로드를 받으면 비효율적입니다. 이 때 레이어라는 개념을 도입하여, 여러개의 레이어를 하나의 파일 시스템으로 사용할 수 있게 해줍니다. 컨테이너를 생성할 때도 레이어 방식을 사용하는데 기존의 이미지 레이어 위에 읽기/쓰기read-write 레이어를 추가합니다. 이미지 레이어를 그대로 사용하면서 컨테이너가 실행중에 생성하는 파일이나 변경된 내용은 읽기/쓰기 레이어에 저장되므로 여러개의 컨테이너를 생성해도 최소한의 용량만 사용합니다.
Dockerfile
Docker는 이미지를 만들기 위해 Dockerfile이라는 파일에 DSL 언어를 사용하여, 이미지 생산과정을 기록합니다.
# 기반 이미지 예제는 CentOS 7 이미지
FROM centos:centos7.4.1708
# 작성자 정보 설정
MAINTAINER Oliver <oliver@bravecompany.io>
# Apache2.4.10 설치
# RUN은 명령어를 실행하는 Dockefile 명령어
# RUN으로 실행한 결과가 새 이미지로 생성되고, 실행 내역은 이미지의 히스토리에 기록됩니다.
RUN yum -y install gcc-c++ zlib-devel expat-devel pcre-devel openssl-devel
RUN wget https://archive.apache.org/dist/httpd/httpd-2.4.10.tar.gz \
&& wget https://archive.apache.org/dist/apr/apr-1.6.5.tar.gz \
&& wget https://archive.apache.org/dist/apr/apr-util-1.6.1.tar.gz \
&& tar -zxvf httpd-2.4.10.tar.gz \
&& tar -zxvf apr-1.6.5.tar.gz \
&& tar -zxvf apr-util-1.6.1.tar.gz \
&& mkdir -p ./httpd-2.4.10/srclib \
&& mv apr-1.6.5 httpd-2.4.10/srclib/apr \
&& mv apr-util-1.6.1 httpd-2.4.10/srclib/apr-util
RUN cd ./httpd-2.4.10 && ./configure --prefix=/usr/local/apache --enable-all --enable-so --enable-rewrite --enable-ssl --with-include-apr --with-mpm=prefork && make && make install && ln -s /usr/local/apache/apachectl /etc/init.d/apache
# ADD는 DockerFile이 위치하는 경로에서 호스트의 파일을 컨테이너 내부로 파일 복사하는 Dockefile 명령어 입니다.
ADD scripts/start.sh /start.sh
RUN sed -i -e 's/\r$//' /start.sh
RUN chmod 755 /start.sh
# ENV는 환경변수를 설정할 수 있씁니다.
# 환경변수는 RUN, CMD, ENTRYPOINT에 적용하여 사용할 수 있습니다.
ENV COMPANYNAME BRAVECOMPANY
# COPY 파일 또는 디렉토리를 복사하는 명령어 입니다.
COPY test /test
# USER는 명령어를 실행하는 계정을 지정하는 명령어 입니다.
USER nobody
# WORKDIR 작업 디렉토리를 변경하는 명령어 입니다.
WORKDIR /data
# 호스트와 연결할 포트를 지정하는 Dockefile 명령어 입니다.(외부에 노출할려면 별도의 작업필요)
EXPOSE 80 443
# docker run, docker start으로 컨테이너 시작시 실행되는 명령어 입니다.
CMD ["/start.sh"]
이 외에도 다양한 명령어가 있습니다. DockerFile reference
Docker 명령어
# 도커이미지를 가지고 컨테이너를 생성 후 실행하는 명령어 입니다.
docker run 이미지명
# 실행된 컨테이너 터미널에 접속하는 명령어 입니다.
docker attach 컨테이너ID
# DockerFile을 빌드하는 명령어 입니다.
docker build 경로
# docker 이미지 목록을 보는 명령어 입니다.
docker images
# docker 컨테이너를 목록을 확인하는 명령어 입니다.
docker ps
# docker 컨테이너를 삭제하는 명령어 입니다.
docker rm 컨테이너ID
# docker 이미지를 삭제하는 명령어 입니다.
docker rmi 이미지명
# 실행 중이 docker 컨테이너를 정지시키는 명령어 입니다.
docker stop 컨테이너ID
# 정지된 docker 컨테이너를 다시 실행하는 명령어 입니다.
docker start 컨테이너ID
이 외에도 다양한 명령어가 있습니다. Docker base command
docker-compose
Docker Compose는 다수의 컨테이너를 쉽게 운용하기 위해 만들어진 도구 입니다. Docker Compose 설정파일 docker-compose.yml에 정이를 입력하고 실행하면, 이 파일을 읽어 컨테이너를 순차적으로 생성합니다.
docker-compose.yml
version: "2"
services:
nginx:
image: nginx
restart: always
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- /data/web:/usr/share/nginx/html
ports:
- "80:80"
links:
- php:php
php:
image: php:7.2-fpm
restart: always
expose:
- "9000"
links:
- mysql
- redis
volumes:
- /data/web:/usr/share/nginx/html
mysql:
image: mysql
restart: always
ports:
- "3306:3306"
volumes:
- /data/mysql:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
redis:
image: redis
restart: always
ports:
- "6379:6379"
volumes:
- /data/redis:/data
command: redis-server --appendonly yes
위와 같이 작성하면, nginx php mysql redis 컨테이너를 한꺼번에 생성 및 연결할 수 있습니다.
docker-compose 명령어
# docker compose 서비스 생성 및 실행
docker-compose up
# docker compose 서비스 정지 및 삭제
docker-compose down
# docker compose 서비스 재시작
docker-compose restart
# docker compose 서비스 시작
docker-compose start
# docker compose 서비스 정지
docker-compose stop
# docker compose 서비스 빌드
docker-compose build
이 외에도 다양한 명령어가 있습니다. docker compose command
제가 사용하는 이유는?
- 도커 컴포즈와 도커 이미지를 잘 조합을 하면, 개발 환경은 금방 뚝딱하고 만들어낼 수 있습니다. docker hub
- Docker만 설치 되어있으면, 동일한 환경을 구축할 수 있습니다. 개발환경 뿐만 아니라, 실제 서비스 서버에 반영했을 때도, Docker로 구현시 동일한 환경을 구축하기 쉽습니다.
- 개발환경 또는 서버환경이 문서화 되기 때문에, 다른 사람들도 쉽게 파악할 수 있습니다.
- VM파일 같이 OS를 포함한 파일을 보관할 필요 없이, 간단한 설정파일과 dockerfile, docker-compose.yml만 있으면 되기에 보관하기 좋습니다.
- 변경사항이 있을 때, 처음부터 빌드하지 않아도 되고, 공유하기 쉽습니다.
- 호스트의 데이터를 공유할 수 있기 때문에, 로컬 가상웹서버를 구축 후 소스파일을 FTP로 올리지 않아도 됩니다.
참고
https://docs.docker.com/ https://www.redhat.com/ko/topics/containers/what-is-docker https://judo0179.tistory.com/14 https://www.44bits.io/ko/post/why-should-i-use-docker-container