[부트캠프 - 32일차] 2/4.수 - Docker

developowl·2026년 2월 4일

부트캠프

목록 보기
23/29
post-thumbnail

Docker Command

Docker 볼륨 활용

볼륨 마운트

  • 볼륨 (Volume)

    • 스토리지의 한 영역을 분할한 것
  • 마운트 (Mount)

    • 스토리지의 영역과 파일 시스템을 연결해서 운영체제에서 사용할 수 있도록 한 것
  • Docker는 유니언 파일 시스템을 사용하는데 하나의 이미지로부터 여러 컨테이너를 만들 수 있는 방법을 제공하고 이미지에 변경된 내용을 저장할 수 있도록 해주는데 데이터베이스, 웹 프로그램 등 업무에서 사용하는 애플리케이션에서 발생하는 데이터에 접근하고 이것을 공유하기 위해서 Docker 볼륨 기능을 사용할 수 있으며 제공하는 서비스의 데이터와 로직은 반드시 분리되어야 하기 때문에 애플리케이션에서 발생하는 여러 가지 상황이 데이터에 영향을 주지 않고 언제든 다른 컨테이너로 이전할 수 있다면 운영자는 데이터를 안전하게 관리하고 운영하는 것이 가능

  • Docker 볼륨은 컨테이너에서 생성, 재사용할 수 있고 호스트 운영체제에서 직접 접근이 가능

  • 보존되어야 하는 데이터를 유지(데이터 영속성과 지속성)하기 위한 메커니즘을 제공

  • 일반적으로 컨테이너 내부의 데이터는 컨테이너의 라이프사이클과 연관되어 컨테이너 종료 시 삭제되는데 이를 영속적으로 유지하기 위한 방법으로 Docker 볼륨을 사용하면 컨테이너가 삭제되어도 볼륨은 독립적으로 운영되기 때문에 함께 삭제되지 않는 특징이 있음

마운트 방식

  • Volume Mount
    • 도커 엔진이 관리하는 영역 내에 만들어진 볼륨을 컨테이너에 디스크 형태로 마운트 하는 방식
  • Bind Mount
    • Docker가 설치된 컴퓨터의 디렉토리를 컨테이너에 마운트 하는 방식
    • 파일 단위로도 가능
항목볼륨 마운트바인드 마운트
스토리지 영역볼륨디렉터리 또는 파일
물리적 위치도커 엔진의 관리 영역어디든지 가능
마운트 절차볼륨을 생성한 후 마운트기존 파일 또는 폴더를 마운트
내용 편집도커 컨테이너를 통해서일반적인 파일과 같이
백업절차가 복잡함일반적인 파일과 같이

볼륨 마운트

  • 볼륨 마운트 영역 생성 및 삭제

    • docker volume create 이름
    • docker volume rm 이름
  • 마운트 절차

    • 스토리지를 마운트 하려면 먼저 마운트 될 스토리지를 생성해야 함
    • 볼륨 마운트의 경우는 마운트와 동시에 볼륨(스토리지 영역)을 만들 수도 있지만 권장하지 않음
  • 볼륨 마운트 명령

    • docker run -v 볼륨이름:컨테이너_마운트_경로
  • 실습(볼륨 생성 및 컨테이너와 연결)

# 볼륨 생성
docker volume create my-appvol-1

# 볼륨 확인
docker volume ls

# 볼륨 검사
docker volume inspect my-appvol-1

# 컨테이너와 연결
# 기존 볼륨과 연결
docker run -d --name vol-test1 -v my-appvol-1:/var/log ubuntu

# 볼륨을 만들면서 연결
docker run -d --name vol-test2 -v my-appvol-2:/var/log ubuntu

# 볼륨 확인
docker volume ls
  • 실습(볼륨 제거)
# 볼륨 제거
docker volume rm my-appvol-1
# ! 볼륨을 컨테이너가 사용 중이면 제거 불가능

# 컨테이너를 중지
docker stop vol-test1 vol-test2

# 컨테이너를 삭제
docker rm vol-test1 vol-test2

# 볼륨을 제거
docker volume rm my-appvol-1 my-appvol-2

