🐳 도커의 기본 개념
- 도커: 데이터 또는 프로그램을 격리시키는 기능(운영체제 통째로!)
- 컨테이너: 어플리케이션이 한 컴퓨팅 환경에서 다른 컴퓨팅 환경으로 빠르고 안정적으로 실행될 수 있도록 코드와 모든 종속성을 패키징하는 표준 소프트웨어 단위
- 이미지: 파일로 애플리케이션 실행에 필요한 독립적인 환경을 포함하며, 런타임 환경을 위한 일종의 템플릿
⭐️ 이미지는 '틀'로 하나의 이미지로 여러 개의 컨체이너를 만들 수 있고 반대로 컨테이너를 만들려면 이미지가 반드시 필요하다!
🐳 데이터나 프로그램을 독립된 환경에서 격리해야 하는 이유
1. 시스템 A와 시스템 B가 한 서버에 함께 있을 경우
시스템 A, B가 같은 디렉토리 사용 → 설정 파일이 섞이거나 설정에 충돌 발생 가능성 ↑
ex) 시스템 A는 penguin 8.0 버전에서 작동하고 시스템 B는 penguin 5.0 버전에서 작동할 때 서버에 깔려 있는 프로그램(penguin)이 8.0 버전이면 시스템 A는 정상적으로 연동이 되지만 시스템 B에서 오류가 발생할 수 있다.
2. 시스템 A와 시스템 B가 격리되어 있을 경우
시스템 A + penguin 8.0 버전
시스템 B + penguin 5.0 버전
→ 각각 다른 컨테이너에 따로 격리
→ 시스템 A와 시스템 B가 정상적으로 연동이 될 수 있다.
🐳 컨테이너 기술은 왜 필요할까?
- 서버: 어떤 서비스를 제공하는 것
- 기능적 의미의 서버: '무슨무슨 서버'라는 말은 '무슨무슨 기능을 제공한다'는 의미
- 물리적 컴퓨터로서의 서버: 데스크톱 컴퓨터와 마찬가지로 어딘가에 물리적으로 존재
하나의 물리적 컴퓨터에 여러 개의 기능적 의미의 서버를 함께 둘 수 있다.
일반적으로는 한 대의 서버 컴퓨터에는 웹 서버를 한 벌 밖에 실행하지 못하지만 컨테이너 기술을 활용하면 여러 개의 웹 서버를 올릴 수 있다.
→ 물리 서버 한 대에 여러 개의 웹 서버를 띄우면 그만큼 물리 서버 수를 줄일 수 있다. 즉, 프로젝트 하나의 비용이 절반으로 감소한다.
🐳 도커의 구조
↑ 프로그램 및 데이터(일부)는 컨테이너 안에 위치한다
<모든 컨테이너에는 '리눅스 운영체제 비슷한 무언가'가 들어있다!>
- 운영체제: 소프트웨어나 프로그램의 명령을 하드웨어에 전달하는 역할. 커널과 그 외 주변 부분으로 구성되어 있으며 주변부분이 커널에 프로그램 연락 내용을 전달한다.
↑ 리눅스의 주변부분만 컨테이너에 넣고 커널은 밑바탕에 있는 것을 빌려 쓰는 형태 → '가벼움'을 얻을 수 있다!
도커는 기본적으로 리눅스 운영체제에서만 동작!
why? 리눅스 운영체제가 동작하는 걸 전체로 하는 구조이기 때문!
따라서 윈도우나 macOS용 소프트웨어를 컨테이너에 넣어도 동작하지 않는다.
!!윈도우나 macOS 운영체제를 사용하는 컴퓨터에서 도커 사용이 가능한 이유!!
- Virtual Box나 VMware같은 가상 환경 위에 리눅스 운영체제를 설치하고 그 위에 도커를 실행
- 도커를 실행하는데 필요한 리눅스 운영체제를 포함하는 패키지를 설치해 사용
⭐️ 어떤 형태로든 리눅스 운영체제를 갖춰야 한다 ⭐️
🐳 도커 이미지와 컨테이너
- 이미지: 컨테이너(우리가 실제로 이용하는 것)을 사용, 이미지는 실제 사용 x
- 하나의 이미지로 동일한 컨테이너 여러 개 배치 가능
- 컨테이너로부터 이미지를 만드는 것도 가능
- 이미 만들어진 컨테이너가 수정되었을 경우 그 수정을 포함하고 있는 이미지를 새로 생성할 수 있다!
- 보안 및 유지 관리 측면에서 한 컨테이너에 한 프로그램을 담아내는 것을 권장
- 컨테이너는 쓰고 버리는 일회용품
🐳 도커 컨테이너의 생애 주기와 데이터 저장

