김가은-3

김가은-3

[따베도] 도커 시리즈 - 실습

11. Docker Install on VM(Ubuntu 22.04)

3-2. 도커 컨테이너 살펴보기 - 실습편

4-2-1. 도커 컨테이너 만들어보기 - 실습편

4-2-2. 문제풀이

5-2. 컨테이너 보관창고(Docker Registry) - 실습편

6-2. Docker 컨테이너 사용하기 - 실습편

7-2. Docker 컨테이너 리소스를 관리하기 - 실습편

8-2. Docker Container Storage - 실습편

9-2. 컨테이너 간 통신(네트워크) - 실습편


Docker Install on VM(Ubuntu 22.04)

  1. VM 정보

MPN 구독에서 테스트용 Ubuntu VM 을 생성한다.

구분

구분

구독

Virtual Studio Enterprise - 구독 MPN

리소스 그룹

RG-ContainerTest-KGE

Region

Korea Central

VM 이름

svr-ubuntu-docker

VM 이미지

Ubuntu Server 22.04 LTS - x64 Gen2

VM 크기

Standard_D2s_v3 - (2 vcpu, 8GiB 메모리)

VNet 정보

Vnet : VNet-MGMT (10.0.0.0/16)

Subnet : default(10.0.0.0/24)

공용 IP

svr-ubuntu-docker-ip (20.39.202.144)

 

  1. OS 시스템 정보

구분

구분

OS 버전

Ubuntu 22.04.5 LTS

커널 버전

6.8.0-1029-azure

Memory

8GiB

vCPU

2 core

Disk

30GiB

 

  1. Docker Engine 설치

https://docs.docker.com/engine/install/ubuntu/ 에서 매뉴얼 참고

세 가지 설치 방법(Repository, 설치파일, 스크립트) 이 있지만 그 중에 Repository 방법으로 설치를 진행한다.

image-20250527-044810.png
  1. 종속성 패키지 제거

for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done

 

  1. Docker apt저장소 설정

# Add Docker's official GPG key: sudo apt-get update sudo apt-get install -y ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc # Add the repository to Apt sources: echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update

 

  1. Docker packages 설치

sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

 

  1. 설치 완료 확인

docker version docker info
image-20250527-050538.png
image-20250527-050740.png

 

  1. Docker 관리자 계정 만들기

  • 기본적으로 docker 관리자는 root 계정뿐임 (sudo -i로 root 접속을 해야 도커 명령어가 가능함)

  • gekim 라는 계정이 있을 때 이 계정이 docker 관리자가 될 수 있도록 구성하기 (usermod 명령어 이용)

root@svr-ubuntu-docker:~# id gekim uid=1000(gekim) gid=1000(gekim) groups=1000(gekim),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),119(netdev),120(lxd) root@svr-ubuntu-docker:~# usermod -a -G docker gekim root@svr-ubuntu-docker:~# id gekim uid=1000(gekim) gid=1000(gekim) groups=1000(gekim),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),119(netdev),120(lxd),999(docker)

 

  • 설정 후 로그아웃-로그인하여 user 사용자로 docker 명령어가 잘 실행되는지 확인 (sudo -i 없이 계정에서 실행)


컨테이너와 컨테이너 이미지

  1. Docker Hub에서 컨테이너 이미지 검색

docker search nginx
image-20250527-053746.png

 

  1. 컨테이너 이미지 다운로드 및 Overlay 구조 확인

컨테이너 이미지를 다운받으면 /var/lib/docker/overlay2 → 이 디랙토리에 overlay가 파일 형태로 저장됨

 

  • 컨테이너 이미지 다운로드 전

/var/lib/docker/overlay2에 파일이 조회되지 않음

image-20250527-054348.png

 

  • 컨테이너 이미지 다운로드 후

docker pull nginx

 

pull 명령어 실행 시 다운로드되는 파일들이 docker 이미지의 overlay임