바인드 마운트

  • 볼륨 마운트에 비해서 사용이 제한적

  • 호스트 파일 시스템 절대경로:컨테이너 내부 경로 를 직접 마운트하여 사용

  • 사용자가 파일 또는 디렉토리를 생성하면 해당 호스트 파일 시스템의 소유자 권한으로 연결이 되고 존재하지 않는 경우 자동 생성

  • 자동 생성된 디렉토리는 루트 사용자 소유

  • 컨테이너 실행 시 지정하여 사용하고 컨테이너 제거 시 바인드 마운트는 해제되지만 호스트 디렉토리는 유지

  • 바인드 마운트 명령

    • docker run -v 스토리지_실제_경로:컨테이너_마운트_경로
  • 실습(httpd 이미지의 /usr/local/apache2/htdocs 디렉토리와 /home/adam/docker/bindmount 디렉토리와 바인드 마운트)

docker run --name apa_01 -d -p 8080:80 -v /home/developowl/bindmount:/usr/local/apache2/htdocs httpd

# 확인
curl http://localhost:8080
	# Index of 가 출력됨

# 컨테이너 중지
docker stop apa_01

# 컨테이너 삭제
docker rm apa_01
  • 마운트를 할 때 :ro 를 추가하면 읽기만 가능하고 :rw 를 추가하면 읽고 쓰기 가능

tmpfs mount

  • 일시적으로 마운트 하는 것으로 호스트 메모리에만 지속되는 데이터를 활용하고자 하는 경우 사용
  • 컨테이너 실행 시 지정하여 사용하고 컨테이너 제거 시 자동 해제
  • --tmpfs 컨테이너 내부 경로 를 추가해서 컨테이너를 생성하면 됨
    • docker run -dit —-name tempfs /var/www/html httpd:2

MySQL 영속성 유지

# 볼륨 생성
docker volume create mysql-data-vol

# 볼륨 확인
docker volume ls

# 볼륨과 연결해서 MySQL 5.7 실행
docker run -it --name=mysql-vtest -e MYSQL_ROOT_PASSWORD=wnddkd -e MYSQL_DATABASE=dockertest -v mysql-data-vol:/var/lib/mysql -d mysql

	# MAC에서 실행이 안 되면 옵션 추가
	--platform linux/amd64

# MySQL 컨테이너 접속
docker exec -it mysql-vtest bash

# 루트 접속
mysql -uroot -pwnddkd dockertest

# 데이터베이스 작업
create table mytable(c1 int, c2 char(100));

insert into mytable values(1, 'adam');

exit

# 데이터 확인
ls /var/lib/mysql/dockertest/
  • 컨테이너 삭제 후 이전과 동일한 방법으로 컨테이너를 생성하고 테이블이 계속 유지되는지 확인

웹 서비스의 로그 정보 보호 및 분석을 위한 바인드 마운트 설정

  • 실습
# 로그 정보를 저장할 nginx-log 디렉토리 생성
mkdir nginx-log
	# nginx의 로그는 /var/log/nginx 디렉토리에 저장됨

# 경로 확인
pwd
	# /home/developowl/nginx-log

# nginx 컨테이너를 생성하는데 로그 디렉토리와 호스트 운영체제의 디렉토리를 마운트 해서 생성
docker run -d -p 8011:80 -v /home/developowl/nginx-log:/var/log/nginx nginx 

# 확인(접속)
curl http://localhost:8011

# 바인딩 된 디렉토리 확인
ls

파일 시스템 마운트의 한계

  • 컨테이너의 마운트 대상 디렉토리가 있고, 이미지 레이어에 이 디렉토리의 파일이 포함되어 있는 경우 이미 존재하는 대상 디렉토리에 마운트하면 원본 디렉토리가 기존 디렉토리를 완전히 대체해서 이미지에 포함되어 있던 원래 파일을 사용할 수 없음
  • 호스트 컴퓨터의 파일 하나를 컨테이너에 이미 존재하는 디렉토리로 마운트 하는 경우 디렉토리의 파일이 합쳐져 이미지에서 온 파일과 호스트에서 마운트 된 파일이 모두 나타나게 되는데 호스트 컴퓨터가 윈도우인 경우는 이 기능을 제공하지 않음

여러 개의 컨테이너 연동

Docker Network

  • Docker 컨테이너 및 서비스는 Docker 네트워크를 통해 격리된 컨테이너 간의 네트워크 연결뿐만 아니라 Docker 외의 다른 애플리케이션 워크로드 와도 연결이 가능
  • Docker 설치 시 기본적으로 제공되는 docker0는 소프트웨어적으로 구현된 가상 이더넷 브릿지(virtual ehternet bridge) 네트워크이고 이것을 통해 격리된 컨테이너들의 상호 간 통신을 제공
  • 별도의 브릿지 네트워크를 생성하여 연결 값으로 설정하지 않는 한 실행되는 모든 컨테이너는 docker0 브릿지에 연결되어 172.17.0.0/16 의 CIDR(Classless Inter-Domain Routing) 범위로 IP 주소가 할당되는데 /16은 최대 65,536 개의 IP 주소 범위를 소유

