본문 바로가기

컴퓨터공학/기타

도커 쿠버네티스 강의 필기노트

목차
파트1
1.이미지와 컨테이너
2.데이터와 볼륨
3.컨테이너와 네트워킹 

파트2
1.멀티 컨테이너
2.도커 컴포즈
3.유틸리티 컨테이너
4.도커 컨테이너 배포

파트3
1.쿠버네티스 개념 
2.쿠버네티스 데이터와 볼륨
3.쿠버네티스 네트워킹
4.쿠버네티스 클러스터 


1.비디오를 보고
2.코드를 치고 
3.정확하지 않은 개념 반복 
4.에러 케이스를 찾아볼 것

-----------------------------------------------------------------------------

1-1 이미지와 컨테이너
*이미지와 컨테이너 
컨테이너는 실행 소프트웨어 단위
이미지는 컨테이너의 템플릿/블루프린트
이미지를 바탕으로 컨테이너를 만들어서 실행한다. 
컨테이너는 이미지 인스턴스라고 볼 수 있다. 
 
*미리 만들어진 이미지를 가져와서 컨테이너 만들기 
docker desktop 실행 후 
명령프롬프트에서 docker run node 입력
docker hub에서 node 이미지를 다운받아 설치한다. 
docker ps -a
실행중인 컨테이너 목록을 출력
docker run -it node 
-it 태그를 붙이면 호스트와 노드는 상호작용할 수 있다. 
Ctl + C 를 두 번 누르거나 .exit를 입력하면 다시 빠져나올 수 있다. 

*이미지를 만들어서 컨테이너 만들기 
visual studio code 기준
Docker 확장 프로그램 설치
Docker file 생성하고 내용을 작성한다. 
FROM node
(로컬이나 docker hub에 있는 node가 베이스 이미지 )
WORKDIR /app
(기본 경로 설정. 앞으로 이 경로 아래에서 작동한다)
COPY . /app 
(hostfile system / image container file system
Docker 파일이 있는 호스트 시스템 경로에서 컨테이너 경로 app 폴더를 만들고 복사 붙여넣기 )
RUN npm install

EXPOSE 80
(dependencies를 실행하기 위해서 npm이 필요하니 컨테이너가 만들어지면 npm install을 실행한다.)
CMD ["node", "server.js"] 
(CMD는 RUN과 다르게 만들어질 때 실행하지 않고 base image에 따라서 실행한다.) 
 
dockerfile이 있는 경로에 가서 
docker build . 
명령어 입력 
이미지 생성
docker run [이미지아이디]
docker stop [이미지이름]

근데 도커파일에 포트 정보를 작성했지만 작동하지는 않아서 실행할 때 플래그를 넣어야 한다. 
docker run -p 3000:80 [이미지아이디]
-p 호스트피씨 포트:컨테이너내부포트
즉 플래그 정보 없이 그냥 run 때리면 컨테이너 내부 80 포트가 호스트컴퓨터 포트하고 연결이 안 되어 있어서 접속할 수 없다. 
도커파일에 expose 포트번호는 선택 옵션이다. 
-p로 포트 번호를 쓰는게 필수이다. 


FROM node
WORKDIR /app
COPY package.json /app
RUN npm install 
COPY . /app
EXPOSE 80
CMD ["node", "server.js"]
이미지는 이미지 레이어 구조로 이전에 사용한 것을 캐시에 저장하여 사용한다.
이전 도커파일은 소스 코드가 변화하면 npm 설치를 다시 하게 되는데 
package.json을 바탕으로 npm 설치하는 부분과 소스코드를 만드는 부분을 나누면
다음에 이미지만들 때 npm 설치 부분을 넘어갈 수 있어서 시간 절약할 수 있다. 

요약
코드와 실행환경을 이미지에 넣는다.
도커파일은 이미지에 어떻게 넣을 지 알려주는 설명서이다. 
어떤 걸 기반으로 이미지를 만들 지 
어떤 코드와 dependencies를 복사해서 넣을 지
npm 설치할 지
포트 설정을 어떻게 할 지 
이미지는 컨테이너를 위한 설계서이다. 
이미지를 바탕으로 여러 컨테이너를 만들 수 있다.

docker ps 
docker ps -a
docker ps --help
docker run 

