도커 컴포즈 개념

도커 컴포즈란 파일 하나로 여러 컨테이너를 생성하고 폐기할 수 있도록 하는 도구입니다.

만약 도커 컴포즈가 없다면, 일일이 커맨드를 입력해야 하는데 이를 한번에 해결해주는 도구이죠.

 


도커 컴포즈 vs Docker file, Kubernetes

Dockerfile 스크립트는 이미지 만드는 용도입니다. 네트워크나 볼륨을 생성할 수 없습니다.

그러나 도커 컴포즈 파일은 컨테이너를 비롯한 네트워크나 볼륨 등 주변 환경까지 포괄합니다.

앞서 말씀드렸듯, 여러 커맨드를 입력할 필요 없이 파일 하나로 해결해낼 수 있는 것입니다.

Kubernetes는 여러 컨테이너를 관리하는 도구입니다. 따라서 생성 및 폐기를 비롯한 관리 기능이 제공됩니다.

그러나 도커 컴포즈에는 컨테이너 관리 기능이 없습니다.

 


도커 컴포즈 사용 및 작동 원리

도커 컴포즈는 도커 엔진과 사용법이 대동소이합니다. 그러나 엄연히 별개의 소프트웨어입니다. 따라서 별도 설치가 필요합니다. 다만 리눅스 환경에서만 설치가 필요할 뿐, 윈도우나 MAC OS에선 필요치 않습니다. 이유는 Docker Desktop 설치 시 함께 설치되기 때문입니다.

도커 컴포즈의 파일 형식은 YAML 파일 형식으로, "파일이름.yml" 양식을 따릅니다.

파일은 호스트에 위치하며 도커 컴포즈가 이를 읽고 대신 커맨드를 입력해주는 방식으로 작동합니다. 단, 파일은 폴더에 하나만 있어야 합니다. 만약 여러 YAML 파일이 있다면 폴더를 각각 분리해야 합니다.

 


도커 컴포즈 커맨드

YAML 파일 커맨드 주요 커맨드로는 up, down이 있습니다.

도커 컴포즈 주요 커맨드: UP

up은 YAML 파일을 읽는 명령어입니다.

docker-compose -f C:\Users\user\Desktop\study\cloud\redmine-maria\docker-compose-red-maria.yml up

up 명령어 사용 시 주의해야할 점 2가지가 있습니다. 먼저, up 명령어는 YAML 파일을 한번 읽고 나면 끝입니다. 따라서 up 실행 이후 YAML 파일을 수정하더라도 동기화되진 않습니다. 마찬가지로, YAML 파일로 생성된 컨테이너의 설정을 변경하더라도 YAML 파일에 반영되지 않습니다. 다음으로, 도커 엔진에 생성되는 컨테이너 이름은 도커 컴포즈에 명시한 service 이름과 다르다는 점입니다. 도커 엔진에 생성되는 컨테이너 이름은 "leaf 폴더명_service에 명시한 컨테이너 이름_번호"로 생성됩니다. 예를 들어, C:\Users\user\Desktop\study\cloud\wordpress-maria\docker-compose-red-maria.yml에 대해 up 커맨드를 입력한 경우 생성되는 컨테이너 이름은 "wordpress-maria-${services에 명시한 컨테이너 이름}-1" 입니다.

번호는 YAML 파일이 여러 번 실행되면, 즉 같은 구성의 컨테이너 세트가 여러 개 생성되면 넘버링 형태로 붙습니다. 

docker-compose -f C:\Users\user\Desktop\study\cloud\redmine-maria\docker-compose-red-maria.yml up --scale maria_lim=2

*근데 여러 컨테이너를 만드는 도커 컴포즈에서 의존 관계와 맞지 않게 특정 컨테이너만 여러 개 생성하면, 장애가 날 가능성이 높습니다. 여러 컨테이너가 포트번호를 공유하는 것(포트 번호 중복)도 장애를 야기할 수 있습니다. 따라서 여러 세트의 컨테이너를 생성하는 경우 쿠버네티스 활용을 권장합니다.

 

도커 컴포즈 주요 커맨드: DOWN