데이터 저장
- 도커가 설치된 물리적 서버(호스트)의 디스크를 마운트(디스크를 연결해 데이터를 기록할 수 있도록 한 상태)해 디스크에 데이터 저장
- 컨테이너가 폐기되더라도 데이터는 컨테이너 외부에 저장되어 사라지지 x
🐳 도커의 장점과 단점
- 독립된 환경
- 여러 개의 컨테이너를 띄울 수 있다.
- 똑같은 애플리케이션도 여러 개 띄울 수 있다.
- 이미지를 만들 수 있다.
- 교체가 쉽고 업데이트가 쉽다.
- 환경 이동이나 개발 환경을 구축하기 쉽다.
- 컨테이너에 '커널을 포함시킬 필요가 없다.'
- 가볍다
→ 모든 장점은 격리가 가능하다는 것에서부터 시작한다.
- 한대의 물리 서버에 여러 대의 서버를 띄울 수 있다.
- 서버 관리가 용이하다.
- 다루기 쉽다.
- 리눅스용 소프트웨어밖에 지원하지 않는다.
- 호스트서버에 문제가 생기면 모든 컨테이너에 영향이 미친다.
- 컨테이너 하나를 장기간에 걸쳐 사용할 때는 큰 장점을 느끼기 어렵다.
🐳 도커 실행 및 삭제
- 도커 엔진은 컴퓨터를 켰을 때 함께 자동으로 실행할 수 있지만, 컨테이너는 그렇지 않다.
docker [상위 커맨드](무엇을) [하위 커맨드](어떻게) (옵션) [컨테이너명/이미지명](대상) (인자)
- 가끔 상위 커맨드를 생략하는 경우도 존재한다.
- 옵션: 커맨드에 세세한 설정을 지정하는 용도
- 인자: 대상에 전달할 값을 지정
- 볼륨: 컨테이너에 마운트 가능한 스토리지
동작중인 컨테이너를 그대로 삭제할 수 없기 때문에 다음과 같은 순서를 따라야 한다.
컨테이너를 생성하고 실행
docker run (옵션) 이미지 (인자)
컨테이너를 정지
docker stop 컨테이너_이름
컨테이너를 삭제
docker rm 컨테이너_이름
현재 존재하는 컨테이너 목록 출력
docker ps -a
- 컨테이너를 삭제해도 이미지는 그대로 남는다!
- 해당 이미지로 실행된 컨테이너가 없어야 이미지를 삭제할 수 있다.
- docker rm → 이미지가 아닌 컨테이너가 삭제
이미지를 삭제
docker image rm 이미지_이름 이미지_이름2 ...
이미지 목록 정보
docker image ls
🐳 컨테이너의 통신
-p 호스트_포트_번호:컨테이너_포트_번호
- 호스트 컴퓨터의 포트 번호가 중복되면 x
- 컨테이너 포트는 중복되어도 무방
도커 네트워크 형성
docker network create 네트워크_이름
도커 네트워크 삭제
docker network rm 네트워크_이름
🐳 컨테이너와 호스트 사이의 파일 복사
호스트 → 컨테이너 파일 복사
docker cp 호스트_경로 컨테이너_이름:컨테이너_경로
컨테이너 → 호스트 파일 복사
docker cp 컨테이너_이름:컨테이너_경로 호스트 경로
파일 복사 명령어
docker cp 원본_경로 복사할_경로
🐳 볼륨 마운트
- 데이터 퍼시스턴시: 매번 데이터를 옮기지 않고 처음부터 컨테이너 외부에 둔 데이터에 접근해 사용하는 것
- 데이터를 두는 장소: 마운트 된 스토리지 영역
- 볼륨 마운트: 도커 엔진이 관리하는 영역 내에 만들어진 볼륨을 디스크 형태로 마운트 하는 것
- 직접 조작하기가 어려워 '임시 목적의 사용'이나 '자주 쓰지는 않지만 지우면 안되는 파일'을 두는 목적으로 많이 사용된다.
- 바인트 마운트: 도커 엔진에서 관리하지 않는 영역의 기존 디렉터리를 컨테이너에 마운트하는 방식
- 자주 사용하는 파일을 두는데 사용된다.
📍 파일을 직접 편집해야 하는 일이 많다 → 바인드 마운트
📍 그렇지 않다 → 볼륨 마운트
✅ 볼륨 마운트, 바인드 마운트는 스토리지 마운트에 속한다.
- 스토리지 마운트는 run 커맨드의 옵션 형태로 지정한다.
- 마운트하려는 스토리지의 경로가 컨테이너 속 특정 경로와 연결되도록 설정하는 형태
바인드 마운트 커맨드 예
docker run -v 스토리지_실제_경로:컨테이너_마운트_경로
볼륨 마운트 커맨드 예
docker run -v 볼륨_이름:컨테이너_마운트_경로
🐳 컨테이너 이미지 변환
컨테이너를 이미지로 변환
docker commit 컨테이너_이름 새로운_이미지_이름
- Dockerfile: 이미지를 만드는 파일, Dockerfile 스크립트를 작성하고 이 스크립트를 빌드해 이미지를 만드는 방법
docker build -t 생성할_이미지_이름 재료_폴더_경로
주요 Dockerfile 인스트럭션
인스트럭션 | 내용 |
---|
FROM | 토대가 되는 이미지를 지정 |
COPY | 이미지에 파일이나 폴더를 추가 |
RUN | 이미지를 빌드할 때 실행할 명령어를 지정 |
🐳 컨테이너 개조 방법
- 파일 복사 + 마운트
- 컨테이너에서 리눅스 명령어를 실행하는 방법: 리눅스에 우리의 명령을 전달해주는 프로그램이 shell(셸)이 필요
docker exec 컨테이너_이름 /bin/bash
docker exec: 컨테이너 속에서 명령어 실행
/bin/bash: bash 실행 인자
- bash가 실행되면 셸에 입력된 명령어는 도커 엔진이 아니라 해당 컨테이너로 전달
- bash를 통해 컨테이너 내부를 조작하는 동안에는 도커 명령 사용 x
- 컨테이너 안에서 할 일을 마쳤다면 exit를 통해 다시 컨테이너에서 나와야 한다.
🐳 도커 컴포즈
- 도커 컴포즈: 시스템 구축과 관련된 명령어를 하나의 텍스트 파일에 기재에 명령어 한 번에 시스템 전체를 실행하고 종료와 폐기까지 한번에 하도록 도와주는 도구
- YAML 포맷으로 기재한 정의 파일을 이용해 전체 시스템을 일괄 실행 또는 일괄 종료 및 삭제할 수 있는 도구
- UP 커맨드: docker run 커맨드와 비슷. 정의 파일에 기재된 내용대로 이미지를 내려받고 컨테이너를 생성 및 실행
- DOWN 커맨드: 컨테이너와 네트워크를 정지 및 삭제. 볼륨과 이미지는 삭제 x
도커 컴포즈와 Dockerfile 스크립트의 차이점
종류 | 내용 |
---|
도커 컴포즈 | 컨테이너와 주변환경 생성. 네트워크와 볼륨까지 함께 만들 수 있다. |
Dockerfile | 이미지를 만들기 위한 것. 네트워크나 볼륨은 만들 수 x |
↑ 정의 파일의 이름은 미리 정해진 docker-compose, yml 사용
- 파일은 호스트 컴퓨터에 배치되지만 명령어는 똑같이 도커 엔진에 전달
- 만들어진 컨테이너도 동일하게 도커 엔진 위에서 동작
- 사람이 일일히 입력하던 명령어를 도커 컴포즈가 대신 입력해주는 역할
- 정의 파일(docker-compose.yml)은 한 폴더에 하나만 존재!