왜 도커가 필요할까?
[상황 1] 나는 맥 환경에서 자바17을 사용하고, 다른 개발자는 윈도우 환경에서 자바11을 사용한다. 내가 작성한 record 클래스는 그의 환경에서 제대로 동작하지 않을 것이다. 이러한 상황에서 도커를 도입한다면?
[상황 2] 사용 중인 JDBC 라이브러리를 새로운 버전으로 업데이트 하고싶다. 팀원들과 수동으로 환경을 맞추어 개발하고 있다면 어떤 버전으로 업데이트 할지 등을 공유해야 한다. 귀찮고 오류 발생 확률도 높다. 하지만 도커로 개발 환경을 관리하고 있었다면?
[상황 3] 현재 진행 중인 총대마켓 프로젝트에 새로운 신입이 합류했다. 신입의 개발 환경을 세팅해 주어야 한다. 내가 로컬에서 개발하고 있는 환경을 신입에게 일일이 설명하고 설정해야 한다. 너무 귀찮다. 이 때 도커를 도입한다면?
도커를 도입해 개발 환경을 관리한다면 위 불편함은 모두 해결된다. 귀찮은 설치 과정이 불필요해지고, 버전, 옵션, 운영 체제 등에 있어 일관된 프로그램을 설치할 수 있다. 더불어 각 프로그램이 독립적인 환경에서 설치 및 실행되므로 프로그램 간 충돌이 발생하지 않는다.
도커의 가장 큰 특징이자 장점은 이식성이다. 특정 프로그램을 다른 곳으로 쉽게 옮겨 설치 및 실행할 수 있는 특성을 가진다.
그래서 도커는 어떤 원리로 동작하는지 알아보고 사용해보자.
도커
도커 공식 홈페이지의 첫 페이지만 확인해도, 도커가 추구하고 제공하고자 하는 가치를 알 수 있다.
Develop faster, Run anywhere.
Accelerate how you build, share, and run applications.
- 환경에 구애받지 않고 애플리케이션을 인프라에서 분리하여 신속하게 구축, 테스트 및 배포할 수 있는 소프트웨어 플랫폼
- 컨테이너를 사용하여 각각의 프로그램을 분리된 환경에서 실행 및 관리할 수 있는 툴
- 가상 머신(AWS EC2)이 서버 하드웨어를 가상화하는 방식과 비슷하게(직접 관리해야 하는 필요성 제거), 컨테이너는 서버 운영 체제를 가상화한다. 도커는 각 서버에 설치되며 컨테이너를 구축, 시작 또는 중단하는 데 사용할 수 있는 간단한 명령을 제공한다.
도커 아키텍처
도커 클라이언트는 도커 데몬과 통신하며, 이 데몬은 도커 컨테이너를 빌드, 실행 및 배포하는 힘든 작업을 수행한다.
도커 데몬 (docker daemon)
- 도커 API 요청을 수신(받음)
- 이미지, 컨테이너, 볼륨과 같은 도커 객체 관리
- 관련 명령어: dockerd
도커 클라이언트 (docker client)
- 많은 도커 사용자가 도커와 상호작용하는 방법
- 도커 API를 사용하는 docker run 과 같은 명령으로 dockerd(도커 데몬)로 명령을 보내 그들을 실행시킴
- 두 개 이상의 도커 데몬과 통신 가능
- 관련 명령어: docker
도커 데스크톱 (docker desktop)
- 컨테이너화된 어플리케이션과 마이크로서비스를 빌드하고 공유할 수 있는 Mac, Windows 또는 Linux 환경을 위한 설치하기 쉬운 어플리케이션
- 도커 데몬, 도커 클라이언트, 도커 컴포즈 등이 포함되어 있음
도커 레지스트리 (docker registry)
- 도커 이미지를 저장하는 공간
- Docker Hub
- 누구나 사용 가능한 공개 레지스트리
- 도커는 기본적으로 Docker Hub에서 이미지 서치
- 개인 레지스트리 직접 관리도 가능
- 관련 명령어: docker pull, docker push
도커 객체 (docker object)
- 도커는 이미지, 컨테이너, 볼륨, 네트워크 등의 객체를 만들고 사용한다.
이미지 (image)
- 도커 컨테이너를 만드는 지침이 포함된 읽기 전용 템플릿
- 프로그램을 실행하는 데 필요한 설치 과정, 설정, 버전 정보 등을 포함 (즉, 프로그램을 실행하는 데 필요한 모든 것을 포함)
- Dockerfile 파일을 통해 본인만의 이미지 생성 가능
- [예시] 이미지를 도커로 실행시키는 순간, MySQL 서버가 컨테이너 환경에서 실행됨 ⇒ 복잡한 설치 과정 없이 손쉽게 실행
- [비유] 닌텐도의 게임 칩
컨테이너 (container)
- 이미지의 실행 가능한 인스턴스
- 하나의 컴퓨터 환경 내에서 독립적인 컴퓨터 환경을 구성하여, 각 환경에 프로그램을 별도로 설치할 수 있게 만든 개념
- 하나의 컴퓨터 내에 여러개의 미니 컴퓨터 환경을 구성하는 형태이고, 여기서의 미니 컴퓨터가 도커의 컨테이너이다.
- 컨테이너를 포함하고 있는 컴퓨터를 호스트 컴퓨터라고 부른다.
- 컨테이너는 독립적인 컴퓨터 환경을 갖는다.
- 디스크 (저장 공간): 각자의 저장 공간을 갖는다. A 컨테이너가 B 컨테이너의 내부 파일 접근할 수 없다.
- 네트워크 (IP, port): 고유의 네트워크를 갖는다. 각자의 IP 주소를 갖는다.
- [비유] 윈도우 내 계정을 분리함으로써 독립적인 환경 구성
볼륨 (volume)
- 문제: 매번 기능이 변경될 때마다 새로운 이미지를 생성한 후 컨테이너를 실행시켜야 한다. 기존 컨테이너를 새로운 컨테이너로 교체하면, 기존 컨테이너 내부의 데이터도 함께 삭제된다. 예시로, 기존 컨테이너 안에 MySQL이 있었다면 DB 저장 데이터도 같이 삭제되어 버린다. 이 경우 볼륨을 사용하여 컨테이너 내부에 저장된 데이터를 유지시킬 수 있다.
- 도커 컨테이너에서 데이터를 영속적으로 저장하기 위한 방법
- 컨테이너 자체의 저장 공간을 사용하지 않고, 호스트 자체의 저장 공간을 공유하여 사용하는 형태
docker run -v [호스트의 디렉토리 절대경로]:[컨테이너의 디렉토리 절대경로] [image]
[호스트의 디렉토리 절대경로]에 디렉토리가 이미 존재할 경우, 호스트의 디렉터리가 컨테이너의 디렉터리를 덮어씌운다. 디렉토리가 존재하지 않을 경우에는, 호스트 디렉터리 절대 경로에 디렉터리를 새로 생성한 후 컨테이너의 디렉터리에 있는 파일들을 호스트의 디렉터리로 복사해온다.
사용해보기
이미지 다운로드
docker pull mysql
docker pull mysql:latest // 태그(이미지의 버전) 설정
이미지 조회
docker image ls
이미지 삭제
docker image rm [image id] // 컨테이너에서 사용하지 않는 이미지만 삭제 가능
docker image rm -f [image id] // 중단된 컨테이너 내 사용 중인 이미지 강제 삭제
docker image rm $(docker images -q) // 컨테이너에서 사용하지 않는 전체 이미지 삭제
컨테이너 조회
docker ps // 실행 중인 컨테이너만 조회
docker ps -a // 모든 컨테이너 조회
컨테이너 생성
docker create [image] // 존재하지 않는 이미지라면, dockerhub에서 자동으로 다운받은 후 컨테이너 생성
컨테이너 실행
docker start [container id] // 컨테이너의 status: created -> UP
컨테이너 중지
docker stop // 정상적으로 종료
docker kill // 강제 종료 (최후의 수단)
컨테이너 삭제
docker rm [container id] // 중지된 컨테이너만 삭제 가능
docker rm $(docker ps -qa) // 중지된 모든 컨테이너 삭제
docker rm -f [container id] // 실행 중인 컨테이너 중지 후 삭제
컨테이너 로그 조회
docker logs [container id]
docker logs --tail [원하는 로그 줄 개수] [container id] // ~줄만 출력
docker logs -f [container id] // 기존 로그 조회 + 생성되는 로그 실시간 조회
docker logs --tail 0 -f [container id] // 현재 시점에서 쌓이는 로그 실시간 조회
컨테이너 생성 후 실행
docker run // docker create + docker start
docker run -d [image] // 백그라운드 실행
실행 과정: 이미지 다운로드 → 컨테이너 생성 → 컨테이너 실행
사용 예시
docker run -d nginx
문제: 컨테이너는 기본적으로 80 포트에서 실행되어, localhost:80 에 접속해 보았으나, 웰컴페이지가 출력되지 않았다.
이유: 호스트 컴퓨터에서 컨테이너에 접속해야 하는데, 컨테이너는 독립된 공간이기 때문에 포트를 직접 연결해주어야 한다.
해결: 포트 포워딩 (port forwarding)
docker run -d -p [host_port]:[container_port] [image]
해결 예시:
docker run -n [container name] -d -p 80:80 mysql
docker run -d -p 4000:80 nginx
해결 성공!
컨테이너 내부 접속
docker exec -it [container id] /bin/bash
- 실행 중인 컨테이너 내부 환경에 입장
- 해당 환경 내에서도 ls, cd, cat 등의 명령어 모두 실행 가능
- exit 명령어로 컨테이너 내부에서 나오기
출처
도커 공식 문서
https://docs.docker.com/guides/docker-overview/
박재성님 Docker 입문 강의
https://www.youtube.com/watch?v=52fBv-O5HBQ&list=PLtUgHNmvcs6rS5aNCRIZtVcyk3gRX2iOd&index=2
'🌱 우아한테크코스 6기' 카테고리의 다른 글
인덱스는 만능인가 (4) | 2024.11.07 |
---|---|
[코리스토텔레스] 패키지 구조: 계층형 구조 vs 도메인형 구조 (0) | 2024.07.28 |
[인프라] AWS EC2 (0) | 2024.07.22 |
[TroubleShooting] 에러 해결 과정에서 알게 된 @DirtiesContext 동작 방식 (3) | 2024.05.07 |
[우아한테크코스] 2월 한달 회고 (32) | 2024.03.12 |