Introduction to Docker
Introduction to Docker
1.Overview
- Docker: 애플리케이션을 developing, shipping, running하기 위한 개방형 플랫폼
- Docker를 사용하면,
1) Application을 인프라에서 분리하고 인프라를 managed application처럼 다룰 수 있음
2) 더 빠르게 코드를 제공, 테스트 및 배포 → 코드 작성과 코드 실행 사이의 cycle를 단축
- Docker는 커널 컨테이너화 기능을 application 관리, 배포에 도움이 되는 워크플로우, 도구와 결합하여 수행
- Docker 컨테이너는 Kubernetes에서 직접 사용할 수 있음
2. Setup and Requirements
- Google Cloud Platform(GCP) 환경 설정
3. Hello World
1) hello world 컨테이너 실행
> Input
docker run hello-world
> Output
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
...
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
- Docker Daemon이 hello-world 이미지를 검색했지만 로컬에서 이미지를 찾지 못함
- Docker Hub라는 공용 레지스트리에서 이미지를 가져와서 해당 이미지에서 컨테이너를 생성하고 컨테이너를 실행
2) Docker Hub에서 가져온 컨테이너 이미지 확인
> Input
docker images
> Output
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest 1815c82652c0 6 days ago 1.84 kB
- 이미지 ID는 SHA256 해시 형식
- 프로비저닝된 Docker 이미지를 지정
3) hello world 컨테이너 재실행
docker run hello-world
- 두 번째로 실행할 때 Docker Daemon은 로컬 레지스트리에서 이미지를 찾고 해당 이미지에서 컨테이너를 실행
4) 실행 중인 컨테이너 확인
docker ps
5) 실행 완료 컨테이너를 포함한 모든 컨테이너 확인
docker ps -a
- Container ID, 컨테이너를 식별하기 위해 Docker에서 생성한 UUID, 실행과 관련된 여러 메타데이터 표시
- 컨테이너 이름도 무작위로 생성되지만 아래 코드로 지정 가능
docker run --name [container-name] hello-world
4. Build
1) 이미지 빌드 방법을 Docker Daemon에 지시
mkdir test && cd test
# 도커 파일 생성 과정
cat > Dockerfile <<EOF
# 기본 상위 이미지를 지정(노드 버전 장기 지원(lts) 공식 Docker 이미지) / 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
# node 명령을 실행하여 애플리케이션을 시작 / Run app.js using node when the container launches
CMD ["node", "app.js"]
EOF
- Dockerfile command references
2) 노드 애플리케이션 작성
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 서버
3) 노드 애플리케이션 기반 Docker 이미지 빌드
docker build -t node-app:0.1 .
- Dockerfile이 있는 디렉토리 내에서 이 명령을 실행(.)
- -t: 이미지에 이름과 태그를 지정
4) 빌드한 이미지 확인
docker images
- node: 기본 이미지
- node-app: 빌드한 이미지
5. Run
1) 빌드한 이미지로 컨테이너 실행
docker run -p 4000:80 --name my-app node-app:0.1
2) 다른 터미널에서 서버 테스트
curl http://localhost:4000
3) 컨테이너 중지 및 제거
docker stop my-app && docker rm my-app
4) 백그라운드에서 컨테이너 시작
docker run -p 4000:80 --name my-app -d node-app:0.1
docker ps
5) 컨테이너 로그 확인
docker logs [container_id]
6) 레이어 수정
cd test
vi app.js
....
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Welcome to Cloud\n');
});
....
docker build -t node-app:0.2 .
- Hello World → Welcome to Cloud
- 2단계에서 기존 캐시 계층을 사용
- app.js를 변경했기 때문에 3단계부터 레이어가 수정됨
7) 새 이미지 버전으로 다른 컨테이너 실행
docker run -p 8080:80 --name my-app-2 -d node-app:0.2
docker ps
curl http://localhost:8080
- 두번째 컨테이너 테스트
curl http://localhost:4000
- 첫번째 컨테이너 테스트
6. Debug
1) 컨테이너 로그 확인
docker logs -f [container_id]
2) 실행 중인 컨테이너 내에서 대화형 Bash 세션 시작(다른 터미널에서)
docker exec -it [container_id] bash
- -it: pseudo-tty를 할당하고 표준 입력을 열린 상태로 유지하여 컨테이너와 상호 작용
ls
exit
3) Docker inspect를 사용하여 Docker에서 컨테이너의 메타데이터 검사
docker inspect [container_id]
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [container_id]
- --format: 반환된 JSON에서 특정 필드를 검사
- Docker inspect reference
- Docker exec reference
7. Publish
- 이미지를 Google Container Registry (gcr)에 push
- 모든 컨테이너와 이미지를 제거하여 새로운 환경을 시뮬레이션하고, 컨테이너를 가져와 실행
1) gcr에서 호스팅하는 비공개 레지스트리에 이미지 push
- 이미지에 레지스트리 이름을 태그
- 형식: [hostname]/[project-id]/[image]:[tag]
- [hostname]= gcr.io
- [project-id]= 프로젝트 ID
- [image]= 이미지 이름
- [tag]= 선택한 문자열 태그, 기본값 "latest"
gcloud config list project
docker tag node-app:0.2 gcr.io/[project-id]/node-app:0.2
docker images
docker push gcr.io/[project-id]/node-app:0.2
2) 웹 브라우저에서 이미지 레지스트리를 방문하여 이미지가 gcr에 있는지 확인
(1) Navigation menu > Container Registry > node-app
(2) http://gcr.io/[project-id]/node-app
3) 모든 컨테이너를 중지하고 제거
docker stop $(docker ps -q)
docker rm $(docker ps -aq)
4) 노드 이미지를 제거하기 전 하위 이미지를 제거
docker rmi node-app:0.2 gcr.io/[project-id]/node-app node-app:0.1
docker rmi node:lts
docker rmi $(docker images -aq) # remove remaining images
docker images
5) 이미지 Pull하고 실행
docker pull gcr.io/[project-id]/node-app:0.2
docker run -p 4000:80 -d gcr.io/[project-id]/node-app:0.2
curl http://localhost:4000
'대외활동 > Google Cloud Study Jam' 카테고리의 다른 글
[Kubernetes 입문] Continuous Delivery with Jenkins in Kubernetes Engine (0) | 2022.07.31 |
---|---|
[Kubernetes 입문] Managing Deployments Using Kubernetes Engine (0) | 2022.07.29 |
[Kubernetes 입문] Orchestrating the Cloud with Kubernetes (0) | 2022.07.26 |
[Kubernetes 입문] Kubernetes Engine: Qwik Start (0) | 2022.07.25 |
[Kubernetes 입문] Kubernetes in Google Cloud (0) | 2022.07.24 |