✔️ 실습에 앞서
실습 목표
- 도커 컨테이너의 빌드, 실행 및 디버깅 방법
- 도커 이미지를 Google 컨테이너 레지스트리에 푸시하는 방법
- 도커 이미지를 Google 컨테이너 레지스트리에서 가져오는 방법
✔️ Hello World
docker run hello-world
이 간단한 컨테이너는 Hello from Docker! 를 출력한다.
명령어는 간단하지만 실행한 스텝의 수가 출력되어 있다.
도커 데몬은 hello-world 이미지를 검색했지만 로컬에서 이미지를 찾지 못하고 Docker Hub라는 Public Registry에서 이미지를 꺼내 해당 이미지에서 컨테이너를 만들고 실행했다.
다음 명령을 실행해 도커 허브에서 가져온 컨테이너 이미지를 확인한다.
docker images
다음 내용은 도커 허브의 퍼블릭 레지스트리에서 가져온 이미지이다.
이미지 ID는 SHA256 해시 형식이며 이 필드(이미지 ID)는 프로비저닝된 도커 이미지를 지정한다.
도커 데몬은 로컬에서 이미지를 찾을 수 없을 경우 기본적으로 퍼블릭 레지스트리에서 이미지를 검색한다.
다시 한번 컨테이너를 실행해보자
docker run hello-world
두번째 실행 시 도커 데몬은 로컬 레지스트리 내의 이미지를 찾아내고 해당 이미지로 컨테이너를 실행한다.
도커 허브에서 이미지를 가져올 필요가 없다.
다시 다음 명령을 이용해 실행 중인 컨테이너를 확인한다.
docker ps
실행 중인 컨테이너가 없다. 이전에 실행한 hello-world 컨테이너는 이미 종료되었기 때문이다.
실행이 완료된 컨테이너를 포함해 모든 컨테이너를 보려면 다음 명령을 입력한다.
docker ps -a
우리는 컨테이너 ID(컨테이너를 식별하기 위해 도커가 생성한 UUID)를 확인할 수 있고 실행에 대한 추가 metadata를 알 수 있다.
컨테이너 이름도 임의로 생성이 되지만 docker run --name [container-name] hello-world을 사용해 지정할 수 있다.
✔️ Build
간단한 노드 어플리케이션을 기반으로 도커 이미지를 구축해본다.
test라는 이름의 폴더를 만들고 이동한다.
mkdir test && cd test
Dockerfile을 만든다.
cat > Dockerfile <<EOF
# Use an official Node runtime as the parent image
FROM node:6
# Set the working directory in the container to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Make the container's port 80 available to the outside world
EXPOSE 80
# Run app.js using node when the container launches
CMD ["node", "app.js"]
EOF
이 파일은 Docker 데몬에게 이미지를 빌드하는 방법을 지시한다.
첫 행은 base parent image를 지정한다. 이 경우 노드 버전 6의 공식 도커 이미지가 된다.
두번째는 컨테이너의 작업(현재) 디렉토리를 설정한다.
세번째로는 현재 디렉토리의 콘텐츠("."로 표시됨)를 컨테이너에 추가한다.
그런 다음 컨테이너의 포트를 노출하여 해당 포트에서 연결을 허용하고
마지막으로 node 명령을 실행해 응용 프로그램을 시작한다.
Dockerfile 명령어 참조를 확인하고 각 행의 의미를 이해해보자
이제 노드 어플리케이션을 작성 후 이미지를 빌드한다.
노드 어플리케이션을 작성하려면 다음 절차를 수행한다.
cat > app.js <<EOF
const http = require('http');
const hostname = '0.0.0.0';
const port = 80;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log('Server running at http://%s:%s/', hostname, port);
});
process.on('SIGINT', function() {
console.log('Caught interrupt signal and will exit');
process.exit();
});
EOF
이것은 포트 80에서 수신해 "Hello World"를 반환하는 단순한 HTTP 서버이다.
이제 이미지를 구축해보자
"."는 현재 디렉토리를 의미하므로 Docker 파일이 있는 디렉토리 내에서 다음 명령을 실행해야 한다.
docker build -t node-app:0.1 .
이 명령이 실행 완료될 때까지 몇분 정도 걸릴 수 있다. 출력은 다음과 같다.
-t는 name:tag syntax를 사용하여 이미지에 이름을 붙이고 태그를 붙인다.
이미지의 이름은 node-app이고 태그는 0.1이다.
도커 이미지를 빌드할 때 이 태그를 사용하는 것이 좋다.
만약 태그를 지정하지 않으면 태그는 기본적으로 최신으로 설정되며 새로운 이미지와 오래된 이미지를 구별하기가 더 어려워진다. 추가로 위의 Dockerfile의 각 행이 이미지 빌드 시 중간 컨테이너 레이어를 생성하는 방법에 주목하자
이제 다음 명령을 실행하여 작성한 이미지를 확인확인한다.
docker images
Notice 노드는 기본 이미지이고 node-app은 빌드한 이미지이다.
노드 앱을 먼저 제거하지 않고는 노드를 제거할 수 없다.
이미지의 사이즈는 VM에 비해 비교적 작다.
node:slim이나 node:alpine 등의 다른 버전의 노드 이미지를 사용하면 보다 작은 이미지로 이동하기 쉬워진다.
✔️ Run
이 모듈에서 작성한 이미지를 기반으로 컨테이너를 실행하려면 다음 코드를 사용한다.
docker run -p 4000:80 --name my-app node-app:0.1
--name 플래그를 사용하면 원하는 경우 컨테이너의 이름을 지정할 수 있다.
-p는 Docker에게 호스트의 포트 4000을 컨테이너의 포트 80에 매핑하도록 지시한다.
이제 http://localhost:4000 의 서버에 접속할 수 있다.
포트 매핑이 없으면 localhost의 컨테이너에 도달할 수 없다.
다른 터미널을 열고 서버를 테스트하자
curl http://localhost:4000
컨테이너는 초기 터미널이 실행되는 동안 실행된다.
컨테이너를 백그라운드에서 실행할 경우(터미널 세션에 연결되지 않음) -d 플래그를 지정해야 한다.
초기 터미널을 닫은 후 다음 명령을 실행하여 컨테이너를 중지하고 제거한다.
docker stop my-app && docker rm my-app
이제 다음 명령을 실행하여 백그라운드에서 컨테이너를 시작한다.
docker run -p 4000:80 --name my-app -d node-app:0.1
docker ps
docker ps의 출력으로 컨테이너가 동작하고 있음을 확인하자
docker logs [container_id] 명령을 실행해 로그를 확인할 수 있다.
TIp : 첫 글자가 컨테이너를 고유하게 식별하기만 하면 컨테이너 ID 전체를 쓸 필요가 없다.
예를 들어 컨테이너 ID가 17bcaca6f...인 경우 도커 로그 17b를 실행할 수 있다.
docker logs [container_id]
어플리케이션을 수정해보자. Cloud Shell에서 앞서 작성한 테스트 디렉토리를 열자
cd test
선택한 텍스트 편집기(예: nano 또는 vim)를 사용하여 app.js를 편집하고 "Hello World"를 다른 문자열로 바꾼다.
....
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Welcome to Cloud\n');
});
....
이 새로운 이미지를 태그를 0.2로 붙여 빌드한다.
docker build -t node-app:0.2 .
스텝 2에서는 기존 캐시 레이어를 사용하고 있다. 스텝 3 이후로는 app.js를 변경했기 때문에 레이어가 변경된다.
새 이미지 버전으로 다른 컨테이너를 실행한다.
왜 호스트의 포트를 80번 대신 8080으로 매핑하는지 주의해보자.
왜냐하면 호스트 포트 4000은 이미 사용 중이므로 사용할 수 없기 때문이다.
docker run -p 8080:80 --name my-app-2 -d node-app:0.2
docker ps
컨테이너를 테스트한다.
curl http://localhost:8080
이제 처음 만든 컨테이너를 테스트한다.
curl http://localhost:4000
'Study > Study Jam' 카테고리의 다른 글
[Study Jam] Managing Deployments Using Kubernetes Engine - 1 (0) | 2022.03.24 |
---|---|
[Study Jam] Introduce to Docker (도커 입문) - 2. Debug, Publish (0) | 2022.03.24 |
[Study Jam] Orchestrating the Cloud with Kubernetes - 2 (0) | 2022.03.24 |
[Study Jam] Orchestrating the Cloud with Kubernetes - 1 (0) | 2022.03.23 |
[Study Jam] 네트워크 및 로드밸런서 설정하기 (0) | 2022.03.23 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!