Docker 기본활용 실습

2019-09-16

.

Data_Engineering_TIL_(20190727)

study program : https://www.fastcampus.co.kr/dev_camp_devb

[학습목표]

  • Container orchestration 기본개념 이해

  • Docker 명령어 및 Dockerfile 작성방법 이해

[학습기록]

1. AWS ECS(Elastic Container Service)

  • 클라우드 환경에서 버츄얼머신(EC2)을 활용하여 컨테이너 클러스터링을 구성할 수 있게 해주는 서비스

  • AWS에서 제공하는 컨테이너 오케스트레이션 서비스

2. Application Load Balancer

  • 로드벨런싱 뿐만 아니라 대상그룹의 컨테이너가 필요에 따라 탄력적으로 숫자가 변경되었을때 자동으로 그룹핑하는 기능

  • 버츄얼 머신을 컨테이너가 늘어남에 따라서 오토스케일링

3. Network Load Balancer

포트단위로해서 들어오는 트래픽을 고효율로 부하분산 처리

4. Potainer

  • 컨테이너 자체를 추가하거나 변경하는 행위에 대해 통합적으로 관리해주는 툴

  • 도커스웜에서 쓰는 매니지먼트 솔루션

5. Container orchestration 개요

예를 들어서 100개의 깡통을 우리가 운영을 하고 있고 87번 깡통에 올라가져 있는 web container의 상태를 확인하고 싶을때 그러면 우리는 87번 깡통에 SSH로 일일히 접속해서 docker ps -a 명령어를 날려야 하는가에 대한 고민이 생긴다. 이러면 너무 불편하기 때문에 컨테이너 오케스트레이션을 하는 것이다.

클러스터라는 개념은 여러대의 서버를 관리자가 볼때는 한대처럼 관리할 수 있어야 한다. 이 클러스터라는 개념은 컨테이너 오케스트레이션 툴이 지원해주는 가장 기본적인 개념이라고 할 수 있다.

우리는 클러스터를 관리하고 있는 마스터 노드라는 것이 있는데 이 마스터 노드에 웹서버들에 대한 상태를 확인하는 명령어를 날려서 확인할 수 있다. 이 마스터 노드는 그 클러스터에 속해있는 서버들을 관리해주는 노드다.

예를 들어서 100개의 깡통을 운영한다고 하면 한 10개 정도는 마스터 노드로 활용할 것이다. 멀티마스터라는 개념이다. 왜냐하면 마스터가 하나만 있는 클러스터는 만약에 하나밖에 없는 이 마스터가 죽어버리면 전체 클러스터에 문제가 발생할 것이다. 그러나 이 마스터 노드가 멀티로 존재하면 그런 문제는 없을 것이다.

통상 컨테이너를 운영할때 컨테이너를 두종류로 나눈다. 하나는 매니지먼트 컨테이너, 다른 하나는 서비스 컨테이너이다. 매니지먼트 컨테이너는 운영하고 있는 컨테이너들을 관리하기 위한 서비스들이 탑재되어 있는 컨테이너를 말한다. 반면에 서비스 컨테이너는 말그대로 웹서비스나 API같은 컨테이너를 말한다. 이 매니지먼트 컨테이너 역시 멀티 개념이 적용되어 있다.

** 이런 멀티개념을 통상 고가용성(High Available)이라고 부른다. 시스템 관리자는 항상 고가용성을 고려해야한다. “만약에 이게 죽을때 어떻게 대비할 것인가”에 대해 항상 고민해줘야 한다.

6. Alpine Linux

  • 가볍고 간단하고 보안성을 목적으로 개발한 리눅스 배포판

  • 도커에서 자주 활용되는 베이스 이미지

  • 용량을 줄이기 위해 시스템의 기본 C runtime을 glibc 대신 musl libc 를 사용하며 다양한 쉘 명령어는 GNU util 대신 busybox 를 탑재

  • Embbeded나 네트웍 서버등 초경량이 요구되는 특정용도에 적합

7. 도커 클러스터 운영 시 헬스체크의 필요성

컨테이너가 정상적으로 실행되고 있는데 컨테이너 안에서 돌고있는 메인 프로세스가 죽어있는 경우가 있다. 그런 경우에는 관리자도 겉으로 보기에는 어떤상태인지 파악하기 어렵다. 그래서 컨테이너 안에서 돌고있는 메인 프로세스의 상태를 확인하기 위해서 도커데몬에게 컨테이너의 헬스체크 요청을 달아주는 것이 일반적이다.

컨테이너 프로세스에 대해 모니터링 하고 있고 무언가 알람을 받고 싶다 하면 우리는 exist와 unhealthy에 대해만 걸어두면 된다.

8. Docker hub

  • GitHub, NPM과 같이 Docker image를 저장, 수정, 공유 등을 할 수 있는 Docker image repository

  • 미리 빌드된 여러 이미지를 사용할 수 있음(CentOS, ubuntu, ELK, NginX, NodeJS, etc…)

9. AWS ECR(Elastic Container Registry)

