[부트캠프 - 31일차] 2/3.화 - Docker

developowl·2026년 2월 4일

부트캠프

목록 보기
22/29
post-thumbnail

2. Docker_Command

Docker Image Command

레이어란?

도커 이미지는 한꺼번에 만들어지는 통짜 파일이 아니라, Dockerfile 에 적힌 명령어를 한 줄 실행할 때마다 생성되는 중간 저장 단계들의 집합. 이때의 중간 저장 단계들을 레이어라고 함.

  • 특징
    • 불변성 (Read-only)
      • 이미 완성된 레이어는 절대로 수정되지 않음. 수정이 필요하면 그 위에 새로운 레이어를 쌓는 방식
    • 공유 (Sharing)
      • 여러 개의 이미지가 똑같은 베이스 레이어(ex: 우분투 OS 레이어)를 사용한다면, 저장 공간에는 하나만 저장하고 서로 공유해서 용량을 아낌
    • 캐싱 (Caching)
      • 이미지를 다시 빌드할 때 변경되지 않은 레이어는 그대로 재사용하기 때문에 빌드 속도가 빨라짐

docker image history 이미지이름

  • 이미지 구성을 위해서 사용된 레이블 정보와 레이어의 수행 명령, 크기 등을 조회
  • 레이어는 재사용 가능
# 이미지 다운로드
docker pull httpd # (docker.io/library/httpd:latest)

# 이미지 확인
docker image history httpd
	# 출력되는 결과에서 CREATED BY 열이 이미지를 구성하기 위한 명령
	
# debian 의 최신 이미지를 다운로드
docker pull debian
	# 다운로드 받을 때 보면 httpd 가 레이어가 더 많음
	

Docker 유니언 파일 시스템

  • 불변의 읽기 전용 레이어들의 집합 구조인 파일 시스템
  • 이미지의 종류는 크게 3가지
    • 운영체제 (ex: debian)
    • Middleware (ex: httpd - apache web server)
    • Application
  • 맨 위에 읽고 쓰기 레이어를 추가해서 컨테이너를 만들었을 때 변경을 할 수 있도록 함

Docker Hub 에 업로드

  • Docker Hun 로그인 관련 명령
  • 비밀번호 대신 토큰을 사용하는 것이 좋음
docker login
docker logout

Image 이름과 태그

  • 도커의 태그는 Registry에 업로드를 상정한 Image 이름
# 기본 형식
저장소 주소/레포지토리이름:버전

# 태그 이름 부여
docker tag 원본이미지ID 변경할이름

# 업로드
docker push 이름
  • 실습
# 이미지 확인
docker images

# 기존 이미지를 이용해서 새로운 이미지 생성
docker image tag 05813aedc15f test1
docker image tag hello-world:latest test2

# 업로드 하기 위한 이름 생성
docker image tag httpd:latest 레포지토리이름(도커허브이름)/myhttpd:2.0

# 업로드
docker push 레포지토리이름(도커허브이름)/이미지이름:버전

Docker Image를 파일로 관리

  • 확장자는 tar (Tape Archiver)

  • 저장

    • docker image save [option] Image_이름 > 파일_경로
  • 로드

    • docker image load < 파일_경로
  • 실습

# 1. eclipse/mysql:latest 다운로드
docker image pull eclipse/mysql:latest

# 2. test-mysql57.tar 파일로 저장 (리다이렉션 대신 -o 옵션 권장)
docker image save -o test-mysql57.tar eclipse/mysql:latest

# 3. 로컬에 저장된 eclipse/mysql:latest 이미지 삭제
# (이미지 ID가 같은 test1, test2 등이 있다면 -f 옵션이 필요할 수 있습니다)
docker image rm eclipse/mysql:latest

# 4. test-mysql57.tar 파일로부터 이미지 로드 (리다이렉션 대신 -i 옵션 권장)
docker image load -i test-mysql57.tar
  • 용량을 줄이고자 할 때는 tar 뒤에 .gz를 추가

이미지 삭제

# 이미지 삭제
docker image rm 이미지이름
docker rmi 이미지이름

# 전체 이미지 삭제
docker rmi $(docker images -q)

# 필터링 해서 삭제
docker rmi $(docker images -q | grep 패턴)
docker rmi $(docker images -q | grep -v 패턴)

# 사용하지 않는 이미지 삭제
docker image prune -a

Docker Container Command