이전에 실행한 도커를 재실행
docker start [이미지이름] 
이러면 백그라운드 실행
docker run -p 3000:80 [이미지아이디]
이건 포어그라운드 실행. 이런 걸 attached 했다고 한다. 
dettach와 attach의 차이점은 attach하면 console.log 같은 output을 볼 수 있다.
백그라운드 실행하기 위해선 dettach 옵션을 추가하면 된다. 
docker run -p 8000:80 -d [이미지아이디]
만약 dettach한 컨테이너에 attach하고 싶으면 
docker attach [컨테이너이름]

로그 확인 명령어 사용법
docker logs [컨테이너이름] 
docker logs --help
로그에서도 attach하고 싶으면 
docker logs -f [컨테이너이름]

입력
docker run -it [이미지아이디]
docker start -a -i [이미지이름]

컨테이너는 멈추고 삭제하자.
docker stop [컨테이너이름]
docker rm [컨테이너이름]

컨테이너 먼저 삭제하고 나서 이미지 삭제
이미지 목록
docker images
이미지 삭제법
docker rmi [이미지아이디]
사용하지 않는 이미지 삭제
docker image prune -a
컨테이너 멈출 때 이미지 자동 삭제법
docker run할 때 --rm 태그 붙인다..


이미지는 코드와 실행환경이 있기 때문에 용량이 크다. 
반면 컨테이너는 크지 않다. 
컨테이너는 이미지에서 커맨드 레이어 하나가 있다.
컨테이너가 여러 개가 있으면 이미지 코드를 공유한다.
그래서 코드 변경할 수 없이 읽기만 가능.

이미지 내용물 보는 법 
docker image inspect 
 
파일 복사해서 컨테이너에 넣는 법
docker cp dummy/. vibrant_carver:/test
docker cp vibrant_carver:/test dummy

이름표 붙이기
docker run -p 3000:80 -d --rm --name goalapp 7cd09d0d24d6
이름과 태그로 버전 설정 가능 node:12
도커 허브에서 어떤 태그를 쓸 수 있는지 씌어져 있음.
이미지 생성 시 태그를 넣을 수 있다.
그룹 : 그룹 내 이름
docker build . -t goals:latest
이름표 있는 이미지를 컨테이너 생성 
docker run -p 3000:80 -d --rm --name goalapp goals



도커 허브나 Private Registry를 통해서 도커 공유법
docker login
docker push seol2/node-app:tagname
docker pull seol2/node-app:tagname

이미지를 만들 때 레퍼지터리의 이름과 맞춰야 한다. 
1. 이미지를 다시 만들거나
2. 이름바꾸기 
docker tag [이전이름:태그] [도커허브아이디/레퍼지터리이름]

docker run --help

-----------------------------------------------------------------------------

1-2 데이터와 볼륨
이미지는 읽기전용
컨테이너는 읽기 쓰기 가능 

복습
 docker run -p 3000:80 -d --name feedback-app --rm feedback-node
detach모드, 이름지정, 포트지정, 정지시이미지자동삭제
명령어 순서 지킬 것

컨테이너를 삭제하고 다시 만들 경우 데이터도 같이 없어진다. 
Volumes
볼륨은 컨테이너나 이미지에 데이터를 저장하는 방식이 아니라 호스트머신인 내 컴퓨터에 데이터를 저장하는 기능이다. 
그래서 컨테이너가 없어져도 자료 보존이 가능하다 .

dockerfile에 VOLUME [ "경로" ] 추가

docker volume ls 
볼륨 리스트 보기

외부 저장소 두 가지 타입
1. 볼륨(managed by docker)
- Anonymous Volumes : 도커파일에 VOLUME [ "경로" ]으로 두고 이미지 생성 후 컨테이너를 만들거나, docker run에 -v 옵션을 주는데 이름 지정이 없으면 볼륨은 아무 이름으로 만들어 진다. 
그리고 컨테이너가 삭제되면 볼륨도 없어진다. 단 --rm 옵션을 붙은 컨테이너만 해당. 
이 옵션이 없을 경우 Anonymous는 삭제 안됨. 
심지어 docker rm으로 container를 삭제해도 삭제 안됨.
여기서 다른 이름으로 새로운 Anonymous Volume이 생길 수 있다.
따라서 안 쓰는 Volume을 삭제하려면
docker volume rm [볼륨이름] 또는
docker volume prune 
으로 삭제하자. 
컨테이너 끼리 공유 불가능
재사용 불가능
anonymous는 컨테이너에 이미 존재하는 특정 데이터가 다른 모듈에 의해서 덮어 씌어지는 것을 막을 때 사용하면 유용하다. 