61320b01ae5e: Pull complete 670a101d432b: Pull complete 405bd2df85b6: Pull complete cc80efff8457: Pull complete 2b9310b2ee4b: Pull complete 6c4aa022e8e1: Pull complete abddc69cb49d: Pull complete

 

동일하게 7개 파일이 /var/lib/docker/overlay2 하위에 다운로드됨

image-20250527-054548.png

 

  1. 도커 컨테이너 실행

docker run --name web -d -p 80:80 nginx
image-20250527-055211.png

 

  • 페이지 접속 확인

curl localhost:80
image-20250527-055456.png

 

  • 외부에서 접속 테스트 (NSG에서 80 Port 인바운드 허용 필요)

image-20250527-055652.png
  • 컨테이너 및 이미지 제거

docker stop web docker rm web docker rmi nginx

 

이미지를 제거하면 /var/lib/docker/overlay2 디랙토리 하위 파일들도 제거됨

image-20250527-055942.png

컨테이너 빌드하기

  1. Node Js 컨테이너 빌드 실습

1-1. Node Js 소스코드 준비하기

  • TestJS라는 디랙토리 하위에 hello.js 소스 코드를 생성한다.

  • Port 8080에서 HTTP 요청을 받고, 요청한 클라이언트의 IP 주소를 로그로 출력하며, 응답으로 컨테이너의 호스트 이름을 반환하는 소스코드임

gekim@svr-ubuntu-docker:~$ mkdir TestJS gekim@svr-ubuntu-docker:~$ cd TestJS/ gekim@svr-ubuntu-docker:~/TestJS$ cat > hello.js const http = require('http'); const os = require('os'); console.log("Test server starting..."); var handler = function(request, response) { console.log("Received request from " + request.connection.remoteAddress); response.writeHead(200); response.end("Container Hostname: " + os.hostname() + "\n"); }; var www = http.createServer(handler); www.listen(8080);

 

Docker Hub 홈페이지 로그인 node 검색하여 베이스 이미지 확인

image-20250528-013647.png

 

1-2. 도커 파일 생성

  • FROM node:12 → 베이스 이미지를 node 12버전을 사용

  • COPY hello.js / → 현재 디랙토리(/home/gekim/TestJS) 에 있는 hello.js를 루트 디렉토리로 복사

  • CMD ["node", "/hello.js"] → node 명령어로 루트 디렉토리 하위 hello.js를 실행

gekim@svr-ubuntu-docker:~/TestJS$ pwd /home/gekim/TestJS gekim@svr-ubuntu-docker:~/TestJS$ vi dockerfile FROM node:12 COPY hello.js / CMD ["node", "/hello.js"]

 

1-3. 이미지 빌드

  • docker build : 도커 이미지를 빌드함

  • -t testjs : 이미지 태그(이미지 이름) 은 testjs임

  • testjs:latest : 이미지 버전은 latest

  • . : 현재 디랙토리에 있는 Dockerfile과 그 안에서 사용하는 모든 파일을 찾아 실행

gekim@svr-ubuntu-docker:~/TestJS$ docker build -t testjs:latest . # 이미지 빌드 확인 gekim@svr-ubuntu-docker:~/TestJS$ docker images
image-20250528-034618.png
image-20250528-034633.png

 

  1. 우분투 기반의 웹 서버 컨테이너 만들기 실습

2-1. 도커파일 만들기

  • Layer 수는 적고 Size는 작게 만들면 좋음

    • FROM ubuntu:18.04 : Base Image는 ubuntu 18.04

    • LABEL maintainer="gekim" : 이미지 작성자 정보 = gekim

    • RUN apt-get update \ : 패키지 목록을 최신화

    • && apt-get install -y apache2 : && Apache2 웹 서버를 설치하는 명령 (&&는 둘 중 하나라도 실패 시 모두 실패함)

    • RUN echo "TEST WEB" > /var/www/html/index.html: 웹서버 접속 시 브라우저에 TEST WEB 문구 표시

    • EXPOSE 80: 컨테이너 포트

    • CMD ["/usr/sbin/apache2ctl", "-DFOREGROUND"]: 컨테이너가 실행되었을 때 Apache 웹서버를 실행함. -DFOREGROUND 가 있으므로 백그라운드로 실행

