본문 바로가기
42Seoul/Inception

Inception 개념

by 하고싶은건많은놈 2023. 3. 2.

VM(Virtual Machine) vs Container

  • VM
    Hypervisor 위에 Guest OS를 띄우고 실행
    각 VM은 완전히 독립된 환경을 구성하며, 최근에는 반가상화(para-virtualization) 방식을 사용
    단, 시스템 자원의 가상화는 하이퍼바이저를 거치기 때문에 성능 손실이 발생하며 운영체제 전체를 포함하기 때문에 배포하기 위한 이미지의 크기 또한 커짐
  • Container
    OS 수준이 아닌 애플리케이션 수준에서 이루어지는 가상화
    커널 하나에 프로세스 단위의 격리 환경인 여러 개의 사용자 공간 인스턴스가 포함될 수 있도록 하며, 이를 컨테이너라고 부름
    호스트 OS의 커널을 공유하기 때문에 해당 커널에 맞는 컨테이너만 사용 가능하며, 컨테이너 내에는 라이브러리 및 실행파일만 존재
    리소스 효율성과 유지관리 측면에서 장점이 있음

Docker

컨테이너 기반의 오픈소스 가상화 플랫폼 - 컨테이너를 생성하는 프로그램

아래와 같이 구성되어있음

  • Docker Client : 도커 명령어를 수행
  • Docker Host : 도커가 띄워져있는 서버
  • Docker daemon : 도커 엔진
  • Registry : 외부 이미지 저장소, 해당 이미지를 내부 도커 호스트에서 사용할 수 있음

도커의 컨테이너에서는 이미지의 개념이 가장 중요

도커에서 이미지란, 컨테이너 실행에 필요한 파일과 설정값 등을 포함한 것을 뜻함

이미지를 Docker Host에서 실행(run)하면 새로운 컨테이너가 생성

  • 이미지는 레이어(layer) 개념으로 구성되어있기 때문에 효율적인 관리가 가능
  • Public인 Docker hub에 등록되어있는 이미지는 'docker.io/library/ubuntu:14.04' 와 같은 url 형식으로 관리되며, 'docker.io/library'는 생략 가능
  • 도커의 이미지를 생성하기 위한 스크립트(설정파일)인 Dockerfile 이 존재하며, 이미지 구성 변경시 Dockerfile의 수정을 통해 관리할 수 있음

Dockerfile

Dockerfile의 실제 파일명 자체는 반드시 Dockerfile 이어야 함

Dockerfile에 사용되는 키워드들이 존재

  • FROM <이미지>:<태그>
    베이스 이미지 지정 명령으로 Dockerfile 내에 반드시 존재해야함
    태그 생략시 latest가 디폴트로 붙음

  • MAINTAINER <자유형식>
    이미지를 생성한 사람의 정보를 입력, 없어도 무방

  • RUN <명령어>
    FROM에서 설정한 이미지 위에서 명령어를 실행시킴 = 이미지 레이어를 만들어
    쉘 명령은 FROM에서 가져온 이미지의 /bin/sh 실행파일을 이용
    실행 결과는 캐시되기 때문에 다음 빌드시 재사용되며, 재활용이 불필요할시 --no-cache 옵션을 사용

  • CMD / ENTRYPOINT <명령어>
    컨테이너 시작 후 가장 먼저 실행될 명령어 지정
    하나의 Dockerfile에 한 개씩만 존재해야하며, 작업할 내용이 없을시 없어도 무방
    ENTRYPOINT가 정의되어있다면 docker run 명령 실행시 반드시 ENTRYPOINT에서 지정한 명령을 수행
    CMD가 정의되어있다면 docker run 명령 실행시 인자값이 있을 경우 CMD에서 지정한 명령 대신 인자값의 명령을 수행
    컨테이너 수행시 변경되지 않을 내용은 ENTRYPOINT로, 메인 명령어 실행시 default option 인자값은 CMD로 정의하는 것이 추천되며 둘 모두 리스트 포맷 ["args1", "args2", ...]으로 정의하는 것을 권장

  • WORKDIR <디렉토리>
    RUN / CMD / ENTRYPOINT에서 설정한 실행파일이 실행될 디렉토리 위치 지정

  • ADD / COPY <복사할 파일 경로(호스트)> <파일이 위치할 경로(이미지 내부)>
    파일을 이미지에 추가
    Dockerfile이 존재하는 경로의 하위경로에 존재하는 파일(하위 디렉토리 자체도 가능)만 이미지 내부로 추가할 수 있음
    ADD의 경우 압축된 파일은 자동으로 압축 해제되며, 파일의 URL을 이용하여 웹에서 가져올 수도 있음
    이미지 내부 경로 마지막에 '/'를 붙이면 새로운 디렉토리를 생성한 후 그 아래에 파일을 추가함
    해당 키워드에서 사용하는 경로는 반드시 절대경로여야 함

  • ENV <환경변수> <값>
    환경변수 설정, RUN / CMD / ENTRYPOINT에 즉각 반영됨
    docker run -e <환경변수>=<값> <이미지이름> 으로도 지정 가능

  • EXPOSE <컨테이너 포트번호>
    호스트와 컨테이너간의 포트 번호 매핑
    docker run -P 명령 이용시 호스트의 랜덤한 포트 번호가 해당 컨테이너 포트번호로 매핑됨
    docker run -p <호스트 포트번호> <컨테이너 포트번호> 로도 매핑할 수 있음

  • VOLUME <디렉토리> 또는 ["디렉토리1", "디렉토리2"]
    지정된 디렉토리는 컨테이너에 저장하지 않고 호스트의 /var/lib/docker/volumes/[hash값으로 자동생성된 디렉토리]에 장
    컨테이너의 데이터를 보존하기 위해 사용

  • USER <사용자계정>:<그룹명> 또는 <UID>:<GID>
    명령을 실행할 사용자 계정 설정, RUN / CMD / ENTRYPOINT에 즉각 반영
    그룹명과 GID는 생략 가능

  • STOPSIGNAL <시그널>
    docker stop시 기본적으로는 SIGTERM을 사용