down은 YAML로 실행된 컨테이너, 네트워크를 폐기하는 명령어입니다.

down 명령어에서 중요한 건 image와 volume은 삭제되지 않는다는 점입니다. 따라서 별도 폐기 작업이 필요합니다.

docker-compose -f C:\Users\user\Desktop\study\cloud\redmine-maria\docker-compose-red-maria.yml down

 

 


도커 컴포즈 파일 양식 및 예제

양식

version: "${버전}"

services:
  ${컨테이너 이름}:
    depend_on:
      - ${의존 컨테이너 이름}
    image: ${이미지 이름}
    networks:
      - ${네트워크 이름}
    ports:
      - ${클라이언트 요청하는 포트}:${리다이렉트되는 포트}
    restart: ${컨테이너 재시작 여부}
    #restart 설정 값: no, always, on-failure, unless-stopped
    environment:
      ${환경변수 이름}=${환경변수 값}

networks:
  ${네트워크 이름}:

volumes:
  ${볼륨 이름}:

 


mysql+wordpress

version: "3"

services:
  mysql000ex11:
    image: mysql
    networks:
      - wordpress000net1
    volumes:
      - mysql000vol11:/var/lib/mysql
    restart: always
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    environment:
      MYSQL_ROOT_PASSWORD: myrootpass
      MYSQL_DATABASE: wordpress000db
      MYSQL_USER: wordpress000kun
      MYSQL_PASSWORD: wkunpass
  wordpress000ex12:
    depends_on:
      - mysql000ex11
    image: wordpress
    networks:
      - wordpress000net1
    volumes:
      - wordpress000vol12:/var/www/html
    ports:
      - 8085:80
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: myrootpass
      MYSQL_DATABASE: wordpress000db
      MYSQL_USER: wordpress000kun
      MYSQL_PASSWORD: wkunpass

networks:
  wordpress000net1:

volumes:
  mysql000vol11:
  wordpress000vol12:

 

 

 


mysql+redmine

version: "1"

services:
  cloudlim_mysql:
    image: mysql
    networks:
      - cloudlim_net
    volumes:
      - cloudlim_vol1:/var/lib/mysql
    restart: always
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    environment:
      MYSQL_ROOT_PASSWORD: myrootpass
      MYSQL_DATABASE: cloudlimdatabase
      MYSQL_USER: cloudlim
      MYSQL_PASSWORD: limlim1234
  cloudlim_redmine:
    depends_on:
      - cloudlim_mysql
    image: redmine
    networks:
      - cloudlim_net
    volumes:
      - cloudlim_vol2:/usr/src/redmine/files
    ports:
      - 8086:3000
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: myrootpass
      MYSQL_DATABASE: cloudlimdatabase
      MYSQL_USER: cloudlim
      MYSQL_PASSWORD: limlim1234

networks:
  cloudlim_net:

volumes:
  cloudlim_vol1:
  cloudlim_vol2:


 

mariadb+redmine

version: "2"

services:
  maria_lim:
    image: mariadb
    networks:
      - net_lim
    volumes:
      - vol_lim1:/var/lib/mysql
    restart: always
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    environment:
      MYSQL_ROOT_PASSWORD: mariarootpw
      MYSQL_DATABASE: limdb
      MYSQL_USER: cloudlim
      MYSQL_PASSWORD: lim1234
  cloudlim_redmine:
    depends_on:
      - maria_lim
    image: redmine
    networks:
      - net_lim
    volumes:
      - vol_lim2:/usr/src/redmine/files
    ports:
      - 8087:3000
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: mariarootpw
      MYSQL_DATABASE: limdb
      MYSQL_USER: cloudlim
      MYSQL_PASSWORD: lim1234

networks:
  net_lim:

volumes:
  vol_lim1:
  vol_lim2:

 


 

출처

 

그림과 실습으로 배우는 도커 & 쿠버네티스 - 예스24

컨테이너나 도커를 도통 이해하기 어려운 분들을 위한 본격 도커 입문서!이 책은 컨테이너 기술이 어렵게 느껴지는 엔지니어나 백엔드 기술에 자신이 없는 분들을 위한 도커 입문서다. 자세한