gekim@svr-ubuntu-docker:~$ mkdir webserver gekim@svr-ubuntu-docker:~$ cd webserver/ gekim@svr-ubuntu-docker:~/webserver$ vim dockerfile FROM ubuntu:18.04 LABEL maintainer="gekim" # install apache RUN apt-get update \ && apt-get install -y apache2 RUN echo "TEST WEB" > /var/www/html/index.html EXPOSE 80 CMD ["/usr/sbin/apache2ctl", "-DFOREGROUND"]

 

2-2. 이미지 빌드

  • docker build : 도커 이미지를 빌드함

  • -t web01 : 이미지 태그(이미지 이름) 은 web01임

  • web01:version1 : 이미지 버전은 version1

  • . : 현재 디랙토리에 있는 Dockerfile과 그 안에서 사용하는 모든 파일을 찾아 실행

gekim@svr-ubuntu-docker:~/webserver$ docker build -t web01:version1 . # 이미지 빌드 확인 gekim@svr-ubuntu-docker:~/TestJS$ docker images
image-20250528-041740.png
image-20250528-041806.png

 

2-3. 컨테이너 실행 및 삭제

gekim@svr-ubuntu-docker:~/webserver$ docker run -d -p 80:80 --name web web01:version1 # 컨테이너 실행 확인 gekim@svr-ubuntu-docker:~/webserver$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 76b70419cf7e web01:version1 "/usr/sbin/apache2ct…" 20 seconds ago Up 20 seconds 0.0.0.0:80 ->80/tcp, [::]:80->80/tcp web # 웹 확인 gekim@svr-ubuntu-docker:~/webserver$ curl localhost:80 TEST WEB # 컨테이너 삭제 gekim@svr-ubuntu-docker:~/webserver$ docker rm -f web web

 

3. 도커 허브에 컨테이너 배포

3-1. docker 로그인

gekim@svr-ubuntu-docker:~/webserver$ docker login
image-20250528-045357.png
image-20250528-045425.png

3-2. 컨테이너 태그

  • Docker Hub Repository에 업로드하려면 이미지 태그를 변경해야 함.

  • [이미지명]:[Version] → [Repository명]/[이미지명]:[Version]

image-20250528-051743.png
gekim@svr-ubuntu-docker:~/webserver$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE web01 version1 77e57866024b 42 minutes ago 205MB testjs latest 8abe0b0dc8ce 3 hours ago 918MB gekim@svr-ubuntu-docker:~/webserver$ docker tag web01:version1 gekimkge/web01:version1 gekim@svr-ubuntu-docker:~/webserver$ docker tag testjs gekimkge/testjs
  • 변경 시 같은 이미지 내 태그가 두개가 됨

image-20250528-051528.png
  • Docker Push로 Repository에 이미지 업로드

gekim@svr-ubuntu-docker:~/webserver$ docker push gekimkge/web01:version1 gekim@svr-ubuntu-docker:~/webserver$ docker push gekimkge/testjs:latest
image-20250528-051953.png
  • Docker Hub Repository에서 업로드 결과 확인

image-20250528-052139.png

 

문제풀이

image-20250528-052500.png
  • dockerfile 디랙토리 생성

mkdir /home/gekim/fortune cd /home/gekim/fortune
  • 스트립트 준비

vi webpage.sh #!/bin/bash mkdir -p /htdocs while true do /usr/games/fortune > /htdocs/index.html sleep 10 done
  • 도커파일 준비