Dockerhub와 마찬가지로 개발자가 로컬에서 개발한 컨테이너 이미지를 공유해서 활용할 수 있도록 AWS에서 지원하는 서버리스 컨테이너 레지스트리 서비스이다. 이 서비스를 이용해서 프라이빗 레지스트리도 만들 수 있다.

IAM에서 권한관리가 가능하고 권한이 있는 서버만 해당 컨테이너 레지스트리에 접속해서 다운받거나 푸시를 날린다거나 할 수 있다.

** 참고로 깃허브에도 컨테이너 프라이빗 레지스트리가 있다.

10. Docker demon 기본명령어

  • docker ps -a

1) 실행되고 있는 docker container process의 리스트 확인

2) 해당 도커 데몬에서 관리하고 있는 프로세스 리스트 확인

3) 이 리스트 내의 특정 컨테이너가 어떤 이미지를 기반으로 실행되고 있는지도 확인 가능

  • docker pull centos:latest

1) pull : 외부 레포지토리에서 이미지 다운로드, 따로 명시된 레포지토리가 없다면 dockerhub(https://hub.docker.com) 에서 다운로드

2) centos : 다운로드 할 이미지 이름

3) latest : 다운로드 할 이미지의 버전, latest로 명시하면 가장 최근에 업데이트 된 이미지를 가져옴

4

  • docker run -d -p 8000:80 --name web1 web:latest

1) run : docker image를 기반으로 컨테이너 생성/실행

2) -d : Detached mode: Run container in the background, print new container id

3) -p : 포트 매핑에 대한 옵션(HOST에 8000포트로 들어온 요청을 컨테이너 내 80포트와 연결), 포트포워딩 개념이라고 생각하면 된다.

4) –name : 컨테이너 이름 설정

5) web:latest : 해당 이미지를 기반으로 컨테이너 실행

3

  • docker stop web1

1) 실행되고 있는 docker container 프로세스 종료

2) web1 : docker run 시 name 옵션으로 지정한 컨테이너 이름으로 종료 가능, 혹은 container id 입력으로도 가능

  • docker rm web1 & docker rmi web:0.1

1) rm / rmi : 컨테이너 / 이미지 삭제시 사용

2) 컨테이너/이미지 이름 혹은 컨테이너/이미지 ID로 삭제

3) 컨테이너 삭제시 실행 중이면 삭제 불가하기 때문에 먼저 항상 stop 명령어로 종료 후 삭제해야 한다.

** 도커에서 f 옵션은 강제 옵션인데 가능하면 이 명령어를 사용하지 말아야 한다.

[실습상세]

ㅇ 실습개요 : web 서비스 구현을 위한 도커 기본기능 사용 및 dockerfile 생성 실습

step 1) 특정 깃서버에 미리 구현된 웹서버 컨테이너를 다운로드 받는다.

임의의 적당한 위치에서 git clone -b container https://github.com/owen1025/Fastcampus-web-deploy.git 명령어를 실행해준다.

여기서 b 옵션은 특정 브랜치만 다운로드 받겠다는 것이고, container는 도커파일로 다운로드하겠다는 옵션을 준 것이다.

1

step 2) 다운로드 받은 폴더로 이동해서 docker build -t web:0.2 . 명령어를 실행하여 도커 컨테이너를 빌드(도커이미지를 생성)한다.

** 참고로 아래 그림과 같이 다운로드 받은 폴더로 이동해서 root 권한을 먼저 가져오고 실습을 진행하는 것이 편하다.

2

step 3) 방금 생성한 도커이미지를 기반으로 컨테이너 생성 및 실행해준다.

docker run -d -p 8000:80 --name web1 web:0.2 명령어 실행

우리가 컨테이너에서 사용하고자 하는 포트가 호스트에서 쓰고 있는 프로세스로 인해 이미 점유되고 있으면 당연히 작동이 안될것이라는 것을 인지하고 다른포트로 포워딩해줘야 한다. 그리고 이렇게 호스트 포트와 컨테이너에서 사용하는 포트번호가 겹치는 것과 무관하게 컨테이너에서 원하는 포트번호로 사용가능하게 해주는 것이 컨테이너 오케스트레이션 툴이다.

3

** 컨테이너 안에 돌고 있는 모든 프로세스는 통상 1개, 많아야 2개가 될텐데 foreground 형태로 돌아야 한다. 만약에 백그라운드로 컨테이너를 돌려주면 도커를 관리하는 주체가 사용자가 해당 도커 프로세스가 잘 돌고 있는지 아닌지 파악을 못한다고 한다.

따라서 컨테이너 내에선 Foreground로 실행해야 한다.

정확히는 컨테이너 내에서 실행할 프로세스들은 foreground로 해당 컨테이너는 ‘-d’ 옵션을 통해 background로 실행

컨테이너를 Background로 실행하면 docker daemon에 등록되며 컨테이너 내에서 background list에 등록된 프로세스가 있다면 충돌이 발생되어 컨테이너 내에선 foreground로 실행하며 프로세스 관리는 docker host에게 전담