- Named Volumes : 데이터 보존에 좋다. 근데 어디에 있는지 모른다. 수정할 수 없다. 
docker run -d -p 3000:80 --rm --name feedback-app -v feedback:/app/feedback  feedback-node:volumes 
이미지를 만들고 docker run 옵션으로  -v를 줄 때 앞에 이름을 붙이면 볼륨을 named로 설정할 수 있다. 
이름을 지정하면 컨테이너를 삭제해도 볼륨은 없어지지 않고 유지. 
컨테이너 간 공유 가능 

Anonymous는 컨테이너에 붙어있고 Named는 컨테이너에 붙어있지 않다는 걸 알 수 있다. 
컨테이너를 삭제하고 다시 생성해도 볼륨 데이터는 여전히 보존.

공통점 :
docker가 호스트 머신에 경로를 만든다.  우리는 파일의 정확한 위치를 알 수 없다. 
docker volume 명령어로 관리한다. 


2. Bind Mounts(managed by you)
-v 옵션에서 이름 대신 호스트 머신 경로를 붙이면 Bind Mont가 된다. 
호스트 파일 시스템에 위치. 어떤 컨테이너에 붙지 않는다. 
컨테이너를 없애도 살아남는다. 데이터를 없애고 싶다면 호스트 머신에서 삭제해야 한다. 
컨테이너 간 공유 가능, 재사용 가능 

볼륨 방식은 소스코드가 바뀔 때마다 이미지를 리빌딩해야 한다. 
Bind Mounts는 경로를 호스트머신에 지정할 수 있다. 
소스코드 수정 가능하고 데이터 영속성이 있다. 

경로를 직접 쓰는 것 대신 아래를 쓸 수 있다. 
macOS / Linux: -v $(pwd):/app
Windows: -v "%cd%":/app

docker run -d -p 3000:80 --rm --name feedback-app -v feedback:/app/feedback -v C:\Users\dev\Docker\data-volumes-01-starting-setup:/app -v /app/node_modules feedback-node:volumes 
로컬 경로를 바탕으로 덮어씌우는데 로컬에는 node_modules가 없어서 컨테이너에서도 없어진다. 
로컬에 볼륨을 만들어서 node modules이 없어지는걸 방지한다. 

볼륨은 컨테이너의 내용이 호스트 어딘가에 저장되고
바인드마운트는 호스트 특정 경로에서 컨테이너로 접근 가능하다. 

로그보기
docker logs feedback-app

html은 수정하면 바로 적용되는데 js은 그렇지 않다. 
파일은 바뀌더라도 웹서버를 재시작해야 적용할 수 있다. 
따라서 노드는 재시작하지 않아도 되는 라이브러리를 추가해야 한다. 
아니면 컨테이너를 멈추고 시작하면 된다. 

read only volume은 뒤에 :vo를 붙인다. 


docker volume create [이름]
볼륨 파일을 먼저 만들고 나중에 -v 옵션에서 지정할 수 있다.

.dockerignore
이미지 만들 때 파일이나 폴더를 제외할 수 있다. 
왜냐하면 프로젝트폴더에 있는 node-modules 경우 구버전이거나 필요한 라이브러리를 안 갖고 있을 수 있기 때문에 제외하는게 좋다. 


ARGuments & ENVironment Variables 
ARG
도커파일 안에 이용가능, CMD나 어플리케이션 코드에서 접근 불가능 
도커파일에서 ARG DEFAULT_PORT = 80 작성 후 ENV PORT $DEFAULT_PORT 이런 식으로 사용 
아니면 이미지 빌드할 때 --build-arg DEFAULT_PORT=8000 옵션 추가 



ENV
도커파일과 어플리케이션 코드에서 이용가능 

ENV PORT 80 이라고 도커파일에 작성한다. 
js 파일에서는 process.env.PORT 로 사용한다. 
같은 도커파일에서 사용하려면 $PORT 방식으로 사용한다. 