www.yes24.com

 

 

1. Desktop에서 Docker Hub 로그인 및 리포지토리 생성

도커허브는 도커가 운영하는 공식 리지스트리이다.

이곳에서 개인이 리포지토리를 생성할 수 있다.

 

 

2.Dockerfile 생성

 

3. 도커 엔진에 이미지 업로드

docker build cloudlim C:\Users\user\Desktop\study\cloud

 

*t 옵션을 사용해 "계정명/리포지토리명:버전" 으로 빌드하면 바로 도커 허브로 업로드(push) 가능하다

*빌드는 됐는데 파이프라인에 문제 있는 것 같다는 메시지가 출력될 수도 있다. 그럴 땐 도커 엔진을 껐다 키면 해결된다.

 

4. 태그 생성

docker tag cloudlim lim0517sh/cloudlim:1

docker tag 명령어 입력 시, 해당 이미지에 태그가 달리는 것이 아닌 태그 달린 이미지가 생성되는 것이다.

docker images 또는 docker image ls로 확인해볼 수 있다.

 

5.  도커 허브 로그인

docker login

 

6. 도커 엔진 이미지를 도커 허브 리포지토리에 업로드

docker push lim0517sh/cloudlim:1

"계정명/리포지토리이름:버전" 양식으로 업로드하면 된다.

 

7. 도커 허브 확인

 

8. 도커 허브 이미지 다운로드

docker pull lim0517sh/cloudlim:1

"계정명/리포지토리명:버전" 양식으로 이미지를 pull한다.

컨테이너는 데이터와 프로그램을 독립 실행할 수 있는 공간

그래서 컨테이너끼리 통신하려면 네트워크 구축 필요

→ 네트워크 구축 후 mysql과 wordpress 컨테이너 배포

docker network create wordpress000net1

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 --collation-server=utf8mb4_unicode_ci --default-authentication-plugin=mysql_native_password

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

 

그리곤 브라우저를 통해 localhost:8085로 접속했으나 에러 발생

에러 메시지 "Error establishing a database connection"

 

컨테이너 상태 봤더니 mysql 상태가 exited

 

mysql 컨테이너 로그 확인(docker logs mysql000ex11)했더니 인식 안되는 환경변수(default-authentication-plugin)가 있음

 

그래서 걔 빼고 입력해봄

docker network create wordpress000net1

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 --collation-server=utf8mb4_unicode_ci

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 Desktop 설치 후 실습 진행

 

명령어 구조: docker + 커맨드(상위 커맨드 + 하위 커맨드) + 대상

근데 상위 커맨드는 종종 빼고 입력해도 됨(왜? 역사적인 이유로..걍 쓰다보니 그게 편해서 라는 거인듯)


Docker 설치 확인

 


기본실습1) 아파치 설치된 이미지 배포해보기

옵션 설명

- "--name" : 다음 나오는 정보가 컨테이너 이름입니다.

- "-d" : 백그라운드로 실행해주세여(daemon의 약자인듯)

- httpd: 이미지 이름

 

컨테이너 확인

- docker ps 또는 docker container ls

- STATUS가 UP=실행중 / Exited=정지됨

 

컨테이너 정지

 

컨테이너 전체 리스트 확인

 

컨테이너 없앰(없애면 리스트에서도 안보임)

 

 


기본실습2) 

옵션 설명

- "-p 8080:80" : 포트는 8080으로 접근하면 컨테이너 80 포트에 도달하도록 해주세여(호스트 포트 8080: 컨테이너 포트 80)

 

→ 그래서 localhost:8080으로 접근해보면

 

 

 

 

