Docker
업데이트:
Docker
도커는 2013년 3월에 출시한 오픈소스 컨테이너 프로젝트입니다.
서버시장이 클라우드 환경으로 옮겨가게 되면서 우리는 가상서버를 손쉽게 수백대를 구매하여 바로 사용할 수 있게 되었습니다. 그런데, 서버 갯수가 많아지면서 각각의 서버에 소프트웨어 설치와 설정이 큰 귀찮음으로 다가오게 됐습니다. 몇개 안됐다면 직접 할텐데 갯수가 엄청나니 이것을 처리할 무언가가 필요했습니다.
초기에 쉘 스크립트를 통해 해결하려는 시도도 있었습다. 이 방법으로 필자도 오랜기간 서버 관리를 해왔습니다. 그러나 쉘 스크립트는 복잡한 기능 구현은 거의 불가능 할 뿐더러 자동화의 한계가 있습니다. 이를 어떻게 해결 할 것인가.
이를 해결하기 위해 나온 아이디어가 바로 Immutable Infrastructure입니다. 그 서버에 깔린 OS(호스트 OS)와 서비스 운영을 위한 환경(서버 운영을 위해 필요한 프로그램들; node js, mysql, java등)을 분리해 이 서비스 운영환경을 패키징 해 배포한다는 아이디어입니다. 이때 이 패키지를 데몬툴즈같은 가상 이미지 파일과 비슷하다해서 이미지라 부릅니다. 어쨋든 이런 생각을 구현한 것이 Docker입니다.
이것은 엄청난 확장성을 가져다 줍니다. 클라우드 플랫폼에 이것을 적용하면 자동 확장이 가능해지고 마치 공장에서 틀에 물건을 찍어내듯 마구마구 서비스를 확장할 수 있습니다.
개요
Docker는 지금까지 사용해왔던 VMware, Microsoft Hyper-V(Virtual PC), Xen 등의 같은 가상 머신과 비슷합니다.
가상 머신에 리눅스를 설치한 뒤 각종 서버와 DB를 설치하고, 개발한 어플리케이션이나 웹사이트를 실행했습니다.
이렇게 세팅한 가상 머신 이미지를 여러 서버에 복사해서 실행하면 이미지 하나로 서버를 계속 만들어 낼 수 있었습니다.
보통 가상 머신 서버를 독자적으로 운영하거나, 서비스 형태로 제공되는 AWS, Microsoft Azure를 사용하기도 합니다.
Docker는 반가상화보다 좀더 경량화된 방식입니다. 그림에서 보는것과 같이 Guest OS를 설치하지 않습니다.
Docker 이미지에 서버 운영에 필요한 프로그램과 라이브러리만 격리해서 설치할 수 있고, OS 자원은 Host와 공유합니다.
이렇게 되면서 이미지 용량이 크게 줄어들었고 가상화 레이어가 없기 때문에 파일 시스템, 네트워크 속도도 가상 머신에 비해 월등히 빠릅니다.
Virtual Machine과 차이점
언뜻 들으면 가상머신과 똑같습니다. 가상 머신에 리눅스를 설치하고 그 가상 머신을 이미지화해 여러 서버에 복사하면 똑같은 것 같지만……좀 다릅니다.
Virtual Machine
가상 머신은 편했습니다. 가상 머신 자체는 거의 완전한 컴퓨터입니다.
이게 무슨말이냐하면, 가상머신은 기본적으로 원래 컴퓨터 OS(호스트OS)위에서 돌아갑니다.
그리고 그 가상머신은 하이퍼바이저를 통해 그 위에서 수십개의 게스트 OS를 돌립니다. 즉 게스트 OS가 독자적으로 돌아가는 가상 컴퓨터 인 것입니다. 올리고 올라가고 올라가서 실행되니 느린건 당연지사.
OS를 자체적으로 가지고 있다는 것은 OS를 가상 머신 이미지에 포함해야 했고, 이렇게 되다보니 이미지 용량이 상당히 컷습니다. 그리고 이것은 상당히 배포와 관리를 힘들게 했습니다. 인터넷이 빨라도 엄청난 용량은 부담인건 똑같습니다.
Docker와 차이점
도커는 이를 더 가볍게 만들었습니다. 게스트 OS를 없애버렸습니다. Docker는 호스트 OS를 사용해서 동작합니다.
즉 호스트 OS의 시스템 콜을 직접 호출합니다. 이것은 매우 빠른 속도로 작동할 수 있음을 의미합니다.(실제 빠른가는 별개의 문제기에)
도커는 도커 이미지에 서버 운영을 위한 프로그램과 라이브러리를 포함하고 있습니다.
이런 이미지들은 도커로 각각 격리되어 설치됩니다.
즉 도커 엔진이 도커 이미지를 설치할 때, 마치 가상 머신처럼 분리 시켜준다는 것입니다. 그러나 호스트 OS는 공유합니다.
도커를 사용하면 호스트OS위에서 바로 돌리는 것과 비슷한 성능 수준을 얻을 수 있습니다. 99%정도까지 유사하다고 합니다.
Docker가 제공하는 Docker Hub
도커는 이미지 생성과 배포에 특화된 기능을 제공합니다. 마치 Git처럼 이것을 이용하면 이미지를 push/pull할 수 있습니다. 뿐만 아니라 이것들을 공유할 수 있는 Git-Hub과 같은 도커허브를 제공합니다.
Docker Image vs Container
도커에는 이미지와 컨테이너라는 2가지의 헷갈리는 단어가 존재합니다. 또 이미지는 베이스 이미지와 도커 이미지로 구분됩니다.
Base Image
베이스 이미지란, 리눅스 배포판의 커널 영역을 제외한 사용자 공간/영역(유저랜드)만을 이미지에 포함한 파일을 의미합니다. 이때 사용자공간/영역(유저랜드)란, 커널 공간/영역과 관련된 것들을 제외한 부팅시 필요한 몇몇 실행파일과 라이브러리, 그리고 패키징 시스템(우분투의 apt같은)것들을 포괄해서 부르는 명칭입니다. 이 유저랜드 혹은 사용자공간/영역에 Redis나 Nginx등을 설치해서 베이스 이미지로 배포하기도 합니다.
유저랜드에는 각 리눅스 배포판의 특징이 고스란히 있어서 각 배포판 고유의 패키징 툴도 그대로 활용 할 수 있습니다. 이 베이스 이미지는 변형되거나 뭔가가 추가 설치될 수 있는데 이렇게 해서 변형된 이미지를 도커 이미지라 부릅니다.
Docker Image
도커 이미지는 베이스 이미지에서 몇가지를 라이브러리, 프로그램, 소스 파일등을 추가/설치/저장한 이미지입니다. 도커 이미지는 베이스이미지부터 상속받듯이 만들어집니다. 즉, 베이스이미지에서 추가되거나 변형되는 부분만 도커 이미지에 저장됩니다. 이렇게 만들어진 도커 이미지는 또 수정될 수 있는데, 이렇게 수정되면 또 그 변형된 부분만 다시 도커 이미지에 저장됩니다.
첫번째 변화후 저장된 도커 이미지를 A라 하고, 두번째 변화후 저장된 도커 이미지를 B라 하면,
베이스 이미지 + A + B
를 하여 도커 이미지 실행이 시작됩니다. 이 때 도커는 필요한 파일을 부모이미지부터 자식이미지까지 싹 받아서 합칩니다. 이렇게하여 실행된 이미지를 우리는 컨테이너라 부릅니다.
Container
도커 컨테이너는 이미지가 실행된 상태를 뜻합니다. 이미지 하나로는 수백개의 컨테이너를 생성할 수 있습니다. 마치 이 관계는 실행파일과 프로세스의 관계 같은 것입니다.
Docker Architecture
- Client : 도커 Container를 관리하고 실행하기 위해서 Deamon과 상호작용하는 Binary 파일.
- Registry : 도커 Image가 저장되어 대표적 장소는 Docker Hub. Registry는 Public Registry와 Private Registry가 있음.
- Daemon : Host에 설치되어 도커 Container를 관리하는 daemon 프로세스. Client와 상호작용.
- Image : 도커 Daemon을 통해 Container로 실행 가능하도록 필요한 프로그램, 라이브러리, 소스 등이 설치된 파일.
- Container : Image를 실행한 상태.
Docker Ecosystem
Docker 지원 OS
Docker 장/단점
장점
- 서버 운영이 쉽다
- Docker Hub를 통해 이미지 버전관리 가능
- 서버가 어떤 것이든 빠른 이동 및 확장 가능
- 이미지에 OS가 없기 때문에 용량 절감
- 하드웨어를 가상화하는 계층이 없어 메모리 접근, 파일시스템, 네트워크 속도가 월등히 빠름
단점
- Linux 이외의 운영체제는 설치/실행 할 수 없음
- 리눅스 커널을 사용하기 때문에 리눅스 외의 운영체제는 Container로 생성 불가
Docker Install
각 운영체제별 Docker 설치 방법은 공식 홈페이지에 잘 정리되어 있습니다. 본 가이드에서는 Ubuntu 18.04 LTS 64bit 기준으로 설명하겠습니다.
Apt Source Update
- 패키지 정보 업데이트 및 설치
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates - GPG key 추가
curl -fsSL https://download.docker.com/linux/ubuntu/gpg sudo apt-key add - - 저장소 추가
$ sudo add-apt-repository “deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable”
- apt package update 및 저장소 삭제(이전 버전)
$ sudo apt-get update
$ sudo apt-cache policy docker-ce
Install
- sudo 권한으로 로그인 및 apt package index update
$ sudo apt-get update
- Docker Install
$ sudo apt install docker-ce
- Daemon 시작
$ sudo systemctl status docker
Docker Group 생성
- sudo 권한으로 로그인 및 docker group 생성
$ sudo groupadd docker
- 사용자 계정 추가 및 Docker 명령어 실행여부 확인
$ sudo usermod -aG docker $USER
$ sudo gpasswd -a ${USER} docker
$ newgrp docker
$ sudo chmod 666 /var/run/docker.sock
$ docker ps -a
기타 설정
- DNS 설정 및 내부 DNS를 사용한다면 다음과 같이 설정
$ vi /etc/default/docker
–dns 8.8.8.8 –dns {내부 DNS IP} - Docker Daemon Restart
$ sudo service docker restart
- 부팅 시 Docker 자동 실행
$ sudo systemctl enable docker
Docker Upgrade & Delete
- Docker Upgrade
$ sudo apt-get upgrade docker-engine
- Docker Package 삭제 & Docker 모든 파일 삭제
docker-engine 삭제 및 Docker Package와 의존성 있는 파일은 모두 삭제됨$ sudo apt-get purge docker-engine
$ #sudo apt-get autoremove –purge docker-engine
Docker 명령어
docker + command
Host OS에 접속하여 “sudo docker”를 실행하게 되면 다음과 같은 명령어 정보를 볼 수 있습니다.
- Docker 명령어는 docker + command 형식으로 사용하고, 항상 root 권한 으로 실행합니다.
자세한 명령어 사용법은 검색을 활용하시고 본 가이드에서는 기반 시스템 Docker Container 환경으로 구성되어 있어 프로젝트 진행 중에 모니터링 및 운영 방안에 대해 설명합니다.
Docker 기본 명령어 - Image
Docker로 구성된 시스템 운영을 위해서는 다음과 같이 Docker 기본 명령어는 숙지해야합니다.
라이프 사이클
docker images 모든 이미지 목록을 보여줌
docker import talball 파일로부터 이미지 생성
docker build Dockerfile을 통해 이미지를 생성
docker commit 컨테이너에서 이미지를 생성
docker rmi 이미지 삭제
docker insert URL에서 이미지로 파일을 삽입
docker load 표준 입력으로 tar파일에서 이미지를 불러옴
docker save 모든 부모 레이어와 태그, 버전 정보를 tar 형식으로 표준출력을 통해
docker impor와 docker commit 파일 시스템만 셋업하고 Dockerfile과 같은
CMD, ENTRYPOINT, EXPOSE는 포함하지 않음
관련된 정보 출력해주는 명령어
docker login 레지스트리에 로그인
docker search 레지스트리에서 이미지 검색
docker pull 이미지를 레지스트리에서 로컬 머신으로 다운
docker push 이미지를 로컬 머신에서 레지스트리에 업로드
Docker 기본 명령어 - Container
Docker로 구성된 시스템 운영을 위해서는 다음과 같이 Docker 기본 명령어는 숙지해야합니다.
라이프 사이클
docker run 컨테이너를 생성
docker stop 컨테이너를 정지
docker start 컨테이너를 다시 실행
docker restart 컨테이너를 재가동
docker rm 컨테이너를 삭제
docker kill 컨테이너에게 SIGKILL을 보냄
docker attach 실행중인 컨테이너에 접속.
docker wait 컨테이너가 멈출 때까지 블럭
관련된 정보 출력해주는 명령어
docker ps 명령어는 실행중인 컨테이너 목록을 보여줌
docker inspect ip 주소를 포함한 특정 컨테이너에 대한 모든 정보를 보여줌
docker logs 컨테이너로부터 로그를 가져옴
docker events 컨테이너로부터 이벤트를 가져옴
docker port 컨테이너의 특정 포트가 어디로 연결되어있는지 보여줌
docker top 컨테이너에서 실행중인 프로세스를 보여줌
docker diff 컨테이너 파일 시스템에서 변경된 파일들을 보여줌
Docker 활용 가이드
기반 시스템을 활용하기 위해서는 몇가지 명령어에 대해서 숙지하고 있어야 합니다.
image 생성부터 container 로그 확인까지 기본적인 사용방법을 알고 있다면 기반 시스템 사용에 있어서 문제될것은 없다고 생각됩니다.
image 정보 출력
docker images
Host OS에 접속하여 sudo docker images 명령어로 이미지 목록을 출력할 수 있습니다.
container 상태
docker ps -a
Docker Container 상태는 sudo docker ps -a 명령어로 확인할 수 있으며, 특이사항이 없으면 대부분 STATUS 부분에 “Up xx days or weeks”라고 출력됩니다.
container 시작
docker start {container name}
중지된 container를 sudo docker start {container name} 명령어로 시작할 수 있습니다.
container name 대신 container id로 사용해도 됩니다.
container 정지
docker stop {container name}
Container를 정지할때 sudo docker stop {container name} 명령어로 정지할 수 있습니다.
container name 대신 container id로 사용해도 됩니다.
container 재시작
docker restart {container name}
Container를 재시작할때 sudo docker restart {container name} 명령어로 재시작할 수 있습니다.
container name 대신 container id로 사용해도 됩니다.
container 로그
docker logs {container name}
Container 로그를 확인할 때는 Container에 접속하여 Application 로그를 직접 확인할 수도 있지만, sudo docker logs {container name} 명령어로 확인할 수 있다.
container 접속
docker exec -it {container name} bash
docker exec -it -u root {container name } bash
Container에 접속하여 정보를 볼때 사용하는 명령어로, Docker Image 생성 방법에 따라 일반 계정으로 접속되는 경우도 있고 root계정으로 접속되는 경우도 있습니다.
첫번째 명령어는 기본 계정으로 접속하는 방법이고, root 권한이 필요한 경우라면 두번째 명령어로 -u root 옵션을 주고 실행하면 root 권한으로 Container에 접속할 수 있습니다.
Docker Image 생성
Docker 이미지 생성 방법에는 두가지가 있습니다. Docker Hub에서 이미지를 검색하고 “pull” 명령어를 사용해서 생성하는 방법과 “dockerfile”을 Build하여 생성하는 방법이 있습니다.
Docker를 처음 사용하시는분은 이미 생성된 이미지를 “pull”해서 HostOS에 저장하고 container를 실행하시면 됩니다.
사용하면서 조금 익숙해지면 직접 “dockerfile”을 작성하셔서 이미지를 생성하시면 자신만의 Docker Image가 만들어 집니다.
Docker search
sudo docker search {image name}
Docker Hub를 통해 이미지 공유가 가능합니다. sudo docker search {image name} Docker Hub에서 이미지 검색을 할 수 있습니다.
많은 이미지가 검색되며, 보통 Ubuntu, CentOS, Redis 등 OS나 프로그램 이름을 가진 이미지가 공식 이미지입니다. 나머지는 사용자들이 만들어 공개한 이미지입니다.
Docker pull
sudo docker pull {image name}:{tag}
sudo docker pull {image name} 명령어로 Docker Hub에서 검색한 image를 다운로드합니다.
태그명을 생략하면 기본적으로 가장 최신 버전(latest)을 다운로드하며, 모든 태그의 이미지를 받기 위해서는 “-a” 옵션을 줍니다.
Docker build
sudo docker build -t {image name} {Dockerfile path}
Docker build는 Dockerfile을 통해서 이미지를 생성하는 방법입니다. Dockerfile은 Docker 이미지를 만들기 위해 Container에 필요한 라이브러리, 프로그램, 소스 파일등을 추가/설치/저장한 내용으로 작성된 파일입니다.
Docker Hub에서 이미지를 검색하면 pull 할 수 있는 명령어와 Dockerfile이 작성되어 있는데, Dockerfile에 추가하고 싶은 사항을 추가하여 sudo docker build -t {image name} {Dockerfile Path} 명령어를 실행하면 Host OS에 작성한 image name 으로 이미지가 생성됩니다.
Dockerfile
Dockerfile은 Program의 Build에 자주 사용되는 Build Automation Tool Makefile과 마찬가지고 Docker Container의 구성 내용을 요약 기술하는 간단한 Text 형식의 파일입니다. 한 행에 하나의 작업을 {명령}과 {인수}로 공백 구분 하여 작성합니다. #부터 시작된 행은 주석 처리가되며 docker build 명령어는 Dockerfile상에서 순서대로 처리됩니다.
FROM 원본 Docker Image를 지정
MAINTAINER 작성자 정보
RUN 명령어 실행
ADD File, Directory 추가
CMD Container의 실행 명령어 1
ENTRYPOINT Container의 실행 명령어 2
WORKDIR 작업 directory
ENV 환경변수 지정
USER 실행 User 지정
EXPOSE Port Export
VOLUME Volume Mount
다음은 내부 DNS를 구성하는 Bind의 Dockerfile의 구성입니다.
FROM sameersbn/ubuntu:14.04.20170123
MAINTAINER sameer@damagehead.com
ENV BIND_USER=bind \
BIND_VERSION=1:9.9.5 \
WEBMIN_VERSION=1.8 \
DATA_DIR=/data \
TZ=Asia/Seoul
RUN rm -rf /etc/apt/apt.conf.d/docker-gzip-indexes \
&& wget http://www.webmin.com/jcameron-key.asc -qO - | apt-key add - \
&& echo "deb http://download.webmin.com/download/repository sarge contrib" >> /etc/apt/sources.list \
&& apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y bind9=${BIND_VERSION}* bind9-host=${BIND_VERSION}* webmin=${WEBMIN_VERSION}* \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y vim && rm -rf /var/lib/apt/lists/*
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY entrypoint.sh /sbin/entrypoint.sh
RUN chmod 755 /sbin/entrypoint.sh
EXPOSE 53/udp 53/tcp 10000/tcp
VOLUME ["${DATA_DIR}"]
ENTRYPOINT ["/sbin/entrypoint.sh"]
CMD ["/usr/sbin/named"]
Docker run
Docker image로부터 Container를 생성하려면 docker run 명령어를 실행해야 합니다.
image에 오류가 없고 정상적으로 container가 생성되면 해당 Container를 사용하면 되지만, 오류 발생 시 Container는 run 옵션에 표기한 name으로 생성되지 않고 임의의 값으로 생성되고 실행되지는 않습니다.
오류 원인을 찾고 수정한 후 다시 Container를 생성한 다음 오류 Container는 삭제합니다.
$ docker run \
–detach \
–env {evironment variables}={value} \
–name {container name} \
–publish {host port}:{container port} \
–volume {host path}:{container path} \
–hostname {container hostname} \
{image name}
Docker run option은 여러가지가 있지만 기반 시스템에서 사용한 옵션은 다음과 같으며, 더 많은 옵션 정보는 Docker Reference를 참조하시기 바랍니다.
-a, --attach=[] : 컨테이너에 표준 입력(stdin), 표준 출력(stdout), 표준 에러(stderr)를 연결.
-d, --detach=false : Detached 모드입니다. 보통 데몬 모드라고 부르며 컨테이너가 백그라운드로 실행.
-e, --env=[] : 컨테이너에 환경 변수를 설정합니다. 보통 설정 값이나 비밀번호를 전달할 때 사용.
-h, --hostname=”” : 컨테이너의 호스트 이름을 설정.
--link=[] : 컨테이너끼리 연결합니다. <컨테이너 이름>:<별칭> 형식.
--name=”” : 컨테이너에 이름을 설정.
-p, --publish=[] : 호스트에 연결된 컨테이너의 특정 포트를 외부에 노출합니다. 보통 웹 서버의 포트를 노출할 때 주로 사용.
--rm=false : 컨테이너 안의 프로세스가 종료되면 컨테이너를 자동으로 삭제. -d 옵션과 함께 사용할 수 없음.
-v, --volume=[] : 데이터 볼륨을 설정. 호스트와 공유할 디렉터리를 설정하여 파일을 컨테이너에 저장하지 않고 호스트에 바로 저장.
지금까지 가이드한 내용으로 Docker Container를 생성하면 다음과 같습니다.
- Dockerfile 작성
- Dockerfile Build
- Image 생성
- Docker Container 생성 (docker run)
- Docker Container 상태 확인
Container 삭제
Docker Run 시 오류가 발생하거나, 필요없는 Container는 정지 후 docker rm 명령어로 삭제 합니다.
sudo docker rm {container name}
Container 정보 조회
생성된 Container의 세부 정보를 출력합니다.
sudo docker inspect {container name}
Image 삭제
불필요한 Docker Image 삭제 시 실행하는 명령어로 docker rmi 다음과 같이 실행하며,
대상 Image를 사용하는 Container가 실행중이거나 Container로 등록 되어 있으면 Image 삭제가 안되므로, Image로 생상한 Container는 정지/삭제하고 Image를 삭제합니다.
sudo docker rmie {image name}
Docker 백업 및 복원
Docker는 Image
와 Container
를 백업 및 복원할 수 있습니다.
Image 백업 및 복원
save
와 load
명령어로 Container에서 사용하고 있는 Image를 tar 파일
로 백업 및 복원이 가능합니다.
Image 백업
$ docker save {docker image name} > {PATH}/{docker backup file name}.tar
Image 복원
$ docker load < {PATH}/{docker backup file name}.tar
Conatiner 백업 및 복원
export
와 import
명령어로 실행중인 Container를 tar or gz 파일
로 백업 및 복원이 가능합니다.
Container 백업
$ docker export {docker container name or id} > {PATH}/{docker backup file name}.tar
$ docker export {docker container name or id} | gzip > {PATH}/{docker backup file name}.tar.gz
Container 복원
$ cat {PATH}/{docker backup file name}.tar docker import - {docker image name}:{tag_name} $ zcat {PATH}/{docker backup file name}.tar.gz docker import - {docker image name}:{tag_name}
다음 저장소 이용하기
BASH
$ sudo vi /etc/apt/sources.list
vi의 치환기능을 이용해 한번에 변경한다.
VIM
:%s/archive.ubuntu.com/mirror.kakao.com/g
BASH
$ sudo apt-get update
$ sudo apt-get upgrade
댓글남기기