네트워크 인터페이스

  • enp0s8
    • Ubuntu 리눅스의 네트워크 카드로 오라클 VirtualBox 에서 제공하는 IP 주소를 할당받아 사용 중(centos 에서는 ens33 등의 이름을 사용)
  • docker0
    • Docker 설치 시 기본적으로 제공되는 브릿지 네트워크로 172.17.0.1 주소를 갖고 docker0 브릿지는 소프트웨어적인 스위치 방식으로 동작하며 일반적인 스위치 방식과는 다르게 DHCP로 연결된 컨테이너에 사전에 정의된 IP 풀을 할당
  • vethxxxxxxx
    • OSI 7 계층 서비스 모델의 2계층 서비스로 컨테이너 내부에 제공되는 네트워크 인터페이스 eth0 와 한 쌍으로 제공되어 docker0 와 가상의 터널링 네트워크를 제공
  • eth0
    • Docker 컨테이너에 생성되는 기본 네트워크 인터페이스명으로 docker0를 게이트웨이로 사용하는데 순차적으로 IP 주소를 할당받거나 사용자가 동일 대역의 IP 주소를 지정할 수 있다.

기본 브리지 네트워크 모드

# Docker 네트워크 드라이버 방식 조회
docker network ls

# 전체 네트워크 조회
docker network inspect bridge

# ubuntu 이미지 실행
docker run -dit --name container1 ubuntu:20.04
docker run -dit --name container2 ubuntu:20.04

# 컨테이너 생성 후 IP Address 확인
docker inspect container1 | grep IPAddress

웹 서비스를 제공하는 nginx 컨테이너가 브릿지 모드의 네트워크와 연결되는 과정

# 컨테이너 생성
docker run -d --name=nginx-net -p 8080:80 nginx

# 확인
curl http://localhost:8080
docker ps
  • 윈도우 웹 브라우저에 http://호스트IP:연결된포트 입력을 통해 접속
  • 호스트 운영체제에 8080 포트가 열려 있음을 확인하고 해당 포트가 연결된 컨테이너를 찾음
  • 해당 컨테이너가 연결된 브리지 네트워크의 프라이빗 IP(172.17.0.2) 와 포트 번호로 사용자가 입력한 외부 IP와 포트 번호가 변환
  • 이때 사용되는 서비스가 네트워크 주소 포트 변환이고, NAT에서는 발신자의 사설망 to 외부망 IP 를 변환해 주는 역할만 수행했다면, 여기에 포트까지 바꿔서 보내는 역할을 수행

워드프레스 구축

워드프레스

  • 웹 사이트를 만들기 위한 소프트웨어로 서버에 설치해 사용
  • 워드프레스는 워드프레스 프로그램 외에도 Apache 나 데이터베이스, PHP 런타임 등을 필요로 함
  • 워드프레스는 MySQL 및 MariaDB 를 지원
  • 컨테이너는 워드프레스 공식 Image를 사용
  • 이 Image는 워드프레스 프로그램 본체와 Apache, PHP 런타임을 함께 포함하고 있어서 매우 편리한데 이 컨테이너와 MySQL 컨테이너가 있으면 워드프레스를 사용할 수 있음
  • 데이터베이스 서버를 꼭 컨테이너가 아니더라도 Docker 외부에 두는 방식도 가능

Docker 네트워크 생성/삭제

  • 워드프레스는 워드프레스 컨테이너와 MySQL 컨테이너로 구성

  • 워드프레스는 간단히 말해 블로그 생성 도구와 같은 것으로 웹 사이트 작성자가 작성한 내용을 데이터베이스에 저장하고 웹 사이트 열람자의 요청에 따라 웹 페이지를 보여주는데 프로그램이 MySQL에 저장된 데이터를 읽고 쓸 수 있어야 하기 때문에 두 컨테이너가 연결돼 있어야 함

  • 컨테아너를 두 개 만들기만 해서는 두 컨테이너가 연결되지 않으므로 가상 네트워크를 만들고 이 네트워크에 두 개의 컨테이너를 소속시켜 두 컨테이너를 연결

  • 가상 네트워크를 만드는 커맨드가 docker network create 로 커맨드 위로 네트워크 이름을 기재하면 됨

  • container 또는 image 상위 커맨드와 마찬가지로 네트워크를 삭제할 때는 docker network rm, 네트워크 목록을 출력할 때는 docker network ls 커맨드를 사용

  • 네트워크 관련 커맨드

    • connect
      • 네트워크에 컨테이너를 새로이 접속
    • disconnect
      • 네트워크에서 컨테이너의 접속을 끊음
    • create
      • 네트워크를 생성
    • inspect
      • 네트워크의 상세 정보를 확인
    • ls
      • 네트워크의 목록을 확인
    • prune
      • 현재 아무 컨테이너도 접속하지 않은 네트워크를 모두 삭제
    • rm
      • 지정한 네트워크를 삭제