vi dockerfile FROM debian LABEL maintainer="gekim" # 웹 페이지 생성 스크립트 복사 및 권한 설정 COPY webpage.sh /webpage.sh RUN chmod +x /webpage.sh && \ apt-get update && \ apt-get install -y apache2 fortune && \ rm -rf /var/www/html && \ ln -s /htdocs /var/www/html EXPOSE 80 CMD ["bash", "-c", "/webpage.sh & apachectl -D FOREGROUND"]
  • 이미지 빌드 & 컨테이너 생성

gekim@svr-ubuntu-docker:~/fortune$ docker build -t gekimkge/fortune:20.02 . gekim@svr-ubuntu-docker:~/fortune$ docker run -d -p 80:80 --name fortune01 gekimkge/fortune:20.02
image-20250528-061000.png
image-20250528-061029.png

 

  • 페이지 접속 확인

image-20250528-085028.png

Container Registry 운영하기

  1. Public Registry(hub.docker.com) 에 업로드하기

 

  1. Private Registry 운영하기

  • Docker Hub에 Official Image로써 등록되어 있는 registry를 활용하여 구축할 수 있음

  • hub.docker.com 접속 후 Reistry 검색

https://hub.docker.com/_/registry

image-20250529-020543.png
  • docker 이미지 다운로드

  • 공식 문서는 2버전으로 다운로드 되도록 쓰여있으나, latest 버전으로 다운받겠음

docker run -d -p 5000:5000 --restart always --name registry registry:latest # 또는 아래처럼 latest 버전은 :latest 생략 가능 # docker run -d -p 5000:5000 --restart always --name registry registry
image-20250529-021816.png
image-20250529-042151.png
image-20250529-042218.png

 

  • port 5000 으로 이름이 registry인 컨테이너가 실행됨

    image-20250529-042255.png

 

  • 앞서 만든 fortune 이미지를 private registery에 업로드하기 위해 태그를 변경한다.

  • 태그 변경 → [LocalIP]:5000/[이미지명]:[Version]

gekim@svr-ubuntu-docker:~$ docker tag gekimkge/fortune:20.02 localhost:5000/fortune:20.02
image-20250529-043029.png

 

  • Docker Push

gekim@svr-ubuntu-docker:~$ docker push localhost:5000/fortune:20.02
image-20250529-043413.png

 

  • 실제로 레포지터리에 올라갔는지 확인하는 방법

  • docker inspect로 Repositry의 Mount 정보 검색

  • (Source → /var/lib/docker/volumes/612276c4db4e93916533d3f824bc1220a71bf91f18f1579eabb2fa9419361ffa/_data)

root@svr-ubuntu-docker:/var/lib/docker/volumes# docker inspect registry | grep -A 10 Mounts "Mounts": [ { "Type": "volume", "Name": "612276c4db4e93916533d3f824bc1220a71bf91f18f1579eabb2fa9419361ffa", "Source": "/var/lib/docker/volumes/612276c4db4e93916533d3f824bc1220a71bf91f18f1579eabb2fa9419361ffa/_data", "Destination": "/var/lib/registry", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }

 

  • [Source 경로]/docker/registry/v2/repositories/ 로 이동하여 업로드한 이미지 확인

  • /var/lib/docker/volumes/612276c4db4e93916533d3f824bc1220a71bf91f18f1579eabb2fa9419361ffa/_data/docker/registry/v2/repositories/ 하위 fortune 존재함

image-20250529-044325.png

컨테이너 명령어 사용

  1. 컨테이너 이미지 관리 명령

1-1. 이미지 검색

docker search nginx
  • 컨테이너 이미지

  • Name : 이미지명

  • Description : 설명

  • Stars : 평점

  • Official : Docker Hub에서 제공하는 공식 이미지

image-20250529-050607.png

 

1-2. 이미지 다운로드

  • docker pull

docker pull nginx # 또는 # docker pull nginx:1.14 # [:version]생략 시 latest 버전임
image-20250529-051218.png

1-3. 이미지 확인

  • docker images

docker images # 또는 docker image ls # 이미지명 풀네임으로 조회 #docker image --no-trunc
image-20250529-051241.png
image-20250529-051624.png

 

  1. 컨테이너 실행 및 운영하기

