본문 바로가기
TIL

[240111] Docker image, Docker container

by 진진리 2024. 1. 11.
728x90

Docker Image

  • 라이브러리, 종속성에 대한 정의, 코드가 포함되어 있는 실행되지 않은 OS 파일
  • 컨테이너 런타임에 필요한 바이너리, 라이브러리 및 설정 값 등을 포함
  • 변경되는 상태값을 보유하지 않고 변하지 않음(stateless, immutable, read-only)
    • 상태 저장 없음(Stateless): 다른 환경에서도 동일한 애플리케이션을 실행 가능
    • 불변성(Immutable): 이미지가 한 번 생성되면 변경할 수 없음
  • 필요한 파일만 포함하고 있어 용량이 작음

 

Docker Image 실습

  • docker pull [name:tag]: 도커 허브에서 이미지 내려받기
    • Private Registry 서버를 통해 이미지를 제공받거나 제공 가능
# docker [image] pull [options] name:[tag]

# 최초에는 docker.io가 default registry로 설정됨.
docker pull debian[:latest]
docker pull library/debian:10
docker pull docker.io/library/debian:10
docker pull index/docker.io/library/debian:10
docker pull nginx:latest

# private registry 나 클라우드 저장소의 이미지를 받는 경우
docker pull 192.168.0.101:5000/debian:10 # 현재는 실제로 동작하지 않음
docker pull gcr.io/google-samples/hello-app:1.0

 

  • docker image inspect [image:tag]: 도커 이미지 구조 확인
    • 생성된 이미지의 내부 구조 정보를 json 형태로 제공
docker image inspect --format="{{.Os}}" nginx:latest
linux
docker image inspect --format="{{.RepoTags}}" nginx:latest
[nginx:latest]
docker image inspect --format="{{.ContainerConfig.ExposedPorts}}" nginx:latest
map[80/tcp:{}]
docker image inspect --format="{{.RepoTags}} {{.Os}}" nginx:latest
[nginx:latest] linux

 

  • docker image history [image:tag]: Dockerfile에 대한 정보
    • 여러 개의 계층 구조로 구성
    • docker pull 시 다운로드된 계층들 정보는 전용 경로에 저장됨

 

  • docker login/logout: 도커 허브에서 회원가입 후 실행
docker login
Log in with your Docker ID or email address to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com/ to create one.
You can log in with your password or a Personal Access Token (PAT). Using a limited-scope PAT grants better security and is required for organizations using SSO. Learn more at https://docs.docker.com/go/access-tokens/

Username: {자신의 계정}
Password: {자신의 암호}
Login Succeeded

$ docker logout
Removing login credentials for https://index.docker.io/v1/

 


Docker Container

  • Docker Image를 실행한 상태로 하나의 도커 이미지로부터 N개의 컨테이너를 생성할 수 있음
  • Docker Container는 프로세스

Docker Container 실습

Docker의 생애주기(Lifecycle)

 

  • Docker Container 수동 생성
docker pull ubuntu:22.04
docker images

# docker create 은 실제 실행하지 않고 컨테이너 생성만
docker create -ti --name ubuntu2204test ubuntu:22.04
docker ps –a
CONTAINER ID   IMAGE          COMMAND       CREATED         STATUS    PORTS     NAMES
2ccc1b2a1144   ubuntu:22.04   "/bin/bash"   4 seconds ago   Created             ubuntu2204test

docker start ubuntu2204test
Ubuntu2204test
docker attach ubuntu2204test

# docker run 은 create/start/attach 를 순차적으로 한 번에 실행하는 것과 같음 
docker run -ti --name=ubuntu2204test2 ubuntu:22.04 /bin/bash
root@57a1a1c759b6:/#

# docker 컨테이너 종료
root@57a1a1c759b6:/# exit

 


컨테이너 명령어

  • 실습
cd ~
mkdir nodejsapp
cd nodejsapp
vi app.js # 테스트용 nodejs 앱 작성
vi Dockerfile # 새로운 도커 이미지를 위한 Dockerfile 작성
docker buildx build -t node-test:1.0 . # 1.0 태그를 추가하여 node-test라는 이미지를 빌드 
docker images | grep node-test  # 빌드 완료한 이미지 보기
docker image history node-test:1.0 # 1.0으로 태그 추가한 이미지의 Dockerfile history
docker run -itd -p 6060:6060 --name=node-test -h node-test node-test:1.0
docker ps | grep node-test
curl http://localhost:6060

 

  • app.js 파일
