본문 바로가기

Personal/Cloud

구글 클라우드 스터디잼 쿠버네티스 입문 - 1. Docker 소개

[실습 설명]

실습 첫 화면

도커 컨테이너에서의 작업을 Google Kubernetes Engine에서 제공하는 쿠버네티스 클러스터로 배포하는 방법과 증가한 트래픽에 대처할 수 있게 스케일링 하는 방법에 대해 다룬다.

+

애플리케이션 업데이트에 따라 지속적으로 쿠버네티스 클러스터로 새로운 코드를 배포하는 방법에 대해서 배울 수 있다.

 

[실습1 - Docker 소개]

[실습 과정]

먼저, 왼쪽 상단의 실습 시작 버튼을 누르면 시간이 흘러 가면서 계정 정보를 제공해준다. Open Google Console 버튼을 누르면 새로운 창에서 아래의 계정 정보로 구글 로그인을 할 수 있게 된다.

실습 첫 화면

계정 정보로 로그인을 하고 여러 가지 동의를 하면, Google Cloud Platform 화면이 나오고 실습을 무료로 진행할 수 있다.

이제 이 화면에서 오른쪽 상단의 쉘처럼 생긴 아이콘을 누르면 아래처럼 Google Cloud Shell 이 활성화 된다.

사용 중인 계정 이름 목록을 표시하자.

gcloud auth list 라는 명령어로 확인 가능하다.

다음으로 프로젝트 ID 목록을 표시하자

gcloud config list project 라는 명령어로 확인 가능하다.

project id가 잘 출력되는 것을 확인할 수 있다.

 

[작업 1. Hello World]

hello world 컨테이너를 실행하는 명령어인 docker run hello-world 를 입력한다.

그 결과 Hello from Docker! 라는 문자열을 반환하는 것을 볼 수 있다.

Docker Hub 라는 공개 레지스트리에서 이미지를 가져오고, 가져온 이미지에서 컨테이너를 생성하고, 컨테이너를 실행한 것을 알 수 있다.

docker images 라는 명령어로 Docker Hub에서 가져온 컨테이너 이미지를 확인할 수 있다.

이미지 ID는 SHA256 해시 형식이다.

컨테이너를 다시 실행한다. 두 번째로 실행하면 로컬에서 이미지를 찾을 수 없다 라는 말이 출력되지 않으므로 Docker 데몬이 로컬 레지스트리에서 이미지를 찾은 뒤 이 이미지에서 컨테이너를 실행하였음을 예상할 수 있다.

docker ps 명령어로 실행 중인 컨테이너를 확인할 수 있다. 이미 종료되었으므로 실행 중인 컨테이너가 없다.

docker ps -a 명령어는 실행이 완료된 컨테이너를 포함하여 모든 컨테이너를 볼 수 있다.

 

[작업 2. 빌드]

test 폴더를 만들고 해당 경로로 이동한다.

cat > Dockerfile <<EOF
# Use an official Node runtime as the parent image
FROM node:lts
# 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 데몬에 이미지를 빌드하는 방법이다. 

첫 번째 줄은 기본 상위 이미지를 지정한다. 노드 버전 장기적 지원(LTS)의 공식 Docker 이미지이다.

두 번째 줄은 컨테이너의 현재 작업 디렉토리를 설정한다.

세 번째 줄은 현재 디렉터리의 콘텐츠(".")를 컨테이너에 추가한다.

네 번째 줄은 컨테이너의 포트를 공개하여 해당 포트에서의 연결을 허용한다. 80번 포트

마지막 줄은 노드 명령어를 실행하여 애플리케이션을 시작한다.

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 build -t node-app:0.1 . 이다. 몇 분 정도 기다리면 결과가 출력된다.

-t는 name:tag 문법을 사용하여 이미지의 이름과 태그를 지정하는 역할을 한다.

이미지 이름은 node-app 이고 태그는 0.1이다. Docker 이미지를 빌드할 때는 태그를 사용하는 것이 좋다고 한다.

빌드한 이미지를 보려면 docker images 라는 명령어를 입력하면 된다.

 

[작업 3. 실행]

빌드한 이미지를 기반으로 하는 컨테이너를 실행하려면 docker run -p 4000:80 --name my-app node-app:0.1 명령어를 입력하면 된다.

--name 플래그로 컨테이너 이름을 지정할 수 있다. -p는 Docker가 컨테이너의 포트 80에 호스트의 포트 4000을 매핑하도록 지시하는 플래그이다. 

 

새로운 터미널을 열어서 curl http://localhost:4000 을 입력하면 Hello World 라는 문자열을 출력한다.

컨테이너 중지 및 삭제하기는 docker stop my-app && docker rm my-app 명령어를 통해 가능하다.