Container로 애플리케이션 실행

  • 이미지는 읽기 전용의 불변 값으로 만들어지는데 이러한 이미지를 바탕으로 Docker 엔진은 읽고 쓰기 가능한 레이어를 추가해서 컨테이너를 생성
  • 컨테이너 관련 명령도 docker daemon이 제공하는 docker cli API 를 통해서 수헹
  • 명령 대부분이 서비스 실행 및 운영과 관련이 있음

Container는 Process

  • Docker Container는 Docker Image를 기반으로 하는 snapshot
  • ⭐️ snapshot은 읽기 전용의 Docker Image Layer를 복제한 것이고 그 위에 읽고 쓰기가 가능한 컨테이너 레이어를 결합한 것이 컨테이너
  • 컴퓨터 애플리케이션의 동작은 프로세스를 통해 이루어지는데 컨테이너는 격리된 공간에서 프로세스가 동작하는 기술
  • 컨테이너는 바로 프로세스 격리 기술(namespace, cgroup, chroot) 의 표준으로 정의된 OCI로 컨테이너 포맷과 런타임에 대한 개방형 업계 표준을 만들기 위한 목적으로 LFX의 지원을 받아 구성된 프로젝트
  • 명령어 docker run~ 을 사용하면 컨테이너가 동작하게 되고 가상의 격리 환경에 독립된 프로세스기 동작하는데 서버 호스트 운영체제가 독립적으로 동작하는 것과 유사
  • 리눅스 호스트 운영체제를 부팅하면 PID 1번은 init(systemd) 프로세스가 동작하며 이 프로세스는 나머지 모든 시스템 프로세스의 부모 프로세스가 됨
  • 컨테이너 내부로 입장을 하게 되면 관리자 권한을 가짐
  • 명령어를 수행할 때 sudo를 붙일 필요가 없음

이미지 다운로드와 컨테이너 생성

# gihyodocker/echo:latest 이미지 다운
docker pull hashicorp/http-echo
# 이미지를 컨테이너로 실행
docker run -p 9000:5678 hashicorp/http-echo -text="hello world"
  • docker run 명령을 내리면 해당 Docker 이미지 복사본 스냅샷 레이어 위에 읽고 쓰기가 가능한 컨테이너 레이어를 추가한 뒤 docker start 명령으로 컨테이너를 시작n
  • 실행된 컨테이너를 조회 → docker ps
    • ps(Process Status) 는 리눅스 호스트에서 실행 중인 프로세스를 조회하는 명령

컨테이너 수동 제어

# 이미지 다운로드
docker pull ubuntu:14.04

# 컨테이너 생성
docker create -it --name 컨테이너이름 이미지이름 # -it 옵션은 터미널 실행
docker create -it --name container-test1 ubuntu:14.04

# 컨테이너 확인
docker ps      # 실행 중인 컨테이너 확인
docker ps -a   # 모든 컨테이너 확인

# 컨테이너 실행
docker start container-test1

# 컨테이너 접속
docker attach container-test1

# 컨테이너 중지
docker stop container-test1

# 컨테이너 삭제
docker rm container-test1

## 컨테이너 접속까지 한 번에 수행
docker run -it --name container-test1 ubuntu:14.04 bash

Docker Container의 생명 주기

실행 상태

  • docker run 명령의 인자로 지정된 도커 이미지를 기반으로 컨테이너가 생성되면 이 이미지를 생성했던 Dockerfile에 포함된 CMD 및 ENTRYPOINT 인스트럭션에 정의된 명령을 수행하며 이 명령이 실행 중인 상태가 Container의 실행 중 상태가 됨
  • 일반적인 서버 애플리케이션은 오류가 발생하지 않는다면 계속 실행할 것이고 일반 애플리케이션의 경우는 자신의 작업이 종료되면 컨테이너가 정지 상태가 됨

정지 상태

  • 실행 중인 상태에 있는 컨테이너를 사용자가 명시적으로 정지하거나 컨테이너에서 실행된 애플리케이션이 정상/오류 여부를 막론하고 종료된 경우에는 컨테이너가 자동으로 정지 상태가 됨
  • 컨테이너를 정지시키면 가상 환경으로는 더 이상 동작하지 않지만 디스크에 컨테이너가 종료되던 시점의 상태가 저장돼 남기 때문에 정지시킨 컨테이너를 다시 실행할 수 있음
  • 정지 상태에서는 run 명령을 수행할 수 없음
    • run은 항상 컨테이너를 새로 만드는데, 새로 만들 때 동일한 이름의 컨테이너는 만들 수 없음

파기 상태

  • 컨테이너를 삭제하면 파기 상태
  • 한 번 파기하면 이전과 동일한 상태를 가진 컨테이너를 다시 생성할 수 없음

