개발 이야기/쿠버네티스

쿠버네티스 헬로월드 - 6

석구석구 2021. 6. 15. 02:24

간단하게 애플리케이션을 이미지(패키징)로 만들고, 쿠버네티스 클러스터에서 실행하는 방법을 살펴보자.

 

도커를 빠르게 설치하고 시작하자.

 

https://www.docker.com/get-started

 

 

Get Started with Docker | Docker

Learn about the complete container solution provided by Docker. Find information for developers, IT operations, and business executives.

www.docker.com

도커 이미지 실행
docker run busybox echo "Hello world"
  1. 터미널을 열고 위 커맨드를 입력하자. 
  2. 먼저 로컬에서 busybox:latest 이미지를 찾을 것이고, 없을 테니 도커 허브에서 해당 이미지를 pull 한다.
  3. 다운로드가 완료되면 이미지로부터 컨테이너를 생성하고, 컨테이너 내부에서 명령어를 실행한다.
  4. echo 명령을 통해 텍스트를 출력한 후, 프로세스를 중단하고 컨테이너 역시 중지된다.
도커 이미지 만들기

이어서, 간단한 node 애플리케이션도 실행해보자.

먼저 app.js 라는 파일을 만들고 간단한 스크립트를 작성하자.

/** app.js */
const http = require('http');
const os = require('os');

console.log('http 서버를 8080 포트에서 시작합니다.')
http.createServer((rq,rs)=>{
    console.log(`요청 주소 ${rq.socket.remoteAddress}`)
    rs.writeHead(200)
    rs.end(`응답 주소 ${os.hostname()}`)
}).listen(8080)

같은 폴더에 Dockerfile 이라는 이름의 파일을 만들고 아래 내용을 작성하자.

# Dockerfile
FROM node:12
ADD app.js /app.js
ENTRYPOINT ["node", "app.js"]

간단하지만 작성 내용은 다음과 같다.

  1. node:12 이미지에서 시작한다.
  2. app.js 파일을 루트 위치에 같은 이름으로 복사한다.
  3. 이미지를 실행했을 때, app.js를 node로 실행하라는 명령어를 작성한다.

다시 터미널을 열고 아래 명령어를 입력해서 이미지를 빌드하자.

docker build -t suk9 .

위 명령으로 도커내부에서 이미지를 빌드하는 과정은 다음과 같다.

  1. 도커 클라이언트가 현재 디렉터리의 콘텐츠를 도커 데몬에 업로드한다.
  2. 도커 데몬에서 빌드 프로세스가 실행되고, node:12 이미지가 없기 때문에 이미지를 pull 한다.
  3. suk9라는 이름의 새로운 이미지를 빌드한다.
docker images

위 명령을 통해 로컬에 저장된 이미지 리스트를 조회할 수 있다. 우리가 방금 빌드한 이미지도 리스트에 나타날 거라 믿는다.

도커의 이미지는 다른 이미지와 공유 가능한 레이어 형태로 구성된다.

도커의 이미지는 단일 구성이 아니라, 여러 겹의 레이어 구조로 구성되어 있다. 도커의 서로 다른 이미지는 레이어를 공유할 수 있으며 때문에 효과적으로 이미지를 저장하고 전송할 수 있다. 위 예제에서 node:12를 기반으로 다른 수많은 이미지를 만들어 내더라도, 기본 이미지를 구성하는 레이어는 단 한 번만 저장될 것이다. 

 

도커 파일을 이용해 도커 이미지를 빌드하는 방법을 알아보았다. 물론 이 방법 외에도 이미지를 빌드하는 방법이 있다. 컨테이너를 실행하고 해당 컨테이너에서 여러 가지 작업을 한 후, 변경 내용을 commit 하는 방식이다. 하지만 Dockerfile을 이용한 빌드 방식이 재사용 가능하고, 더 명확하다.

 

이제 우리가 빌드한 이미지를 실행(컨테이너화) 해보자.

docker run --name suk9-container -p 8070:8080 -d suk9

1. suk9-container 라는 이름으로 실행한다.

2. 로컬 머신의 8070 포트와 컨테이너의 8080 포트를 맵핑한다.

3. 데몬모드, 즉 백그라운드에서 suk9 이미지를 실행한다.

curl localhost:8070

8070 포트로 요청을 해보면 
"응답 주소 76aac1a29fe1" 이와 비슷한 응답을 받게 된다. 컨테이너 내부에서 애플리케이션이 돌아가고 있으므로, 우리가 응답받은 호스트 이름은 로컬 머신의 이름과 다르다. 이 값은 바로 도커 컨테이너의 ID다.

docker ps

위 명령어를 통해 현재 실행 중인 컨테이너 목록을 조회할 수 있다.

docker inspect suk9-container 

위 명령어를 통해 특정 컨테이너의 상세 정보를 조회할 수 있다.

뿐만 아니라, 컨테이너에 셸을 통해 접근할 수도 있다.

docker exec -it suk9-container bash

위 명령어는 현재 실행 중인 suk9 컨테이너 내부의 bash를 실행한다. it 옵션은 표준 입력과 터미널을 할당하는 옵션이다. 해당 옵션이 없다면 정상적으로 터미널 이용을 할 수 없다.

이제 node.js가 돌아가고 있는 격리된 컨테이너 환경을 살펴볼 수 있다.

ps aux

격리된 환경이므로, 우리가 실행한 프로세스만 볼 수 있을 것이다.

이제 또다른 터미널을 열어 로컬 머신의 프로세스 목록을 조회해보자.

ps aux | grep app.js

컨테이너가 실행하고 있는 프로세스가 보일 것이다. 이는 컨테이너에서 실행하는 프로세스가 사실은 로컬 머신의 운영체제에서 실행 중이라는 것을 증명한다. PID는 다르다는 것도 확인할 수 있다. 컨테이너는 자체 PID 네임스페이스를 사용하고 완전히 분리된 프로세스 트리를 갖고 있다.

ls

우리가 추가한 app.js 파일과 컨테이너 내부의 독립된 파일 시스템을 볼 수 있다.

exit 명령을 통해 내부 터미널에서 빠져나와 이제 컨테이너를 중지해보자.

docker stop suk9-container
docker ps -a

컨테이너는 중지되었지만, 아직 컨테이너는 사라지지 않고 존재하고 있다.

docker rm suk9-container

이제 컨테이너는 완전히 삭제되었고, 다시 시작할 수 없다.