백그라운드에서 컨테이너를 다시 시작한다. -d 옵션을 지정하면 백그라운드에서 실행가능하다.

docker ps로 확인까지 해보면 my-app이라는 이름의 컨테이너가 실행 중인 것을 확인할 수 있다.

docker logs [container_id] 명령어를 통해 로그를 볼 수 있다.

app.js 파일의 Hello World 문자열을 원하는 다른 문자열로 변경한다.

나는 Hello CLOUD CLUB 으로 변경하였다.

새로운 이미지를 빌드하고 0.2로 태그를 지정했다.

새 이미지 버전으로 다른 컨테이너를 8080 포트로 매핑하여 실행시킨다.

컨테이너를 테스트하면 Hello CLOUD CLUB 이 잘 나오는 것을 확인할 수 있다.

0.1 태그인 컨테이너를 테스트하면 Hello World 즉, 바꾸기 전의 문자열로 잘 나오는 것을 확인 가능하다.

 

[작업 4. 디버그]

실행 중인 컨테이너의 로그를 확인하려면 -f 옵션을 추가해줘야 한다.

실행 중인 컨테이너에서 대화형 Bash 세션을 시작하는 방법은 docker exec 를 사용하면 된다.

-it 옵션은 pesudo-tty 를 할당하고 stdin을 열린 상태로 유지하여 컨테이너와 상호작용할 수 있도록한다고 한다.

dockerfile에 지정된 WORKDIR 즉, app 디렉토리에서 bash가 실행된 것을 확인 가능하다.

ls로 파일 목록을 확인해보면 Dockerfile과 app.js가 잘 있는 것을 확인할 수 있다.

exit를 입력해서 Bash 세션을 종료할 수 있다.

docker inspect [container_id] 명령어로 Docker 컨테이너의 메타데이터들을 확인할 수 있다.

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [container_id]

--format으로 json의 특정 필드를 출력할 수 있다. 

 

참고 사이트

https://docs.docker.com/engine/reference/commandline/inspect/#examples

 

docker inspect

docker inspect: Docker inspect provides detailed information on constructs controlled by Docker. By default, `docker inspect` will render results in a JSON array. ### Format the output (--format) {#format} If...

docs.docker.com

https://docs.docker.com/engine/reference/commandline/exec/

 

docker exec

docker exec: The `docker exec` command runs a new command in a running container. The command started using `docker exec` only runs while the container's primary process (`PID 1`) is...

docs.docker.com

 

[작업 5. 게시]

이미지를 Google Artifact Registry로 푸시해보자

여기서 Artifact Registry > 저장소로 이동하고 만들기를 클릭합니다.

저장소 이름은 my-repository 지정, 형식 Docker, Region -> us-central1 (Iowa) 로 선택합니다.

만들기를 누릅니다.

만들어진 것을 확인할 수 있다.

다음으로 이미지를 푸시하거나 가져오려면 Docker가 Artifact Registry에 대한 요청을 인증하는데 Google Cloud CLI를 사용하도록 설정해야 한다.

Docker 구성을 업데이트하였다. 

프로젝트 id를 설정하고 Dockefile이 포함된 디렉토리인 test로 디렉토리를 변경한다.

node-app:0.2라는 태그를 지정한다.

docker images 명령어로 빌드된 Docker 이미지를 확인한다.

docker push us-central1-docker.pkg.dev/$PROJECT_ID/my-repository/node-app:0.2

마지막으로 Artifact Registry로 푸시한다.

my-repository를 클릭하면 node-app Docker 컨테이너가 생성된 것을 볼 수 있다.

모든 컨테이너를 중지하고 삭제한다.

docker rmi us-central1-docker.pkg.dev/$PROJECT_ID/my-repository/node-app:0.2
docker rmi node:lts
docker rmi -f $(docker images -aq) # remove remaining images
docker images

그 이후 Docker 이미지도 모두 삭제한다.

결과를 보면 잘 삭제된 것을 알 수 있다.

이미지를 pull해와서 실행한다. Hello CLOUD CLUB이 출력된다.

마지막으로 내 진행 상황 확인하기 버튼을 누르고 체크 표시가 나오면 클라우드 스터디잼의 첫 번째 실습을 완료한 것이다.

  • Docker Hub의 공개 이미지를 기반으로 컨테이너 실행
  • 컨테이너 이미지를 빌드하고 Google Artifact Registry로 푸시
  • 실행 중인 컨테이너를 디버그하는 방법 숙지
  • Google Artifact Registry에서 가져온 이미지를 기반으로 컨테이너 실행

-> 이 4가지는 첫 번째 실습에서 배운 것을 정리한 내용이다.