Docker 명령어

  • docker search <이미지> : Docker Hub에서 사용가능한 이미지 검색
  • docker pull <이미지> : Docker Hub로부터 이미지를 다운
  • docker images : 현재 호스트에 다운받은 이미지들을 출력
    • docker image rm <image ID> : 도커 단일 이미지 삭제
    • docker rmi $(docker images -q) -f : 도커 모든 이미지 삭제
  • docker run <옵션> --name <컨테이너이름> <이미지> : 도커 컨테이너 생성 및 실행
    • -i : 사용자가 입출력을 할 수 있는 상태
    • -t : 가상 터미널 환경을 에뮬레이션
    • -d : 컨테이너를 일반 프로세스가 아닌 데몬프로세스 형태로 실행해 프로세스가 끝나도 유지되도록
    • -p <호스트 포트>:<컨테이터 포트> : 포트포워딩
  • docker create <옵션> --name <컨테이너이름> <이미지 레포> : 도커 컨테이너 생성
  • docker exec -it <컨테이너이름> /bin/bash : 컨테이너 접속
  • docker attach <컨테이너이름> : 컨테이너 접속, 처음 도커 컨테이너를 run 하였을때의 환경이 포그라운드로 보여짐
    • attach는 로컬 머신의 표준 입출력을 해당 컨테이너와 연결, 직접 명령 및 제어가 가능
      단, 컨테이너 내 기본 프로세스가 백그라운드에서 실행되는 형태라면 프로세스의 확인 및 제어가 어려울 수 있음
    • exec은 컨테이너 외부에서 접근해 코드를 작동
  • docker ps : 실행중인 컨테이너 리스트 확인, -a 옵션 적용시 모든 컨테이너 리스트 확인
  • docker start <컨테이너이름> : 컨테이너 실
  • docker stop <컨테이너이름> : 컨테이너 종료
  • exit / ctrl+D : 컨테이너 종료
  • ctrl+P 입력 후 Q : 컨테이너 가동상태를 유지하면서 접속만 종료
  • docker rm <컨테이너이름> : 컨테이너 삭제
  • docker system prune : 사용하지 않는 Docker 컨테이너 리소스 전부 삭제

Docker-compose

여러 개의 컨테이너로 이루어진 서비스를 구축 및 실행하는 순서를 자동화하여 관리를 간단히하는 기능

.yml 확장자를 가진 compose 파일에 정의되어있는 내용을 바탕으로 서비스할 컨테이너들을 관리

도커 버전에 따라 도커 컴포즈의 버전을 맞춰서 사용해야하며, 아래 링크를 참조