docker run

  • docker image pull + docker container create + docker container start + command 의 기능을 하나로 합친 명령으로 image를 다운로드 한 상태가 아니라면 먼저 이미지를 내려 받은
docker run [option] 이미지 [인자]
  • 인자
    • 이미지 종류에 따라 달라짐
    • MySQL 같은 경우는 로그인에 사용할 아이디나 패스워드, 인코딩이나 정렬 순서를 인자로 받는 경우도 있고 미리 로그인할 아이디 같은 것들은 생성한 상태에서 만들어지기도 함
  • 옵션
    • --name 컨테이너 이름
      • 컨테이너 이름을 지정하는 것으로 미지정시 자동으로 부여
    • -p [Host Port]:[Container Port]
      • 컨테이너 포트를 호스트 포트로 Port Forwarding , 외부에서 접근할려면 포트포워딩을 이용할 수 있음
    • -P, --publish-all=[true|false]
      • Dockerfile 에서 EXPOSE로 노출한 포트를 임의의 포트에 연결할 것인지 설정
    • -v, --volume=호스트경로:컨테이너경로
      • 볼륨 마운트, 컨테이너 내부의 경로와 호스트 경로를 매핑헤서 데이터를 저장하거나 읽기 위해서 사용
    • --net
      • 네트워크 연결
    • -i , --interface
      • 대화식 모드로 연결
    • -t
      • 단말 디바이스 할당
      • i 와 t 는 외부에서 컨테이너 내부로 접속하고자 할 때 사용
      • ⭐️ -it 와 같이 둘은 항상 같이 사용
    • -d , --detach=true
      • 백그라운드에서 실행, 서버용 애플리케이션은 이 옵션이 필수
    • -e , --env
      • 환경 변수 지정
    • --rm
      • 컨테이너 종료 시 자동 삭제
    • --restart [no | on-failure | on-failure 횟수 | always]
      • 컨테이너가 종료될 때 재시작 정책
    • -h 컨테이너의 호스트 이름
      • 컨테이너의 이름을 설정하는 것으로 설정하지 않으면 컨테이너 아이디가 이름이 됨
    • --link=[컨테이너이름:컨테이너아이디]
      • 동일 호스트의 다른 컨테이너와 연결 설정으로 IP가 아닌 컨테이너 이름을 이용해 통신

한 번만 실행되는 컨테이너와 데몬 형태로 동작하는 컨테이너

  • -d 는 컨테이너를 백그라운드로 실행하는 옵션이고 -I , -t 는 컨테이너 내부에 터미널로 접속하기 위해 사용하는 옵션
  • -d 를 붙이지 않고 컨테이너를 실행하면 실행된 컨테이너가 프로그램의 실행을 마칠 때까지 터미널의 제어를 차지하므로 그 다음 명령을 입력할 수 없는 상태가 되며 -i , -t 옵션을 붙이지 않으면 컨테이너 안의 파일 시스템에 접근할 수 없음
  • 한 번만 실행되는 컨테이너는 실행하자마자 종료되므로 컨테이너가 터미널의 제어를 차지하더라도 일시적인 것이므로 문제가 되지 않음
  • 데몬처럼 계속적으로 실행되는 프로그램은 저절로 종료되지 않으므로 한번 터미널의 제어를 넘기면 이를 되찾아 오기가 번거로움
  • 컨테이너 속 파일 시스템을 다루려면 -i 또는 -t 옵션을 사용해야 하지만 실행하자마자 곧장 종료되는 컨테이너라면 컨테이너 속 파일 시스템에 손을 댈 일도 없으므로 불필요한 옵션

docker ps

  • 컨테이너를 확인하는 명령
  • -a 옵션을 이용하면 모든 컨테이너를 확인하는 것이 가능
  • 내용
    • CONTAINER ID : 컨테이너 아이디
    • IMAGE : 이미지 이름
    • COMMAND : 컨테이너가 실행이 될 때 수행하는 명령
    • CREATED : 생성 후 경과된 시간
    • STATUS : 현재 상태로 Up이면 정상 수행이고, Exited 이면 종료 상태
    • PORTS : 포트포워딩 내용
    • NAMES : 컨테이너 이름

실행 중인 Container 중지 및 삭제

# 실행 중인 컨테이너 중지
# 특정 컨테이너 중지
docker stop 컨테이너ID 또는 컨테이너이름

# 모든 컨테이너 중지
docker stop $(docker ps -a -q)

# 컨테이너 삭제
# 특정 컨테이너 삭제
docker rm 컨테이너ID 또는 컨테이너이름