MySQL

  • 컨테이너 실행, 컨테이너 생성

    • docker run --name 컨테이너이름 –dit -p 외부접속포트번호:MySQL포트번호 -e MYSQL_ROOT_PASSWORD=root비밀번호 –e MYSQL_DATABASE=데이터베이스_이름 –e MYSQL_USER=MYSQL_사용자이름 –e MYSQL_PASSWORD=MySQL_패스워드 -p 소호스트포드번호:컨테이너포트번호 mysqlImage이름 --charaterset-set-server=문자_인코딩 --collation-server=정렬순서
  • 컨테이너에 명령 수행

    • docker exec -it 컨테이너이름 bash
  • MySQL 8.0 명령어

    • 루트 접속
      • mysql -u root –p 명령 실행 후 root 비밀번호 입력
    • 데이터베이스 생성
      • create database user00;
    • 사용자 생성 및 비밀번호 설정
      • create user 'user00'@'%' identified by 'user00’;
        • 데이터베이스 이름 대신에 .을 대입하면 모든 데이터베이스 사용 가능
        • %대신에 ip를 기재하면 특정 ip에서만 접속이 허용되며 localhost로 지정하면 현재 컴퓨터에서만 접속이 가능
    • 권한 부여
      • grant all privileges on *.* TO 'user00'@'%’;
    • 변경 내용 적용
      • FLUSH privileges;

워드프레스 구축

MySQL 컨테이너 실행 시에 필요한 옵션과 인자

# 컨테이너 생성 및 실행
docker run --name 컨테이너이름 \
  -dit \
  --net=네트워크이름 \
  -e MYSQL_ROOT_PASSWORD=root비밀번호 \
  -e MYSQL_DATABASE=데이터베이스_이름 \
  -e MYSQL_USER=MYSQL_사용자이름 \
  -e MYSQL_PASSWORD=MySQL_패스워드 \
  -p 호스트포트번호:컨테이너포트번호 \
  mysqlImage이름 \
  --character-set-server=문자_인코딩 \
  --collation-server=정렬순서
  • 사용된 옵션
    • --net
      • 컨테이너를 연결할 Docker 네트워크 나머지는 모두 -e 옵션으로 환경변수를 설정하기 위해 사용
    • 환경 변수
      • 운영체제에서 다양한 설정 값을 저장하는 장소를 가리키는 것으로
        컨테이너의 설정 값을 환경 변수를 통해 전달하는 경우가 많은데 어떤 환경 변수를 사용할지는 컨테이너의 종류에 따라 달라짐
    • 패스워드
      • 루트 패스워드와 일반 사용자 패스워드 두 가지를 설정
    • 루트는 모든 권한을 가진 사용자로 이 권한이 없으면 할 수 없는 작업이 있지만 매번 루트 사용자로 접속할 경우 보안 측면에서 문제가 생기기 때문에 제한된 권한을 가진 일반 사용자로 전환하는 것이 일반적

워드프레스 컨테이너 실행 시 필요한 옵션과 인자

# 컨테이너 생성 및 실행
docker run --name 컨테이너이름 \
  -dit \
  --net=네트워크이름 \
  -p 포트_설정 \
  -e W0RDPRESS_DB_HOST=데이터베이스_컨테이너_이름 \
  -e WORDPRESS_DB_NAME=데이터베이스_이름 \
  -e WORDPRESS_DB_USER=데이터베이스_사용자_이름 \
  -e WORDPRESS_DB_PASSWORD=데이터베이스_패스워드 \
  wordpress
  • 사용된 옵션

    • -e 옵션은 MySQL 접속과 관련된 옵션
  • 실습

# network create 커맨드로 네트워크 생성
docker network create wordpress000net1

# MySQL 컨테이너를 생성 및 실행
docker run --name mysql000ex11 \
	-dit \
	--net=wordpress000net1 \
	-e MYSQL_ROOT_PASSWORD=myrootpass \
	-e MYSQL_DATABASE=wordpress000db \
	-e MYSQL_USER=wordpress000kun \
	-e MYSQL_PASSWORD=wkunpass mysql \
	--character-set-server=utf8mb4 \
	--collationserver=utf8mb4_unicode_ci
	