step 4) docker pull 명령어를 이용하여 centos 이미지 가져오기

4

step 5) 가져온 centos 이미지를 기반으로 컨테이너 생성 및 실행

아래 그림과 같이 docker run -it --name cent centos:latest /bin/bash 명령어를 실행하면 부여된 옵션에 따라 centos가 구동되고 내부에 Bash shell이 실행된다.

1) -it : -i, -t 옵션으로 실행

2) -i(interactive), -t(Pseudo-tty) : Bash shell에 입력 및 출력 가능

3) /bin/bash : centos 이미지 내에 /bin/bash 실행

5

step 6) CentOS 컨테이너 안 bash shell을 통해 아래의 명령어들을 순차적으로 실행

1) yum install -y epel-release : yum 명령으로 설치가 안되는 툴들을 설치할 수 있는 레포지토리 설치

2) yum install -y nginx

3) nginx

4) yum install -y nmap : 포트사용 현황파악을 위한 nmap 툴 설치

5) nmap localhost grep http : 현재 연려 있는 포트 확인

6) history : 실행한 명령어 내역 확인

6

7

8

9

10

11

step 7) web 컨테이너 Dockerfile 작성해보기

앞서 Cent OS에 작업한 명령어들을 기반으로 작성

1) 해당 컨테이너에서 어떤 OS를 기반으로 실행될 것인지

2) 필요한 소프트웨어를 해당 OS에 맞는 package manager 등을 통해 다운로드

3) 소스 코드, 설정 파일 다운로드, 적용

4) 컨테이너 내에서 소프트웨어 구동 및 Port listen

** Dockerfile 내용

FROM centos:latest

컨테이너 내에서 기반으로 할 OS(정확히는 docker image)

1) FROM {image_name:tag}

2) tag에 latest로 명시하면 가장 최근에 업데이트된 이미지 다운로드

RUN yum install -y epel-release

컨테이너 내에서 명령어 실행

1) RUN {EXEC commend}

2) RUN : 뒤에 오는 명령어 실행, 기반이 되는 컨테이너 OS의 체계에 맞춰 실행됨

RUN yum install -y nginx

컨테이너 외부에 있는 파일을 내부로 복사

1) COPY {external path / internal path} : 디렉토리 / 파일 복사

2) ./ : Dockerfile과 같은 경로에 있는 모든 파일

3) 소스 코드, 설정 파일 등

COPY ./ /usr/share/nginx/html/Fastcampus-webdeploy

= RUN yum install -y git

WORKDIR /usr/share/nginx/html

git clone {git-repository-url.git}

  • WORKDIR /usr/share/nginx/html

1) RUN으로 명령어 실행시 기본 Path는 ‘/’인 root directory에서 실행됨

2) NginX root directory에 소스 코드를 배포하기 위해 /usr/share/nginx/html 경로로 작업경로 설정

EXPOSE 80

EXPOSE

1) HOST와 연결될 포트 번호

2) Nginx는 80포트로 통신하기에 외부(host)와 연결하기 위해 80포트 설정

3) HOST : Docker가 구동되고 있는 환경, 물리머신, VM, 컨테이너 안이 될 수도 있음

CMD ["nginx", "-g", "daemon off;"]

CMD

1) 컨테이너가 start(run) / restart 될 때 명령어 혹은 스크립트를 실행

2) Dockerfile내에서 한 번만 사용 가능 , RUN ~~ 과의 차이점

CMD [“nginx”, “-g”, “daemon off;”]

1) CMD [“실행 파일”, “매개 변수1”, “매개 변수 2”]

2) Nginx를 “daemon off” 매개 변수를 통해 foreground로 실행

0

step 8) CentOS 컨테이너 안 bash shell에서 아래의 명령어들을 순차적으로 실행 (WAS(NodeJS) 컨테이너 구현테스트)

curl --silent --location https://rpm.nodesource.com/setup_8.x | bash -

yum install -y nodejs

Node.js/NPM 코드 다운로드 및 yum을 통해 설치

yum install -y git

git clone -b v1 https://github.com/owen1025/Fastcampus-api-deploy.git

Git 설치 및 git 레포지토리에서 api 프로젝트 코드 다운로드

cd Fastcampus-api-deploy/

npm install -g pm2

npm install

pm2 start bin/www --name WAS

pm2(node.js process manager) 설치

npm을 통해 api 프로젝트에서 필요한 module 다운로드

pm2로 nodejs background로 실행

step 9) step 8)에서 테스트한 WAS를 dockerfile로 구현하고 띄워보기

step 9-1) 로컬환경으로 돌아가서 적당한 폴더에서 git clone -b container https://github.com/owen1025/Fastcampus-api-deploy.git 명령어 실행

13

step 9-2) 해당 프로젝트에서 Dockerfile 열어서 아래 그림과 같이 수정

14

step 9-3) docker build -t api:0.1 . 명령어로 이미지 빌드 후 docker run -d -p 3000:8080 --name api1 api:0.1 실행

15

step 9-4) curl 명령어로 api 정상작동여부 확인

16