docker run 커맨드에서 변수를 두는 방법은 --env PORT =8000 이거나 -e PORT=8000 이런 식으로 작성하면 된다. 

.evn 파일을 만들어서 변수를 지정할 수 있다. 
docker run 에서 --env-file ./.env 옵션으로 준다. 

docker run -d -p 3000:80 --evn PORT=8000 --rm --name feedback-app -v feedback:/app/feedback -v /app/node_modules  -v C:\Users\dev\Docker\data-volumes-01-starting-setup:/app -v /app/temp  feedback-node:volumes 



-----------------------------------------------------------------------------
1-3 컨테이너와 네트워킹
attach 모드를 하면 에러뜨는 로그를 볼 수 있다. 

1. 외부 request
2. 호스트머신에 있는 데이터베이스 접속
'mongodb://localhost:27017/swfavorites', 여기에서 다음으로 바꿔야 한다. 
'mongodb://host.docker.internal:27017/swfavorites',
도커가 알아먹도록 수정. host.docker.internal은 local host ip 주소로 변환한다.

3. 컨테이너 데이터베이스 접속 
몽고디비 컨테이너 생성
docker run mongo 이걸로 하면 로컬이 아니라 도커 허브에서 갖고 온다. 
docker run -d --name mongodb mongo
docker container inspect mongodb
NetworkSettings에서 IPAddress가 컨테이너의 아이피이다. 이걸 주소에 대신 입력한다. 

컨테이너 네트워크이용하는 방법  docker internal network 
볼륨과는 다르게 네트워크는 미리 직접 만들어 줘야 한다. 
docker network create [네트워크이름]
네트워크 리스트 보기 
docker network ls 
컨테이너 생성 시 네트워크 옵션을 붙인다--network 
docker run -d --name mongodb --network favorites-net  mongo
같은 네트워크 몽고디비 데이터베이스 컨테이너 이름으로 대신 넣을 수 있다. 
'mongodb://mongodb:27017/swfavorites',

docker run -d -p 3000:3000 --rm --network favorites-net --name favorites  favorites-node 

mongodb 컨테이너를 만들 때 p옵션을 주지 않았다. 
왜냐하면 p 옵션은 오직 localhost와 통신할 때, 또는 컨테이너 네트워크 밖에 있는 컨테이너와 통신할 때 필요하다. 


-----------------------------------------------------------------------------

2-1 멀티 컨테이너
docker build -t goals-node .
docker run --name mongodb --rm -d -p 27017:27017  mongo
docker run --name goals-backend --rm -d -p 80:80  goals-node 
docker build -t goals-react .
docker run --name goals-frontend --rm -d -p 3000:3000 -it goals-react 


docker network create goals-net
docker run --name mongodb --rm -d --network goals-net  mongo
docker build -t goals-node .
 docker run --name goals-backend --rm -d -p 80:80 --network goals-net goals-node
docker build -t goals-react . 
docker run --name goals-frontend --rm --network goals-net -p 3000:3000 -it goals-react 
백엔드 서버를 같은 네트워크에 둘 때 몽고디비 주소는 컨테이너 이름으로 대치하자. 그래서 이미지 재생성한 것임..


데이터베이스 볼륨 구성
docker run --name mongodb -v data:/data/db --rm -d --network goals-net mongo

환경변수로 데이터베이스 아이디 비밀번호 설정 
docker run --name mongodb -v data:/data/db  --rm -d --network goals-net -e MONGO_INITDB_ROOT_USERNAME=max -e MONGO_INITDB_ROOT_PASSWORD=secret mongo
아이디 비밀번호를 새로 만들고 볼륨을 설정할 때 이전 볼륨과 이름이 같지 않은지 본다. 이름이 같으면 이전 볼륨은 삭제하고 다시 만든다. 

백엔드에서 주소에 아이디 비밀번호를 넣어야 몽고디비 이용 가능 
mongodb://max:secret@mongodb:27017/course-goals?authSource=admin


docker run -d --rm --name goals-backend -p 80:80 --network goals-net -v C:\Users\dev\Docker\multi-01-starting-setup\backend:/app -v logs:/app/logs -v /app/node_modules goals-node