# WordPress 컨테이너를 생성 및 실행
docker run --name wordpress000ex12 \
	-dit \
	--net=wordpress000net1 \
	-p 8085:80 \
	-e WORDPRESS_DB_HOST=mysql000ex11 \
	-e WORDPRESS_DB_NAME=wordpress000db \
	-e WORDPRESS_DB_USER=wordpress000kun \
	-e WORDPRESS_DB_PASSWORD=wkunpass \
	wordpress
	
# 컨테이너가 실행 중인지 확인
docker ps

# 확인
curl http://localhost:8085

# -----------

# 뒷 정리
# 워드프레스 컨테이너 중지
docker stop wordpress000ex12

# MySQL 컨테이너 중지
docker stop mysql000ex11

# 두 컨테이너 삭제
docker rm wordpress000ex12
docker rm mysql000ex11

# 네트워크 삭제
docker network rm wordpress000net1

Redmine 및 Maria DB 컨테이너

  • 오픈소스 프로그램으로 웹 기반의 프로젝트 관리와 버그 추적 기능을 제공하는 도구
  • 화면 기반의 프로젝트 관리에 도움이 되어 달력과 간트 차트를 제공하고 일정관리 기능을 제공

Dockerfile

이미지 생성 방법

  • 현재 실행 중인 컨테이너를 이미지로 생성
    • docker commit
  • Dockerfile 을 생성한 후 빌드해서 이미지를 생성

IaC(Infrastructure as Code - 코드형 인프라)

  • 수동으로 배포했을 때 문제점

    • 커맨드 기반의 인프라 구성 시 사용자 실수 등의 인적 오류 가능성이 높은데 APM(Apache + PHP + MySQL) 을 구축하는 경우 설치 순서와 상호 연관성 등을 고려하여 각종 라이브러리와 함께 복잡한 명령어를 고민해야 함
    • 각종 환경 설정 정보와 설치 프로그램을 요구사항에 맞게 살펴봐야 하는데 만일 설치 이후에 잘못된 설정이 있다면 수정해야 하고 때로는 재설치도 불가피
  • 개요

    • 수동 프로세스가 아닌 코드를 통해 인프라를 관리하고 프로비저닝 하는 것
    • IaC를 사용하면 인프라 사양을 담은 구성 파일이 생성되므로 구성을 편집하고 배포하기가 쉬워지고 동일한 환경을 프로비저닝 하도록 보장
    • IaC는 구성 사양을 코드화 하고 문서화함으로써 구성 관리를 지원하며 구성 변경 사항을 문서화하지 않고 임시로 변경하는 일을 막을 수 있음
    • 버전 제어는 IaC의 중요한 부분으로 다른 소프트웨어 소스 코드 파일과 마찬가지로 구성 파일도 버전 제어가 필요
    • 코드로 인프라를 배포한다는 것은 인프라를 모듈식 구성 요소로 분할하고 자동화를 통해 다양한 방식으로 결합할 수 있다는 의미
    • IaC를 인프라 프로비저닝을 자동화 하면 애플리케이션을 개발하거나 배포할 때마다 개발자가 직접 서버, 운영 체제, 스토리지, 기타 인프라 구성 요소를 수동으로 프로비저닝하고 관리할 필요가 없어지는데 인프라를 코드화하여 템플릿을 만들고 프로비저닝 할 때 이 템플릿을 사용하면 됨
    • 코드형 인프라 개발은 탄력성, 확장성, 반복성을 부여하여 눈송이 서버가 아닌 동일한 환경을 보유한 서버를 수십에서 수백 대까지 운영 관리하게 해주고 민첩성, 비용 효율적인 구성, 위험 감소와 같은 장점을 가짐
    • IaC 지원 도구로 Docker, Ansible, Kubernetes 등이 있음

Dockerfile

  • DockerImage를 생성하기(Application을 Packaging) 위한 스크립트(설정 파일)

  • 여러 명령어를 토대로 Dockerfile을 작성한 후 빌드하면 Docker는 Dockerfile에 나열된 명령문을 차례대로 수행하며 DockerImage를 생성

  • 장점

    • 이미지가 어떻게 만들어졌는지를 기록
    • 배포에 용이
    • 컨테이너(이미지)가 특정 행동을 수행하도록 할 수 있음
profile
Don’t get mad at the computer.

0개의 댓글