컨테이너, 도커 기본 개념

  • 컨테이너? 데이터나 프로그램을 격리시키는 조립형 창고
    • 컨테이너는 자유롭게 옮길 수 있다(도커 엔진A → 도커 엔진B: easy)
  • 이런 컨테이너를 다루는 기술이 Docker
    • (주로) 서버에서 사용되는 소프트웨어
    • Docker 제약사항: 리눅스
  • 어떤 컨테이너를 만들건데? 이걸 정하는 게 바로 이미지
  • 근데 왜 필요함?
    • 프로그램을 동작시키려면 이걸 실행시킬 실행 환경(런타임)이 필요함.
    • 그뿐만 아니라 라이브러리들도 런타임마다 제각각임.
    • 또 어떤 프로그램끼리는 같은 디렉토리를 공유할 수도 있음. 프로그램 여러 개를 동시에 가동시키는 데 디렉토리를 공유하고 있었다..? 그건 재앙..

가상화 기술 vs 도커

  • 가상화 기술은 가상의 물리 서버 → 실질적으로 하나의 물리 서버나 마찬가지.
  • 도커는 운영체제 일부 기능을 호스트 컴퓨터(물리 서버)에 의존

도커 동작 원리

  • 물리서버의 리눅스 운영체제 위에, 도커 엔진 위에, 컨테이너.
  • 이 컨테이너 안에는 위에서 설명한 프로그램이나 데이터가 위치하고 또 리눅스 운영체제 비스무리한 게 위치한다.
    • 비스무리? 원래 운영체제는 커널+주변 영역으로 구성됨
      • 커널: 하드웨어 다루는 애 / 주변 영역: 프로그램의 내용을 커널에 전달하는 애
      • 컨테이너에는 주변 영역만 들어 있음. 원래 컨테이너는 개별 공간 마냥 분리되어 있는데 그럼 하드웨어 장비를 어떻게 써..그래서 주변 영역이 소통 창고 같은 느낌으로 있는 거임.
      • 컨테이너 속 프로그램의 작업 → 컨테이너 속 리눅스 OS 주변 영역이 의견 수렴 후 전달 → 도커 엔진이 컨테이너들의 의견 수렴 후 전달 → 커널 수렴
    • 컨테이너에는 주변 영역만 있기 때문에 이 덕분에 도커는 “가벼움”

도커 이미지

  • 이미지는 컨테이너를 만드는 빵틀 같은 거임. 그래서 똑같은 컨테이너 여러 개 찍어내듯 만들어낼 수 있음
  • 근데 빵틀과 달리 개조하기 겁나 쉬움
  • 다른 도커 엔진으로 공유하는 것도 쉬움
  • 아예 공유하라고 만들어 놓은 곳이 도커 허브임(hub.docker.com)

도커 생애주기

  • 도커는 사실 일회용품 같은 거임.
    • 설치된 소프트웨어 업데이트 필요하면 일일이 해주는 게 아니라, 걔네들 설치된 거 다 폐기 시키고 그냥 새로운 버전이 설치된 이미지로 컨테이너 쫙~ 뽑아서 쓰는 거임
  • 근데, 그럼 그 안에 있는 데이터는 우짬? 그래서 데이터는 도커 설치된 물리 서버의 디스크에 마운트해 따로 저장하긴 함. 이러면 컨테이너 간 데이터 공유도 편함.

 

 

 


출처: 

 
그림과 실습으로 배우는 도커 & 쿠버네티스
이 책은 컨테이너 기술이 어렵게 느껴지는 엔지니어나 백엔드 기술에 자신이 없는 분들을 위한 도커 입문서입니다. 자세한 그림과 친절한 실습을 통해 리눅스 지식이나 서버 구축 경험이 없어도 컨테이너와 도커, 쿠버네티스에 대한 지식을 쉽게 이해할 수 있습니다. 도커의 개념부터 동작 방식, 명령어 사용법, 컨테이너 운용, 나아가 도커 컴포즈와 쿠버네티스까지, 컨테이너 기술에 대한 배경지식이 전혀 없는 분들도 도커와 쿠버네티스의 개념과 기초 사용법을 익힐 수 있도록 안내합니다. 도커나 쿠버네티스를 배우고 싶은 초보자라면 철저하게 입문자의 눈높이에 맞춘 이 책으로 도커의 세계에 첫발을 내디뎌 보세요.
저자
오가사와라 시게타카
출판
위키북스
출판일
2022.04.05

 

 

 

+ Recent posts