도커파일에 
ENV MONGODB_USERNAME=root
ENV MONGODB_PASSWORD=secret 집어넣고 노드에서는 
 `mongodb://${process.env.MONGODB_USERNAME}:${process.env.MONGODB_PASSWORD}@mongodb:27017/course-goals?authSource=admin`
이런 식으로다가 하고 
docker run 명령어에는 
docker run -d --rm --name goals-backend -p 80:80 --network goals-net -v C:\Users\dev\Docker\multi-01-starting-setup\backend:/app -v logs:/app/logs -v /app/node_modules -e MONGODB_USERNAME=max goals-node
-e MONGODB_USERNAME=max옵션으로 가능
몽고디비에는 아이디 max 비밀번호 secret으로 설정했기에 정상 작동된다. 


프론트엔드
docker run -v C:\Users\dev\Docker\multi-01-starting-setup\frontend\src:/app/src --name goals-frontend --rm -p 3000:3000 -it goals-react
도커 파일에서 COPY . . 
컨테이너에 이미 npm을 설치해놨는데 프로젝트파일을 컨테이너로 모두 카피하면 프로젝트폴더에 있는 오래된 node_modules이 컨테이너로 들어갈 수 있다. 따라서 .dockerignore로 node_modules을 등록하여 제외해야 한다. 
이러면 node_modules 폴더가 copy에서 제외된다. 

-----------------------------------------------------------------------------

2-2 도커 컴포즈

도커 컴포즈는 여러 개 docker build 와 docker run 커맨드를 하나의 configuration 파일에 묶어 놓은 것이다.
여러 서비스와 컨테이너를 한 번에 다룰 수 있는 기능이다. 
도커 컴포즈는 기본적으로 네트워크에 같이 들어간다. 
도커 컴포즈 파일은 .yaml 확장자를 갖는다.
도커 컴포즈는 bind mouts를 사용할 때 편리하게 절대경로를 쓸 수 있다. 
도커 컴포즈는 도커파일을 대체하지 않는다. 같이 작동한다. 


    environment:
      MONGO_INITDB_ROOT_USERNAME: max
      MONGO_INITDB_ROOT_PASSWORD: secret
몽고디비 관련 컴포즈 작성중 환경변수를 이렇게 할 수 있지만 파일을 따로 만들어서 참조할 수 있다. 
env 폴더를 만들고 거기에 mongo.env 라고 파일을 만든 다음 
MONGO_INITDB_ROOT_USERNAME=max
MONGO_INITDB_ROOT_PASSWORD=secret
내용을 넣는다. 
version: "3.8"
services:
  mongodb:
    image: 'mongo'
    volumes:
      - data:/data/db
    env_file:
      - ./env/mongo.env
이렇게 하면 됨

dettach 모드로 실행법
docker-compose up -d
컨테이너 모두 삭제 
docker-compose down
볼륨까지 삭제
docker-compose down -v


backend:
    build: 
      context: ./backend
      dockerfile: dockerfile
      args:
        - some-arg: 1
build를 좀 더 자세하게 하는 법 



--build 옵션은 이미지를 다시 빌드하는 옵션. 그냥 이미지만 재빌드하는 것.
docker-compose는 그냥 이미지가 있는지 체크하고 이미지가 있으면 그냥 사용한다. 



version: "3.8"
services:
  mongodb:
    image: 'mongo'
    volumes:
      - data:/data/db
    env_file:
      - ./env/mongo.env
    container_name: mongodb
  backend:
    build: ./backend
    ports:
      - '80:80'
    volumes:
      - logs:/app/logs
      - ./backend:/app
      - /app/node_modules
    env_file:
      - ./env/backend.env
    depends_on:
      - mongodb
  fronend:
    build: ./frontend
    ports:
      - '3000:3000'
    volumes:
      - ./frontend/src:/app/src
    stdin_open: true
    tty: true
    depends_on:
      - backend

volumes:
  data:
  logs:

-----------------------------------------------------------------------------

2-3 유틸리티 컨테이너 
지금까지 배운 건 애플리케이션 컨테이너로 
앱 환경과 앱이 같이 있는 컨테이너
유틸리티 컨테이너는 공식 용어는 아니지만 환경만 세팅되어 있는 컨테이너다. 
애플리케이션 컨테이너는 docker run 앱이름 
유틸리티 컨테이너는 docker run 앱이름 init 으로 시작한다. 