2-1. 컨테이너 실행

  • docker create

gekim@svr-ubuntu-docker:~$ docker create --name web02 nginx:1.14 fcab2266f7b963658be942912f8b83545bd20621a092d03e1bbd0092a8a4db8c
image-20250529-053337.png
  • docker start

gekim@svr-ubuntu-docker:~$ docker start web02 web02
image-20250529-053525.png

 

2-2. 컨테이너 세부정보 확인

  • docker inspect

gekim@svr-ubuntu-docker:~$ docker inspect web02 # IP Address만 조회 gekim@svr-ubuntu-docker:~$ docker inspect --format '{{.NetworkSettings.IPAddress}}' web02 172.17.0.3

 

2-3 컨테이너 로그 확인

  • docker logs

gekim@svr-ubuntu-docker:~$ docker logs web02 172.17.0.1 - - [29/May/2025:05:55:00 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.81.0" "-" # 계속 확인 # docker logs -f web02
image-20250529-055741.png

2-4 컨테이너 프로세스 확인

  • docker ps

gekim@svr-ubuntu-docker:~$ docker top web02 UID PID PPID C STIME TTY TIME CMD root 2742 2720 0 05:35 ? 00:00:00 nginx: master process nginx -g daemon off; systemd+ 2770 2742 0 05:35 ? 00:00:00 nginx: worker process
image-20250529-055821.png

2-5. 컨테이너 원격 접속

  • docker exec -it [컨테이너명] /bin/bash

  • -i (--interactive) : 표준 입력을 계속 열어줌줌

  • -t (--tty) : 터미널 인터페이스처럼 화면을 보여줌

gekim@svr-ubuntu-docker:~$ docker exec -it web02 /bin/bash root@fcab2266f7b9:/#

 

  1. 컨테이너 종료하기

3-1. 컨테이너 중지

  • docker stop

gekim@svr-ubuntu-docker:~$ docker stop web02 web02
image-20250529-060551.png

3-2. 컨테이너 삭제

  • docker rm

  • docker rm -f (running 컨테이너를 강제종료 후 삭제)

gekim@svr-ubuntu-docker:~$ docker rm web02 web02

 

3-3. 컨테이너 이미지 삭제

  • docker rmi

gekim@svr-ubuntu-docker:~$ docker rmi nginx:1.14 Untagged: nginx:1.14 Untagged: nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d Deleted: sha256:295c7be079025306c4f1d65997fcf7adb411c88f139ad1d34b537164aa060369 Deleted: sha256:19606512dfe192788a55d7c1efb9ec02041b4e318587632f755c5112f927e0e3 Deleted: sha256:0b83495b3ad3db8663870c3babeba503a35740537a5e25acdf61ce6a8bdad06f Deleted: sha256:5dacd731af1b0386ead06c8b1feff9f65d9e0bdfec032d2cd0bc03690698feda

컨테이너 리소스 관리

  • stress 컨테이너 준비

gekim@svr-ubuntu-docker:~$ mkdir build gekim@svr-ubuntu-docker:~$ cd build gekim@svr-ubuntu-docker:~/build$ vi dockerfile FROM debian LABEL maintainer="gekim" RUN apt-get update && apt install stress -y CMD ["/bin/sh", "-c", "stress -c 2"] gekim@svr-ubuntu-docker:~/build$ docker build -t stress .
image-20250529-074626.png
  1. 메모리 리소스 제한

  • 컨테이너 실행 및 부하 테스트

gekim@svr-ubuntu-docker:~/build$ docker run -m 100m --memory-swap 100m stress:latest stress --vm 1 --vm-bytes 90m -t 5s stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd stress: info: [1] successful run completed in 5s
  • -m 100m : 컨테이너에 메모리 100MB 제한 설정

  • --memory-swap 100m : 컨테이너가 사용할 수 있는 RAM + 스왑 메모리의 총합 = 100MB
    → 즉, 스왑은 0MB

  • stress는 시스템 자원에 부하를 주는 테스트 도구임

  • --vm 11개의 가상 메모리 worker를 생성

  • --vm-bytes 90m각 worker가 90MB의 메모리를 할당하려고 시도

  • -t 5s5초 동안 부하 테스트 수행

 

  1. CPU 리소스 제한

2-1. CPU Core 지정하여 사용량 제한

gekim@svr-ubuntu-docker:~$ docker run --cpuset-cpus 1 --name c1 -d stress:latest stress --cpu 1
  • --cpuset-cpus 1 : 호스트 CPU 중 1번 코어만 사용 가 (CPU가 0, 1, 2, 3번 총 4개일 경우 → 이 컨테이너는 1번만 사용)

  • stress --cpu 1 : CPU 1개에 부하 주는 명령

image-20250530-020357.png

 

2-2. 우선순위로 cpu 사용량 제한

  • -c (--cpu-shares) : 경쟁상황에 cpu 점유 비율을 결정하는 옵션임. cpu가 남아돌면? 둘 다 원 없이 100% 사용 가능함.

  • 기본값은 1024

  • 아래의 경우 경쟁 상황일 때 cload1(2048):cload2(1024) cpu 점유율 비율 = 2:1 이 됨

gekim@svr-ubuntu-docker:~$docker run -c 2048 --name cload1 -d stress:latest gekim@svr-ubuntu-docker:~$docker run -c 1024 --name cload2 -d stress:latest
image-20250530-054548.png
  • cload1 : 130~140% CPU 사용률 (즉 1.5core 정도 사용중)

  • cload2 : 60~70% CPU 사용률 (0.5core 정도 사용중)

  • 2 core 모두 100% 꽉 사용하게 됨

image-20250530-055527.png

 

  1. Block I/O 제한

  • IO 제한을 적용하려는 디스크 이름 확인

  • sda 8:0 0 30G 0 disk

gekim@svr-ubuntu-docker:~$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS loop0 7:0 0 63.8M 1 loop /snap/core20/2571 loop1 7:1 0 63.8M 1 loop /snap/core20/2582 loop2 7:2 0 89.4M 1 loop /snap/lxd/31333 loop3 7:3 0 50.9M 1 loop /snap/snapd/24671 sda 8:0 0 30G 0 disk ├─sda1 8:1 0 29.9G 0 part / ├─sda14 8:14 0 4M 0 part └─sda15 8:15 0 106M 0 part /boot/efi sdb 8:16 0 16G 0 disk └─sdb1 8:17 0 16G 0 part /mnt

 

  • --device-write-iops [DEVICE]:[RATE] : 특정 블록 디바이스(예: /dev/sda)에 대해 쓰기 작업 횟수(초당)를 제한

  • /dev/sda:10 → /dev/sda에 초당 최대 10번 쓰기 가능

gekim@svr-ubuntu-docker:~$ docker run -it --device-write-iops /dev/sda:10 ubuntu:latest /bin/bash

 

  • 컨테이너 접속 후 테스트 실행

옵션

의미

옵션

의미

if=/dev/zero

입력은 /dev/zero (0으로 채워진 무한 바이트 스트림)

of=file1

출력 파일 이름 (file1)

bs=1M

block size = 1MiB (1,048,576 bytes)

count=10

10개의 블록 (총 10MiB)

oflag=direct

버퍼 캐시(bcache)를 우회하여 디스크에 직접 쓰기 (캐시 영향 배제)

root@7113b647ca1e:/# dd if=/dev/zero of=file1 bs=1M count=10 oflag=direct 10+0 records in 10+0 records out 10485760 bytes (10 MB, 10 MiB) copied, 0.903269 s, 11.6 MB/s
  • 결과 해석

항목

설명

항목

설명

10+0 records in/out

10개의 블록을 읽고 썼음

10485760 bytes

총 10 MiB를 처리함

0.903269 s

걸린 시간 약 0.9초

11.6 MB/s

디스크 쓰기 속도 약 11.6MB/s (캐시 무시하고 실제 디스크 성능 기준)

 

  • /dev/sda:100 으로 늘려 생성한 경우 속도가 더 빨라짐

블록 크기 1M인 쓰기 작업을 10번 수행한 dd 명령에서,
IOPS가 10일 땐 초당 10번밖에 못 써서 느렸고
IOPS가 100일 땐 초당 100번까지 가능해서 빨라진 것임

gekim@svr-ubuntu-docker:~$ docker run -it --device-write-iops /dev/sda:100 ubuntu:latest /bin/bash root@c067156e5baa:/# dd if=/dev/zero of=file1 bs=1M count=10 oflag=direct 10+0 records in 10+0 records out 10485760 bytes (10 MB, 10 MiB) copied, 0.00796826 s, 1.3 GB/s

 

  1. cAdvisor (모니터링 툴) 사용하기

4-1. cAdvisor 설치

  • cAdvisor Git 접속

  • Quick Start 명령어 복사하여 실행

image-20250530-071059.png
image-20250530-071156.png
image-20250530-071721.png

 

4-2. cAdvisor 접속

  • http://[VM Public IP]:8080 웹 브라우저 접속

image-20250530-071756.png

 

  • 모니터링 그래프 확인 가능

image-20250530-071925.png

Docker Container Storage

  1. Mysql DB Data 영구 보존하기

1-1. Mysql DB 컨테이너 생성

  • -v /dbdata:/var/lib/mysql : 볼륨 마운트 – 호스트의 /dbdata 디렉터리를 컨테이너 안의 /var/lib/mysql로 연결함.

    • -v [호스트의 디렉터리]:[컨테이너 디렉터리]

    • 호스트 디렉터리 지정 안해주면 아래 경로로 됨(/var/lib/docker/volumes/uuid/_data:/var/lib/mysql)

    • MySQL의 실제 데이터가 저장되는 위치를 호스트에 유지할 수 있게 함 (데이터 영속성 확보)

    • /dbdata 디렉터리가 호스트에 존재하지 않더라도 생성해 줌

  • -e MYSQL_ROOT_PASSWORD=pass : 환경변수 설정 – MySQL의 루트 계정 비밀번호를 pass로 설정

gekim@svr-ubuntu-docker:~$ docker run -d --name db -v /dbdata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=pass mysql:latest

 

1-2. Database 생성해보기

  • db 컨테이너에 접속하여 gekimDB 데이터베이스를 생성

root@svr-ubuntu-docker:~# docker exec -it db /bin/bash bash-5.1# mysql -u root -ppass mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 10 Server version: 9.3.0 MySQL Community Server - GPL Copyright (c) 2000, 2025, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.004 sec) mysql> create database gekimDB; Query OK, 1 row affected (0.018 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | gekimDB | | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.001 sec)
  • 컨테이너 /var/lib/mysql 에 실제 gekimDB가 생성됨

  • 동일하게 호스트의 /dbdata에도 gekimDB가 생성됨

  • db 컨테이너를 삭제하여도 /dbdata는 유지됨

    • 볼륨과 함께 삭제하려면 docker rm -v <container_id>

image-20250604-040322.png
image-20250604-040426.png

 

  1. 미사용 Volume 관리하기

  • docker volume prune

  • 현재 어떤 컨테이너에도 연결되어 있지 않은 것들만 삭제

root@svr-ubuntu-docker:/var/lib/docker/volumes/a2571a1ade25de3598d1289bd2ffd3599b312146108df3f3aaef4124bd10d54c/_data# docker volume ls DRIVER VOLUME NAME local 612276c4db4e93916533d3f824bc1220a71bf91f18f1579eabb2fa9419361ffa local a2571a1ade25de3598d1289bd2ffd3599b312146108df3f3aaef4124bd10d54c root@svr-ubuntu-docker:/# docker volume prune WARNING! This will remove anonymous local volumes not used by at least one container. Are you sure you want to continue? [y/N] y Deleted Volumes: a2571a1ade25de3598d1289bd2ffd3599b312146108df3f3aaef4124bd10d54c Total reclaimed space: 0B root@svr-ubuntu-docker:/var/lib/docker/volumes/a2571a1ade25de3598d1289bd2ffd3599b312146108df3f3aaef4124bd10d54c/_data# docker volume ls DRIVER VOLUME NAME local 612276c4db4e93916533d3f824bc1220a71bf91f18f1579eabb2fa9419361ffa

  1. 웹데이터 ReadOnly 서비스로 컨테이너 지원

image-20250604-052826.png

3-1. 웹데이터 생성

root@svr-ubuntu-docker:/dbdata# mkdir /webdata root@svr-ubuntu-docker:/dbdata# cd /webdata/ root@svr-ubuntu-docker:/webdata# echo "<h1>gekim Website</h>" > index.html root@svr-ubuntu-docker:/webdata# cat index.html <h1>gekim Website</h>

 

3-2. 컨테이너 연결

  • -v /webdata:/usr/share/nginx/html:ro : 호스트머신 /webdata를 컨테이너의 /usr/share/nginx/html로 볼륨 마운트

root@svr-ubuntu-docker:/webdata# docker run -d --name web02 -p 80:80 -v /webdata:/usr/share/nginx/html:ro nginx:latest Unable to find image 'nginx:latest' locally latest: Pulling from library/nginx 61320b01ae5e: Pull complete 670a101d432b: Pull complete 405bd2df85b6: Pull complete cc80efff8457: Pull complete 2b9310b2ee4b: Pull complete 6c4aa022e8e1: Pull complete abddc69cb49d: Pull complete Digest: sha256:fb39280b7b9eba5727c884a3c7810002e69e8f961cc373b89c92f14961d903a0 Status: Downloaded newer image for nginx:latest ed7513fb8ec7e43319d3a1dc21b0b24914dd9e22d4f139d51d48f8b9786dd9b9
  • 웹 접속 확인

image-20250604-053546.png
  • ReadOnly이므로 컨테이너에서 수정 행위가 불가능함

image-20250604-054131.png

 

  1. 컨테이너 간 볼륨 공유하기

image-20250604-062829.png

 

  • 10초마다 df 결과를 출력하는 스크립트 작성

root@svr-ubuntu-docker:/# mkdir /dftest root@svr-ubuntu-docker:/# cd/dftest root@svr-ubuntu-docker:/dftest# cat df.sh #!/bin/bash # Bash 셸 사용 선언 mkdir -p /webdata # /webdata 디렉토리 생성 (이미 있어도 에러 없음) while true # 무한 루프 시작 do df -h / > /webdata/index.html # 루트 디스크 사용량을 /webdata/index.html에 덮어씀 sleep 10 # 10초 대기 done

 

  • dockerfile 생성 및 docker build

    • Docker 이미지로 컨테이너를 실행하면 자동으로 /bin/df.sh가 실행됨

root@svr-ubuntu-docker:/dftest# cat dockerfile FROM ubuntu:18.04 ADD df.sh /bin/df.sh RUN chmod +x /bin/df.sh ENTRYPOINT ["/bin/df.sh"] root@svr-ubuntu-docker:/dftest# docker build -t gekimkge/df:latest .

 

  • 컨테이너 실행 및 결과 확인

root@svr-ubuntu-docker:/dftest# docker run -d -v /webdata:/dftest --name df gekimkge/df:latest d27430cfd2ee20928b8a57e4011eaaf43e4cdf9c8d0fc721977535120f036648 root@svr-ubuntu-docker:/dftest# cat /webdata/index.html Filesystem Size Used Avail Use% Mounted on overlay 29G 5.7G 24G 20% /
image-20250604-063356.png