# 모든 컨테이너 삭제
docker rm $(docker ps -a -q)

Apache 컨테이너를 이용한 웹 서버 생성

  • 이미지 이름은 httpd(리눅스에 아파치 웹 서버가 설치된 이미지)
  • 컨테이너 생성
docker run [옵션] 이미지이름 [인자]
# 웹 서버이므로 - 옵션은 필수

# 컨테이너 생성 및 실행
docker run -d --name apa000ex1 httpd

# 컨테이너 실행 상태 확인
docker ps

# 컨테이너 정지
docker stop apa000ex1

# 컨테이너 삭제
docker rm apa000ex1

nginx 이미지를 이용한 컨테이너 생성

# 이미지 검색
docker search nginx

# 이미지 다운로드
docker pull nginx

# 컨테이너 생성
docker run -d --name webserver1 nginx
  • curl http://localhost:80 명령을 수행해도 다운로드 되지 않음

  • 포트포워딩

    • 호스트 머신의 포트를 컨테이너 포트와 연결해서 컨테이너 외부에서 온 통신을 컨테이너 포트로 전달하는 것
    • p 옵션과 호스트포트:내부포트 를 이용해서 수행
# 아파피 웹 서버는 80번 포트를 개방
docker run -d -p 8080:80 --name apa000ex2 httpd

# curl http://localhost:80 으로 다운로드 시도
curl http://localhost:8080

다양한 컨테이너

  • 리눅스 운영체제가 담긴 컨테이너

    • ubuntu
    • centos
    • debian
    • fedora
    • busybox
    • alpine
  • 웹 서버 및 데이터베이스 서버용 컨테이너

    • httpd : 아파치 웹 서버
    • nginx : nginx 웹 서버
    • mysql
    • postrgres
    • mariadb
  • 프로그래밍 언어의 런타임 컨테이너

    • openjdk
    • python
    • php
    • ruby
    • perl
    • cc
    • node
    • registry : 도커 레지스트리 생성 시 필요
    • wordpress : MySQL 이나 MariaDB 필요
    • nextcloud
    • redmine : MySQL 이나 MariaDB 필요

웹 서비스 실행을 위한 nginx 컨테이너 실행

# 이미지 다운로드
docker pull nginx

# 컨테이너 실행
docker run --name webserver1 -d -p 8001:80 nginx

# 컨테이너 확인
docker ps

# 컨테이너의 리소스 사용량 실시간 확인
docker stats webserver1

# 컨테이너의 실행 중인 프로세스 확인
docker top webserver1

# 컨테이너의 접근 로그를 Docker 명령으로 확인
docker logs -f webserver1

# 컨테이너 중지
docker stop webserver1

# 컨테이너 실행
docker start webserver1
  • 관련 명령어
# 실행 중인 Container를 제외한 모든 Container 파기
docker container prune

# 사용하지 않는 Docker image 및 컨테이너, 볼륨, 네트워크 등 
# 모든 도커 리소스를 일괄적으로 삭제
docker system prune

# 사용 현황 확인
docker container stats

컨테이너와 호스트 간의 공유

컨테이너와 호스트 간에 파일 복사

docker cp 호스트경로 컨테이너이름:컨테이너경로

docker cp 컨테이너이름:컨테이너경로 호스트 경로

# 컨테이너 생성
docker run --name apa000ex19 -d -p 8089:80 httpd

# 컨테이너에서 호스트로 파일을 복사
docker cp apa000ex19:/usr/local/apache2/htdocs/index.html index.html
	# 현재 디렉토리에 index.html 파일이 생성됨
	
# 현재 디렉토리에 있는 index.html 파일 수정

# 호스트에서 컨테이너로 파일을 복사
docker cp index.html apa000ex19:/usr/local/apache2/htdocs/index.html

Container로 애플리케이션 실행

파이썬 실행 환경

# 현재 디렉토리에 lotto.py 파일을 생성

# 파이썬 컨테이너 실행
docker run -it -d --name=python_test -p 8900:8900 python

# 파일 복사
docker cp lotto.py python_test:/

# 컨테이너에 명령 수행
docker exec -it python_test bash

# 파이썬 확인
python

# 파이썬 종료
exit()

# 파이썬 관련 도구 확인
pip list

# 파이썬 모듈 확인
python -c 'help("modules")'

# 외부로 나가기
exit

# 외부에서 파이썬 컨테이너 코드 실행
docker exec -it python_test python /lotto.py
profile
Don’t get mad at the computer.

0개의 댓글