[docker] 도커 심화
1. Docker 정의 및 사용 이유
- 애플리케이션을 신속하게 구축, 테스트 및 배포할 수 있는 소프트웨어 플랫폼
- 소프트웨어를 컨테이너라는 표준화된 유닛으로 패키징하며, 이 컨테이너에는 라이브러리, 시스템 도구, 코드, 런타임 등 소프트웨어를 실행하는데 필요한 모든 것을 포함
- 도커의 등장으로 DevOps 발달
- 더 많은 소프트웨어를 더 빨리 제공
- 운영 표준화
- AWS 프로덕션 배포로 원활하게 이전
- 비용 절감
2. 배포
- 빌드
- 소스코드를 실행 가능한 소프트웨어로 만드는 과정
- 배포
- 애플리케이션을 개발 환경에서 실행 환경으로 전달하여 실제 사용자들이 이용할 수 있도록 하는 과정
- 배포 전략
- 애자일 개발 방법론과 MSA의 발전에 따라, 서비스를 작게 만들고 더 자주 배포하는 방식으로 IT 산업군이 변화하고 있음
- 애자일 개발 방법론: 미래를 예측하기 보다는 주기적으로 제작 프로토타입을 시험해보는 철저한 관리를 통한 개발 방법론
- MSA: 마이크로서비스 아키텍처
- 이 상황에 맞게 배포 전략을 구성하는 것이 중요
- 애자일 개발 방법론과 MSA의 발전에 따라, 서비스를 작게 만들고 더 자주 배포하는 방식으로 IT 산업군이 변화하고 있음
대표적인 배포 전략
- 인플레이스 배포
- 롤링 배포
- 블루 / 그린 배포
- 카나리 배포
- 빅뱅 배포
인플레이스 배포
- 애플리케이션을 업데이트할 때 현재 실행 중인 애플리케이션 인스턴스를 중지하고 새 버전을 대체
-
배포 방식 상, EC2와 온프레미스 환경에서만 사용 가능한 전략
- 장점
- 가장 간단한 방법
- 단일 서버에 적합
- 작은 규모의 애플리케이션에 효율 높음
- 단점
- 애플리케이션 업데이트 동안 서비스 중단
-
롤백이 복잡
- 위 단점을 보완하기 위해 무중단 배포가 발전
롤링 배포
- 애플리케이션 업데이트를 일정한 간격으로 점진적으로 실시하는 배포 전략
-
구 버전에서 새 버전으로 트래픽을 점진적으로 전환하며, 구 버전의 인스턴스로 점차 삭제됨
- 장점
- 무중단 배포
- 점진적 배포
- 서버 수의 제약이 있을 경우 유용
- 단점
- 서버 처리 용량을 미리 고려하여야 함
- 롤백 시간이 오래 걸림
- 무중단 배포
- 애플리케이션의 새 버전을 사용자가 서비스 이용에 차질없이 이용하도록 배포하는 전략
블루 / 그린 배포
- 새로운 변경사항이 포함된 애플리케이션을 위한 새로운 환경을 구축하고 교체하는 방법
- 블루: 현재 운영 중인 프로덕션 환경
-
그린: 새로운 버전의 애플리케이션 프로덕션 환경
- 사용자가 서비스를 이용하는 동안 그린에 배포
-
배포가 완료되면 사용자 트래픽을 블루 > 그린 변경
- 장점
- 무중단 배포
- 롤백 용이 (인플레이스 배포보다 빠름)
- 운영 환경에 영향을 주지 않고 실제 서비스 환경으로 새 버전 테스트 가능
- 단점
- 구 버전, 새 버전 두 환경을 갖춰야 해서 자원, 비용이 두 배로 필요
카나리 배포
- 새 버전의 애플리케이션을 일부 사용자에게만 배포
-
새 버전에 대한 피드백을 빠르게 얻을 수 있음
- 배포 동작 과정
- 새 버전의 애플리케이션을 일부 사용자에게만 제공
- 피드백 체크 > if not problem > 점진적 배포
- 피드백 체크 > if problem > 배포 중단
- 장점
- 무중단 배포
- A/B 테스트 적용 가능
- 성능 / 오류 / 에러 모니터링에 적합
- 일부 사용자에게만 새 버전을 배포하므로, 문제가 발생해도 전체 사용자에게 영향 X > 리스크 감소
- 단점
- 사용자 경험 일관성 X
3. Docker CI / CD
- CI/CD
- Continuous Integration -> Continuous Deployment
- 애플리케이션 개발 단계를 자동화하여 애플리케이션을 더욱 짧은 주기로 고객에게 제공하는 방법
- 핵심
- 애플리케이션 토ㅇ합 및 테스트 단계에서부터 제공 및 배포에 이르는 사이클 전체에 걸쳐 지속적인 자동화와 지속적인 모니터링 제공
- 장점
- 프로젝트를 작은 단위로 빈번하게 코드를 통합하고 테스트할 수 있으며, 코드 변경 사항을 신속하게 전달할 수 있음
- 빠른 배포 주기, 고객 요구사항 신속 대응 보장
CI
- 지속적인 통합 (Continuous Integration)
- 동일한 프로젝트에서 작업하는 모든 사람이 정기적으로 코드 베이스의 변경 사항을 중앙 저장소에 병합하도록 하는 방식
-
지속적 통합의 목표는 공동 작업, 자동화 및 짧은 피드백 주기를 촉진하여 소프트웨어 빌드와 릴리스에 대한 안정적인 접근 방식을 유지관리하는 것
- 지속적 통합을 통해 품질 저하 없이 소프트웨어 릴리스 주기 단축
-
**배포 중에 발생할 수 있는 잠재적인 위험을 완화하고 피드백 루프를 단축하는 것
- 장점
- 배포 위험 감소
- 높은 품질 보장
- 비용 절감
Develop -> Source Control -> Build & Test
CD
- 지속적인 제공 (Continuous Delivery)
- 소프트웨어를 빌드하고 릴리스하는 데 필요한 수작업 단계를 자동화하는 방법
- CD를 구현하기 전에는 Develop 파이프라인에 CI가 먼저 구축되어 있어야 함
-
지속적인 제공의 목표는 프로덕션 환경으로 배포할 준비가 되어 있는 코드베이스를 확보하는 것
- 주요 특징
- 환경 자동화
- 롤백 및 배포 관리
- 낮은 배포 위험
Develop -> Source Control -> Build & Test -> Deploy on Test Environment -> Deploy on Prod
CD
- 지속적인 배포 (Continuous Deployment)
- CI/CD 파이프라인의 마지막 단계, 지속적인 제공 단계를 기반으로 함
- 배포 단계를 자동화하여 개발자들이 코드 변경을 실시간으로 프로덕션 환경에 배포하는 방식
-
실제 실무에서 지속적인 배포의 의미는 개발자가 애플리케이션에 변경 사항을 작성한 후 몇 분 이내로 클라우드 애플리케이션을 자동으로 실행할 수 있는 것 (테스트 시간 제외)
- 지속적인 전달: 사용자에게 소프트웨어를 제공하는 데 필요한 단계를 자동화하는 데 중점 (빌드 자동화)
- 지속적인 배포: 지속적인 전달이 모두 충족된 상태에서 사용자에게 소프트웨어를 자동 릴리스 하는 것
4. Docker CI/CD
- Docker: 컨테이너화 기술 제공
- CI/CD: 개발 & 배포 프로세스를 자동화하는 방법론
-
도커의 컨테이너 환경을 CI/CD 파이프라인과 결합하면 일관된 환경에서 신속하고 안정적인 소프트웨어 배포를 수월하게 진행할 수 있음
- Jenkins
- CI/CD로 가장 널리 알려진 오픈소스 툴
- Docker & Jenkins
- 도커 컨테이너 실행
- 빌드 환경 일관성 유지
- 테스트 환경 구축
- 배포 자동화
- 도커를 통해 환경 일관성과 이식성을 확보
- 젠킨스를 통해 빌드, 테스트, 배포 자동화
- 개발자 업무 효율 극대화
5. Docker Orchestration
- Orchestration
- 여러 개의 독립적인 서비스를 관리하여 전체 프로세스를 자동화하는 것
- Docker Orchestration
- 여러 대의 도커 호스트를 관리하고, 컨테이너의 배포, 확장, 조정, 장애, 복구 등을 자동화하는 기술
- 도커 컨테이너의 대규모 배포와 관리를 간소화하며, 안정적이고 확장 가능한 애플리케이션 환경 구축
- Kubernetes
- 쿠버네티스, k8S, 큐브, kube
- 컨테이너화된 애플리케이션을 배포, 관리, 확장할 때 수반되는 다수의 수동 프로세스를 자동화하는 오픈소스 컨테이너 오케스트레이션 플랫폼
- 프로덕션 환경에서 애플리케이션을 실행하는 컨테이너를 관리하고 시스템 측면에서 처리할 수 있음
- Linux
- 자원 격리 기술
- 자원을 격리해서 프로세스들이 독립적인 환경에서 돌아갈 수 있도록 제공해주는 기술이 있음
- but, 사용법이 어려워 대중적으로 널리 퍼지지 않았음
- VM
- 가상화 기술
- but, VM 가상화를 통해 자동화를 구현할 수는 있지만, 무거운 OS를 띄워야 한다는 근본적인 문제점이 있기 때문에 시스템 효율이 별로임
- Container
- 가상화 기술
- 도커라는 기업에서 내장 리눅스의 어려운 자원 격리 기술을 컨테이너라는 개념으로 보다 쉽게 사용할 수 있도록 만듦
- 이를 통해 서비스 간에 자원 격리를 하는데 OS를 별도로 띄우지 않아도 됨
- OS 가동시간이 없기 때문에 자원 효율이 압도적으로 높고 빠름
- 도커는 하나의 서비스를 컨테이너로 가상화해서 배포하는 것
- 대량의 서비스를 운영할 때, 수많은 서비스를 일일이 배포하고 운영하는 것에 복잡함이 생김
- 이를 해결하기 위해 컨테이너 오케스트레이션이 생김
- Contatiner Orchestration
- 다수의 컨테이너들을 관리해주는 솔루션
- 대량의 컨테이너들을 효율적으로 관리하기 위한 컨테이너 전용 관리자라고 생각하면 됨
- Kubernetes
- 오픈소스 컨테이너 오케스트레이션 플랫폼
- 컨테이너를 다루는 도구
- 현재 IT 산업군에서 서비스 배포 운영의 표준으로 자리매김함
6. Docker Run과 CMD 명령어 차이
RUN
- Docker 컨테이너 생성, 실행, 동작 등 정의 역할 수행 명령어
RUN <command>
RUN ["executable", "param1", "param2"]
RUN bundle install
- Docker 컨테이너가 시작될 때, Docker RUN 명령어가 포함된 명령을 실행
- 만약 RUN 명령을 시행하지 않았다면, Dockerfile의 CMD나 ENTRYPOONT에서 정의한 명령이 실행됨
CMD
- Docker 컨테이너 생성, 실행, 동작 등 정의 역할 수행 명령어
CMD ["executable", "param1", "param2"]
CMD command param1 param2
CMD bundle exec ruby app.rb
- Dockerfile에 CMD 명령어를 기재하면 해당 컨테이너가 시작될 때마다 해당 명령이 자동으로 실행
- 도커 컨테이너가 실행되었을 때 실행되는 명령어를 정의
- 빌드할 때는 실행되지 않으며 여러 개의 CMD가 존재하면 가장 마지막(최신) CMD만 실행됨
7. Docker 엔진
- 컨테이너를 구축 및 실행하는 오픈소스 호스트 소프트웨어
- 리눅스 운영체제에서 컨테이너를 지원하는 클라이언트-서버 애플리케이션 역할 수행
-
Docker Daemon, Docker CLI, Docker Image and Containers 이 세 가지 구성 요소를 사용하여 애플리케이션을 컨테이너화하고, 실행, 관리 등을 수행
- Docker Engine 구성 요소
- Docker Daemon
- Docker CLI
- Docker Images and Containers
- Docker Daemon
- Docker API 요청을 수신하고 Docker 객체(이미지, 볼륨, 네트워크 등) 관리
- Docker CLI
docker
명령을 사용하여 Docker Daemon과 통신 수행
- Docker Images and Containers
- 이미지: 애플리케이션 실행에 필요한 모든 것을 포함하는 템플릿
- 컨테이너: 이미지 실행 가능 인스턴스 version
8. Docker 레이어 (이미지 컨테이너)
- Docker Image
- 도커에서 이미지란 컨테이너 실행에 필요한 파일과 설정값 등을 모두 포함하고 있는 것을 의미
- 도커 이미지는 상태값을 가지고 있으며 변하지 않는 것이 핵심 특징
- 도커 이미지는 Docker Hub나 Docker Registry에 저장소를 직접 만들어 관리할 수 있음
- 이미지에 모든 정보가 포함되어 있기 때문에 번거로운 환경 세팅 작업이 필요가 없어짐
- Docker Container
- 컨테이너는 도커 이미지를 실행한 상태
- 이후 추가되거나 변화되는 값은 컨테이너에 저장됨
- 컨테이너의 상태가 바뀌거나 컨테이너가 삭제되더라도 이미지는 변하지 않고 원본 그대로 남아있음
- Why Docker is Fast
- 도커 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 평균 용량이 수백메가
- 기존 이미지 파일에 파일이 계속 추가되고, 수백 메가를 추가로 다운받기에는 서버 용량에 부담이 감
- 위와 같은 문제를 해결하고자 레이어 개념 사용
- 유니온 파일 시스템을 이용하여 여러 개의 레이어를 하나의 파일 시스템으로 사용할 수 있게 함
- 유니온 파일 시스템 Union File System
- 여러 개의 디렉터리를 하나의 연결된 파일 시스템으로 표현하는 파일 시스템
- Docker에서 이미지를 여러 개의 레이어로 분리하며, 각 레이어는 DockerFile의 각 명령에 의해 생성
- 레이어는 읽기 전용이며, 컨테이너가 실행될 때 읽기-쓰기 레이어가 추가되어 변경사항을 추적
- 변경사항을 추적하여 기존 레이어를 변경하지 않고도 파일 시스템의 상태 변경 (버전관리, 롤백)
- Docker Layer
- 레이어의 변경 사항은 그 이전 레이어에 영향을 주지 않음
- 즉, A + B + C에 D가 추가되면 D 레이어만 다운받으면 되기 때문에 굉장히 효율적으로 이미지 관리
- 또한, 도커는 내부적으로 레이어 재사용
- 동일한 기반 이미지를 사용하는 도커 파일이 있다면 해당 레이어를 재사용함에 따라 이미지 빌드, 배포 가속화
- 도커파일 명령어 한 줄마다 layer 작성됨
- 컨테이너 실행 시점
- 도커 내부에서 읽기-쓰기 레이어를 최상위에 추가
- 컨테이너의 모든 변경사항이 읽기-쓰기 레이어에 저장되는 로직
- 컨테이너가 삭제되면 모든 변경사항이 사라짐
- 영구적인 데이터를 저장하기 위해서는 볼륨 등 사용
9. Docker에서 OS 실행 방식
- Docker는 기본적으로 Linux 커널 기능을 사용하여 컨테이너 실행
- 따라서, 도커는 MacOS, Windows와 같은 운영체제 위에서 동작 불가하지만, 그 위에서도 사용할 수 있는 애플리케이션 제공
- 리눅스 외 운영체제에서 도커를 사용하면 실제로 리눅스 가상머신 위에서 도커를 실행하여 리눅스 커널 기능을 통해 도커 컨테이너 실행
-
Docker Desktop을 사용하면, 사용자는 Docker가 직접 MacOS 위에서 실행되는 것처럼 느낄 수 있지만, 실제로 모든 도커 컨테이너는 리눅스 VM에서 실행됨
- Docker Desktop
- Docker Desktop은 이 명령을 VM 위의 도커 데몬으로 전달하고, 이 데몬이 실제로 컨테이너를 실행하는 구조