What we have to do is to be forever curiously
testing new opinions and courting new impressions

우리가 해야 할 일은 끊임없이 호기심을 갖고
새로운 생각을 시험해보고 새로운 인상을 받는 것

Docker에 대하여

  • Container기술
  • Docker
  • 설치와 명령어
  • 정리


Container기술

서로 다른 소프트웨어의 구성 요소가 서로 다른 혹은 상충될 수 있는 종속 라이브러리의 버전을 필요로 하는 경우, 각 구성 요소에 전용 가상머신VM을 제공해 환경을 격리할 수 있지만, 구성 요소의 점점 작아지고 수가 많아지기 시작하면 하드웨어 리소스의 낭비와 그에 들어가는 비용이 증가

이에 리눅스 컨테이너 기술을 통해 동일한 호스트 시스템에서 여러 개의 서비스를 실행할 수 있으며 동시에 서로 다른 환경을 만들어 주고, VM과 유사하게 서로 격리하지만 오버헤드가 훨씬 적음

VM은 구성 요소 프로세스 뿐만 아니라 시스템 프로세스를 실행해야 하기 때문에 추가 컴퓨팅 리소스를 필요로 함

컨테이너는 호스트OS에서 실행되는 동안 동일한 유일 커널에서 시스템 콜을 받아 수행하고 따로 부팅이 필요하지 않기 때문에 프로세스를 즉시 시작할 수 있음

반면 VM은 각 VM이 부팅하여 자체 리눅스 커널을 실행해 완전한 격리를 제공하기 때문에 보안위험이 현저히 낮음

IMG_0069


Docker

Docker는 컨테이너를 여러 시스템에 쉽게 이식(패키징, 배포, 실행)할 수 있게 해주는 플랫폼

도커에서는 컨테이너 이미지가 여러 이미지에서 공유되고 재사용될 수 있는 레이어로 구성되어 있기 때문에, 동일한 레이어를 포함하는 다른 컨테이너 이미지를 실행할 때 다운로드 된 이미지를 빼고 다른 이미지의 특정 레이어만 다운로드하면 됨

도커의 주요 개념

  • 이미지 : 애플리케이션과 해당 환경을 패키징한 것
  • 레지스트리 : 이미지를 저장하고 다른 사람이나 컴퓨터 간 쉽게 공유할 수 있는 저장소
  • 컨테이너 : 이미지에서 생성된 일반적인 리눅스 컨테이너

도커를 통해 소프트웨어의 이미지를 만들고, 레지스트리로 푸쉬하면, 어디서나 도커를 통해 해당 소프트웨어를 컨테이너로 띄울 수 있음

설치와 명령어

도커 설치