https://docs.docker.com/compose/compose-file/compose-file-v3/

 

Compose file version 3 reference

 

docs.docker.com


Docker-compose 명령어

docker-compose 명령은 docker-compose.yml을 저장한 디렉토리에서 실행해야함

다른 디렉토리에서 실행할시 -f 옵션으로 compose 파일 경로의 지정이 필요

  • docker-compose up <옵션> <서비스명> : 컨테이너 생성
    • -d : 백그라운드에서 실행
    • -f : 사용할 설정 파일 지정, 지정하지 않을시 docker-compose.yml 또는 .yaml 사용
    • --build : 이미지를 빌드 (아래의 docker-compose.yml 항목에서 자세히 설명)
    • --env-file : 사용할 환경 설정 파일 지정, 지정하지 않을시 .env 파일을 사용
  • docker-compose down <옵션> : 컨테이너 정지 후 삭제
  • docker-compose rm : 정지되어있는 컨테이너만 삭제
  • docker-compose ps : 컨테이너 확인
  • docker-compose run <컨테이너> <명령> : 컨테이너에서 명령 실행
  • docker-compose start : 컨테이너 시작, 인자에 서비스 입력시 해당 서비스만 시작
  • docker-compose stop : 컨테이너 정지, 인자에 서비스 입력시 해당 서비스만 정지
  • docker-compose restart : 컨테이너 재시작, 인자에 서비스 입력시 해당 서비스만 재시작
  • docker-compose pause : 컨테이너 일시정지, 인자에 서비스 입력시 해당 서비스만 일시정지
  • docker-compose unpause : 컨테이너 일시정지 재개, 인자에 서비스 입력시 해당 서비스만 재개
  • docker-compose port <옵션> <컨테이너> <포트 번호> : 서비스의 공개용 포트 확인
  • docker-compose config :  compose 구성 확인
  • docker-compose kill : 실행중인 컨테이너에 시그널을 송신하여 강제 정지, 기본은 SIGKILL 송신이며 -s <시그널 종류>로 시그널 지정 가능

docker-compose.yml

version: '3'

services:
  wordpress:
    depens_on:
      - mariadb
    image: wordpress:latest
    port:
   	  - "60000:80"
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: example username
      WORDPRESS_DB_PASWORD: example password
      WORDPRESS_DB_NAME: wordpress
    restart: always

  nginx:
    depends_on:
      - wordpress
    container_name: nginx
    build: .
    port:
   	  - "8080:80"
    volumes:
      - data:/var/www/html

사용하고자 하는 docker-compose 버전 기입 후, 기본적으로 services: 구문으로 시작

만들고자 하는 컨테이너들마다 필요한 항목을 넣어 작성

  • image : Docker Hub에서 이미지를 가져와 컨테이너 생성
  • build : 이미지 생성에 사용할 Dockerfile의 위치 지정
  • environment : 환경변수 정의
  • ports : 호스트 포트와 컨테이너 포트 매핑
  • expose : 컨테이너 실행시 요청을 기다리는 listen 포트 지정
  • depens_on : 의존성 추가, 컨테이너의 실행 순서를 결정
  • container_name : 컨테이너 이름 설정
  • restart : 컨테이너의 프로세스가  종료되었을시의 동작을 결정
    • no : 기본값, 컨테이너를 재시작하지 않음
    • always : 컨테이너를 항상 다시시작
    • on-failure : 오작동으로 종료되었을 때만 컨테이너 다시 시작
  • volumes : 호스트의 디렉토리를 컨테이너 디렉토리에 마운트

PID 1

Linux 등 대다수 OS에서 첫번째 PID는 초기에 실행되는 Init 프로세스가 할당받음

Init 프로세스는 부팅시 최초의 프로세스가 되는 데몬으로 모든 프로세스의 직/간접적 부모 프로세스 역할을 하여 좀비 프로세스를 방지함
그러나 도커의 경량 컨테이너에는 Init 시스템이 없기 때문에 실행된 애플리케이션이 PID 1에 할당됨

이 때 PID 1은 성격상 정상적으로 시그널 처리를 할 수 없기 때문에 문제가 생길 수 있음

따라서 dumb-init, tini 등의 기능을 사용하기도 함

 

'42Seoul > Inception' 카테고리의 다른 글

Inception 기초 설정  (0) 2023.03.03

댓글