const http = require('http');
const server = http.createServer().listen(6060);
server.on('request', (req, res) => {
	console.log('요청 처리중');
	res.write("HostName: " + process.env.HOSTNAME + "\n");
	res.end();
});
server.on('connection', (socket) => {
	console.log("연결 완료.");
});

 

  • Dockerfile
FROM node:20-alpine
RUN apk add --no-cache tini curl
WORKDIR /app
COPY app.js .
EXPOSE 6060
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "app.js"]

 

 

docker run 자주 사용하는 옵션

  • -d: detached mode; 백그라운드 모드
  • -p: 호스트와 컨테이너의 포트를 연결(포워딩)
  • -v: 호스트와 컨테이너의 디렉토리를 연결(마운트)
  • -e: 컨테이너 내에서 사용할 환경변수 설정
  • -name: 컨테이너 이름 설정
  • -rm: 프로세스 종료 시 컨테이너 자동 삭제
  • -ti: -i 와 -t 를 동시에 사용한 것으로 터미널 입력을 위한 옵션

 

실행 중인 Container에 대한 정보

# 컨테이너에서 실행 중인 프로세스 조회
docker top node-test(컨테이너 이름) 
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                2398                2378                0                   08:37               ?                   00:00:00            /sbin/tini -- node runapp.js
root                2421                2398                0                   08:37               ?                   00:00:00            node runapp.js

# 컨테이너에 매핑된 포트 조회
docker port node-test
8080/tcp -> 0.0.0.0:8080

# 컨테이너 리소스 통계 출력 (1회)
docker stats node-test --no-stream
CONTAINER ID   NAME        CPU %     MEM USAGE / LIMIT     MEM %     NET I/O        BLOCK I/O   PIDS
14c475f7ac09   node-test   0.01%     9.035MiB / 15.45GiB   0.06%     1.5kB / 518B   0B / 0B     11

# 컨테이너 리소스 통계 출력 (스트림)
docker stats node-test

 

 

  • docker logs
# 표준 출력(stdout), 표준에러(stderr) 출력
docker logs node-test 
…
 
# 로그를 계속 출력
docker logs –f node-test
…
…

# 출력된 로그는 파일로 관리되기 때문에 HostOS 의 disk 를 사용
docker info | grep -i log

 

  • docker [container] inspect
    • 컨테이너 내부 확인
  • docker stop | start | pause | unpause
# 터미널1, 도커 상태 확인
docker stats

# 터미널2, 도커 프로세스 이벤트 확인
docker events

# 터미널3, docker start
docker stop node-test
docker ps –a
docker start node-test

# 
docker pause node-test
docker unpause node-test
docker ps -a

 

 

docker exit code

  • 0: Docker Process가 수행해야 할 모든 Command 또는 Shell을 실행하고 정상 종료
  • 255: Docker Image에 정의된 EntryPoint 또는 CMD가 수행이 완료되었을 경우 발생
  • 125: Docker run 명령어의 실패로 실제 docker process가 기동되지 않음
  • 126: Docker Container 내부에서 Command를 실행하지 못할 경우 발생
  • 127: Docker Container 내부에서 Command를 발견하지 못하였을 경우 발생
  • 137: kill -9로 인해 종료됨
  • 141: 잘못된 메모리 참조하여 종료 됨
  • 143: Linux Signal로 정상 종료 됨
  • 147: 터미널에서 입력된 정지 시그널로 종료됨
  • 149: 자식 프로세스가 종료 되어 종료됨

 

Docker Container를 정리하는 방법

  • docker container prune: 실행 중이 아닌 컨테이너를 모두 삭제
  • docker image prune: 태그가 붙지 않은(dangling) 모든 이미지 삭제
  • docker system prune: 사용하지 않는 도커 이미지, 컨테이너, 볼륨, 네트워크 등 모든 도커 리소스를 일괄적으로 삭제