Docker 공식문서(http://docs.docker.com/install/)에 들어가서 운영체제에 맞게 도커 설치

busybox 이미지 실행

도커 CLI로 도커 공개 레지스트리인 docker hub에 있는 busybox라는 이미지를 pull하여 격리된 컨테이너로 실행하고 echo “Hello world”를 통해 명령어 실행

docker run busybox echo "Hello world"

위 커맨드를 입력하면 백그라운드에서 다음과 같이 수행

  1. 도커가 busybox:latest이미지를 로컬에 존재하는지 체크
  2. 없으면 도커 레지스트리에서 해당 이미지를 다운로드
  3. 이미지로부터 컨테이너를 생성
  4. 컨테이너 내부에서 echo 명령어를 실행
  5. echo 명령어는 텍스트를 STDOUT으로 출력하고 프로세스 종료(컨테이너 종료)

애플리케이션 이미지 생성 후 컨테이너 띄워보기

1. 간단한 node.js 애플리케이션인 app.js를 생성

const http = require('http');
const os = require('os');

console.log("server starting...");

var handler = function(req, res) {
    console.log("reveived request from " + req.connection.remoteAddress);
    res.writeHead(200);
    res.end("you've hit " + os.hostname() + "\n");
};

var www = http.createServer(handler);
www.listen(8080);

위 코드는 포트 8080으로 http server를 열고 모든 요청에 대해 200(상태코드)와 해당 애플리케이션의 호스트명을 텍스트와 출력

2. 이미지를 빌드하기 위한 Dockerfile 생성

FROM node:7
ADD app.js /app.js

ENTRYPOINT ["node", "app.js"]

위 코드는 노드 컨테이너 이미지의 태그 7을 사용하고, app.js라는 파일을 루트 디렉토리에 app.js라는 이름으로 추가하고, 명령어로 node app.js라고 실행한다는 의미

3. 컨테이너 이미지 생성

docker build -t {이미지명} .

위 커맨드는 이미지를 빌드하라는 명령어를 의미

4. 컨테이너 이미지 실행

docker run --name {컨테이너별명} -p 8080:8080 -d {프로세스명}

위 커맨드는 도커가 로컬의 8080포트를 컨테이너 내부의 8080포트와 매핑하여 컨테이너를 {컨테이너별명}으로 띄우고, -d 플래그를 통해 콘솔에서 분리하여 백그라운드에서 돌아가게끔 실행한다는 의미

위 커맨드 이후 다음 커맨드로 app.js가 실행되고 있는 서버 애플리케이션에 접근

curl localhost:8080

다음 커맨드로 실행 중인 컨테이너 목록을 확인

docker ps

docker ps 커맨드는 컨테이너의 기본 정보만 표시하기 때문에 자세한 정보(JSON형식)를 확인하기 위해서는 docker inspect를 사용

5. 실행 중인 컨테이너 내부 탐색

실행 중인 컨테이너 내부에서 셸 실행

하나의 컨테이너 안에서는 여러 프로세스를 실행할 수 있기 때문에 컨테이너 내부를 보고 싶다면 추가 프로세스를 실행하거나 이미지 내에 실행가능한 셸 바이너리를 통해 셸을 실행

node.js는 bash 셸을 포함하고 있으므로 다음 명령어로 내부에서 명령을 실행할 수 있다.

docker exec -it {컨테이너별명} bash

위 명령어의 -it옵션은 i(STDIN표준입력 오픈 상태 유지)와 t(명령어프롬프트 표시) 두 옵션을 축약한 것

내부에서 컨테이너 탐색

it옵션을 통해 내부에서 셸을 실행하면 계정명@호스트명:/#으로 명령어를 입력할 수 있게 뜸 이때 ps aux를 입력하면 세 개의 프로세스를 볼 수 있고, 호스트 운영체제의 다른 프로세스는 볼 수 없음

호스트 운영체제에서 실행되는 프로세스 이해

ps aux | grep app.js를 입력하면 호스트 운영체제에서 실행 중인 컨테이너 프로세스인 app.js를 조회할 수 있음

격리된 컨테이너 파일시스템

ls /를 입력하면 컨테이너 내부에서 이미지에 있는 모든 파일과 컨테이너가 실행하는 동안 생성한 파일(로그 파일 등)을 포함해서 볼 수 있음

6. 컨테이너 중지와 삭제

docker stop {컨테이너별명}

컨테이너에 실행 중인 메인 프로세스를 중지시킬 수 있지만, docker ps -a로 보면 컨테이너 자체는 여전히 존재 컨테이너를 완전히 삭제하려면 docker rm 명령을 수행

docker rm {컨테이너별명}

7. 이미지 레지스트리에 푸쉬

빌드한 이미지를 다른 사용자나 다른 컴퓨터에서도 실행가능하게 만들려면 외부 이미지 저장소에 push해야 함 이번에는 docker hub(http://hub.docker.com)에 이미지를 push

추가 태그로 이미지 태그 지정
docker tag {이미지명} {도커허브ID/이미지명}

해당 명령은 태그를 변경하지 않음

같은 이미지에 추가적인 태그를 생성

docker images 명령으로 시스템에 저장된 이미지를 조회해보면 같은 이미지 ID를 가진 두개의 태그를 가진 이미지들이 조회됨

도커 허브에 이미지 푸쉬하기

도커 허브에 docker login으로 로그인을 하고 나면 다음과 같이 태그명으로 이미지를 push할 수 있게 됨

docker push {이미지태그명}
다른 머신에서 이미지 실행하기

이제 도커 허브에 있는 이미지를 모든 사람이 사용할 수 있게 됨 다음 명령어를 실행하여 도커를 실행하는 모든 머신에서 이미지를 실행할 수 있음

docker run -p 8080:8080 -d {이미지태그명}


정리

간단하다.

무엇보다 좋은 점은 도커가 실행된다면 호스트 머신이 무슨 환경인지 걱정할 필요가 없이 언제든 애플리케이션의 동일한 동작이 보장된다는 점이다.


댓글남기기