docker run -it -d node 
docker exec -it 컨테이너이름 npm init 
docker run -it node npm init 



도커파일 내용
FROM node:14-alpine
WORKDIR /app

docker build -t node-util .
docker run -it -v C:\Users\dev\Docker\utilcontainer:/app node-util npm init 
docker run -it -v C:\Users\dev\Docker\utilcontainer:/app node-util npm install



도커파일 내용 
FROM node:14-alpine
WORKDIR /app
ENTRYPOINT [ "npm" ]
 
docker build -t mynpm .
docker run -it -v C:\Users\dev\Docker\utilcontainer:/app mynpm init
docker run -it -v C:\Users\dev\Docker\utilcontainer:/app mynpm install
docker run -it -v C:\Users\dev\Docker\utilcontainer:/app mynpm install express --save 
express dependency를 추가한다. 



도커 컴포즈 사용하기 
version: "3.8"
services:
  npm:
    build: ./
    stdin_open: true
    tty: true
    volumes:
      - ./:/app
      
도커 파일에는 엔드리포인트만 설정했지 실행 동작을 설정 안 했으므로 추가 정의한다.
docker-compose run  뒤에는
services에 있는 실행시킬 서비스 이름 npm과 init을 입력
docker-compose run --rm npm init

-----------------------------------------------------------------------------

dockerfiles 폴더
env 폴더
nginx 폴더 
src 폴더 
docker-compose.yaml파일


docker-compose.yaml 파일 내용 

version: "3.8"

services:
  server:
    image: 'nginx:stable-alpine'
    ports:
      - '8000:80'
    volumes:
      - ./src:/var/www/html
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - php
      - mysql

  php:
    build:
      context: ./dockerfiles
      dockerfile: php.dockerfile
    volumes:
      - ./src:/var/www/html:delegated

  mysql:
    image: mysql:5.7
    env_file: 
      - ./env/mysql.env
    
  composer:
    build: 
      context: ./dockerfiles
      dockerfile: composer.dockerfile
    volumes:
      - ./src:/var/www/html

  artisan:
    build:
      context: ./dockerfiles
      dockerfile: php.dockerfile
    volumes:
      - ./src:/var/www/html
    entrypoint: ["php", "/var/www/html/artisan"]

  npm:
    image: node:14
    working_dir: /var/www/html
    entrypoint: ["npm"]
    volumes:
      - ./src:/var/www/html


php의 .env 파일에서 수정해야 할 것 
바로 데이터베이스 정보 
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret




laravel 설치 명령어 
 docker-compose run --rm composer create-project --prefer-dist laravel/laravel .

 docker-compose up -d server php mysql 
docker-compose up -d --build server php mysql 
docker-compose run --rm  artisan migrate -> 따로 서비스를 실행하고 싶을 경우 



-----------------------------------------------------------------------------

2-4.도커 컨테이너 배포

-----------------------------------------------------------------------------
톰캣 도커 이미지 만들기 


RUN rm -rf /var/lib/apt/lists/*
RUN apt-get update
apt-get install net-tools
: net-tools를 설치해주어야 ifconfig 명령어를 사용 가능하다.
apt-get install vim
: vi 편집기 사용을 위해 미리 vim도 설치해주자.
apt-get install iputils-ping
: ping 테스트가 필요한 경우 iputils-ping 패키지를 설치한다.
apt-get install wget
: wget 명령어 이용하여 다운로드 받아오기 위해 wget 패키지를 설치한다.



docker exec -it tomcat8 /bin/bash
echo $JAVA_HOME

 

 

 


 

이미지와 컨테이너를 다루는 것도 아직 능숙하지 않아서 AWS 컨테이너 배포와 쿠버네티스 내용은 듣지 않았다..

지금 딱 진도가 절반정도 들었다.  좀 더 내공이 쌓이면 쿠버네티스를 배울 생각이다. 

 

회사는 구버전 톰캣, 오라클, JDK를 사용하는데 이걸 컨테이너에서 동작하려니 애로사항이 많다. 

톰캣 구동이야 되긴 되지만 war파일을 동작시키면 에러가 많다. 

차세대 버전에서 동작하게 환경을 구성하든지 아니면 소스코드를 차세대화 하든지 차근차근 배워가면서 풀어야 겠다....