Docker 동작 원리에 대해 알아보자

moreas·2024년 8월 18일
0

Docker

목록 보기
1/1

Docker 🐳

  • app을 패키징할 수 있는 툴
  • Application, System Tools, Dependencies 들을 하나로 묶어서 다른 서버와 OS(운영체제)에서 쉽게 배포하고 안정적으로 구동할 수 있게 도와주는 툴
    • e.g. node.js와 npm 버전 체크, 디펜던시, 환경변수 등의 설정이 필요한데 서버마다 개발자 pc마다 설치하는 것은 번거롭고 에러가 발생할 확률이 높다.
  • 도커 컨테이너 안에는 어플리케이션 뿐만 아니라 노드.js, npm, 등 어플리케이션을 구동하기 위한 런타임 환경에 대한 모든 것들을 어떤 환경에서도 동일하게 구동할 수 있도록 만들어주는 툴

Building Containers

  • 도커 파일 생성 - 이미지 생성 - 컨테이너 구동
  • Dockerfile
    • 컨테이너를 어떻게 만들어야 하는지 설명서의 역할
  • Image
    • 실행되고 있는 어플리케이션의 상태를 스냅샷해서 이미지로 만들어 둔다.
    • 만들어진 이미지는 불변의 상태
    • 객체지향 클래스와 같은 개념 (템플릿 형태로 만들어둠)
  • Container
    • 컨테이너 안에서 어플리케이션이 동작한다.
  • 템플릿 형태로 이미지를 만들어두고 이미지를 이용해 실제로 어플리케이션이 동작하는 각각의 컨테이너를 만들 수 있다.
  • 그래서 이미지는 우리가 캡처했을 당시의 프로젝트 상태를 불변으로 갖고 있음
    • 컨테이너에서 각각 동작하는 어플리케이션은 개별적으로 추가, 수정이 가능한 상태
    • 수정된 파일들은 이미지에 영향을 미치지 않는다.

Shipping Containers

  • 어떻게 컨테이너를 배포하고 이미지를 공유할 수 있는지 알아보자
  • 깃과 깃허브 사용자라면 익숙하다.
  • 로컬 머신에서 이미지를 만들어서 컨테이너 레지스트리에 push하고 필요한 서버나 다른 개발자 PC에서 내가 만들어둔 이미지를 가져와 실행하면 됨
  • 이미지를 정상적으로 실행하기 위해서는 도커와 같은 컨테이너 엔진을 설치해두어야 함
  • 우리가 이미지를 업로드할 수 있는 컨테이너 레지스트리는 퍼블릭과 프라이빗이 있는데 퍼블릭에서는 도커 허브가 가장 많이 쓰임
  • 회사에서는 프라이빗 레지스트리를 사용 (구글 클라우드, 마소, aws)
  • 어플리케이션 구동에 필요한 도커 파일 작성 후 이걸 이용해서 이미지를 만들고 이미지를 컨테이너 레지스트리에 올린 후 서버에서 다운 받아 컨테이너 실행 가능

도커란 무엇인가

  • 도커는 데이터 또는 프로그램을 격리 시키는 기능을 제공한다.
    • 왜?
      • 운영체제, 프로그램 실행 시 버전 차이 등의 문제를 해결
      • 여러 컨테이너에서 같은 프로그램도 실행 가능
  • 도커는 리눅스 운영체제에서 사용하는 것을 전제로 만들어졌기 때문에 컨테이너 안에서 동작할 프로그램도 리눅스용 프로그램이다. (종류와 상관없이 리눅스 운영체제 사용)
  • 서버란 어떤 서비스를 제공하는 걸 가리키는 것
    • 개발 현장에서 사용되는 두 가지 의미
      • 기능적 의미의 서버: 어떤 기능을 제공하는 서버 (e.g. 웹 서버, 메일 서버)
      • 물리적 서버: 물리적 컴퓨터로서의 서버.
      • 구분 하는 이유는 물리적 서버에 기능적 의미의 서버를 여러 개 둘 수 있기 때문.
  • 서버는 여러 사람이 원격으로 접근해 사용
  • 서버의 기능은 소프트웨어가 제공하는 것
  • 서버용 운영체제는 보통 리눅스를 많이 사용함

TEST

1. 도커 설치

  • Docker Desktop 설치
  • VScode 사용하는 경우 Docker 익스텐션 설치

2. 노드 프로젝트

2-1. 간단한 백엔드 환경 만들기

  • express 설치
npm inin -y 
# 초기화 
npm i express
# 익스프레스 설치
  • index.js
const express = require("express");

const app = express();

app.get("/", (req, res) => {
  res.send("🐳Docker test!🐳");
});

app.listen(8080, () => console.log("Server is running🤖"));

3. Dockerfile 만들기

  • 루트 디렉토리에 Dockerfile 생성

    • 프로젝트에 필요한 것들을 명시함

    • baseimage 사용하기

      FROM node:16-alpine
      # 숫자는 노드의 버전, alpine은 최소 단위의 리눅스 버전을 말함(os)
      # 어떤 버전의 베이스이미지를 사용할 것인지 명시 
    • 이미지 안에서 어떤 경로에서 실행할 건지 명시

      WORKDIR /app
      # WORKDIR /path/to/workdir
      # app이라는 폴더 안에 프로젝트 관련 파일을 모두 카피하겠다고 명시
      # 유닉스 명령어에서 cd와 같은 개념 
    • 프로젝트 파일들 복사하기

      • 도커파일 명령어 수행은 레이어 시스템으로 구성되어 있어 빈번히 변경되는 파일일수록 제일 마지막에 작성해주는 것이 좋다.

      • index.js는 다른 디펜던시 정보를 담고 있는 pakage.json보다 빈번히 변경 되기 때문에 하단에 배치

        COPY package.json package-lock.json ./
        # 우리 프로젝트에 모든 디펜던시를 담고 있는 pakage.json 
        # 필요한 라이브러리를 다 설치하게 됨 
        
        RUN npm install
        # install 대신 ci를 사용하면 package-lock.json에 명시되어 있는 버전 그대로를 
        # 설치하기 때문에 버전 달라지는 문제 해결
        
      • 최종 작성 파일

        FROM node:16-alpine
        
        WORKDIR /app
        
        COPY package.json package-lock.json ./
        
        RUN npm ci
        
        COPY index.js .
        # 소스파일 카피
        
        ENTRYPOINT [ "node", "index.js" ]
        # 실행하는 명령어
        
      • 도커 문법은 공식 사이트 참고

      • 도커 파일은 레이어 형태로 작성해주는 것이 좋은데 제일 빈번히 변경되는 파일을 제일 마지막에 작성하는 것이 좋다.

      • 명령어 하나 하나가 레이어로 되어 있어 자주 변경되는 걸 아래에 적으면 실행될 때는 레이어 상단으로 위치가 되기 때문에 이미지를 만들고 새로운 이미지를 만들어야 할 때 변경된 최상단 레이어만 업데이트 해주고 나머지 레이어는 다시 만들지 않아도 된다.

      • 이미지 다시 만들 때 변경되지 않은 레이어는 재사용 (캐싱), 변경된 레이어부터만 다시 빌드하도록 만듦

        ⇒ 이미지 만드는 시간 단축, 효율성 높아짐

4. 이미지 만들기

docker build -f Dockerfile -t fun-docker .
# build context . 명령어를 수행하는 현재 경로 지정
# use -f to point to a Dockerfile (어떤 도커파일 사용할 건지 명시,
# 기본적으로 도커파일이라고 작성하지만 다른 이름 지정해줄 수도 있음)
# use -t to name the image (도커 이미지에 네이밍하기. 태그 같은 개념!)
# 다양한 옵션들이 존재함

docker images
# 이미지 확인 

5. 도커 컨테이너 실행

  • 이미지 이용해 도커 실행하기
docker run -d -p 8080:8080 fun-docker
# -d stands for datached to run a container in a background
# 백그라운드에서 도커가 동작해야 하므로 (node.js 백엔드 어플리케이션이기 때문)
# 터미널이 계속 기다려야 함? 끝날 때까지 기다리지 말고 할 일 하라는 옵션 (?)
# -p is port publishing 포트 지정하는 옵션 
# maps a port on the container to a port on the host
# 호스트 머신의 8080과 컨테이너의 8080을 연결해주는 작업
# 각각의 컨테이너는 고립된, 개별적인 환경에서 동작하고 있으므로.

6. 컨테이너 확인

  • 동작하는 컨테이너에 대해 로그나 다양한 정보들을 확인하고 싶다면 컨테이너가 실행될 때 부여된 컨테이너 아이디를 이용해서 확인 가능
    docker logs 6ce1eda1c787
    # docker logs 컨테이너 ID 
  • 지금까지 했던 과정들을 터미널에서 확인하는 게 번거롭다면 도커 데스크탑 ui에서 확인할 수 있다.
  • 환경 변수나 사용하고 있는 리소스들에 대해서도 확인 가능하고
  • 컨테이너 내부에서도 자체적으로 터미널을 사용할 수 있다.

7. 도커 이미지 배포

도커의 동작 원리

  • 일반적으로 한 대의 서버 컴퓨터에는 웹 서버(아파치)를 한 벌밖에 실행하지 못한다. 그러나 도커를 사용하면 여러 컨테이너를 띄워서 여러 서버를 사용할 수 있음 → 물리 서버를 여러 대 사용하지 않아도 되는 효율성
  • 도커는 컨테이너에서 리눅스가 동작하는 것처럼 보이지만 실제로 동작하는 것은 아니다. 운영체제의 기능 중 일부를 호스트 역할을 하는 물리 서버에 맡겨 부담을 덜어둔 상태.
    • 실행 환경을 독립적으로 격리한 컨테이너
  • 가상화 기술과의 차이
    • 가상화 기술은 물리적인 부품을 소프트웨어로 구현한 것

도커 설치

03 도커 조작 방법과 명령 프롬프트 및 터미널 실행

  • 컴퓨터에 명령을 전달하는 소프트웨어를 뭉뚱그려 ‘터미널 소프트웨어’라고 한다.
  • 터미널 소프트웨어를 종료한다고 도커도 종료되는 것은 아니다.

04 컨테이너를 실행해보자

  • 도커는 64비트 컴퓨터에서만 동작함
  • SSH란? 원격으로 컴퓨터에 접속하기
  • 명령어 p.91
  • 한 번만 실행되는 컨테이너와 데몬 형태로 동작하는 컨테이너
    • 컨테이너에 따라 지정 가능한 옵션이나 인자도 달라진다. 여러 가지 옵션이나 인자를 지정할 수 있는 컨테이너가 있는가 하면, 그렇지 않은 것도 있다.
    • 특히 docker run -i, -d, -t 옵션은 자주 쓰이는 반면, 사용하지 않을 때도 많으므로 초보자에게 혼란을 일으키기 쉽다.
    • -d: 컨테이너를 백그라운드로 실행
      • -d를 붙이지 않고 컨테이너 실행하면 프로그램의 실행을 마칠 때까지 터미널의 제어를 차지하므로 그다음 명령을 입력할 수 없는 상태가 된다.
    • -i 와 -t: 컨테이너 내부에 터미널로 접속하기 위해 사용
      • 옵션 붙이지 않으면 컨테이너 안의 파일 시스템에 접근할 수 없다.
    • 데몬
      • 유닉스 또는 리눅스에서 동작하는 프로그램 중에서 백그라운드에서 항상 동작하는 프로그램을 관례적으로 일컬어 데몬이라고 한다. 메일 전달 실패 등을 알려주는 ‘메일러 데몬’이 유명
  • 컨테이너의 통신
    • 아파치: 웹 서버 기능을 제공하는 소프트웨어다.
cmd 컨테이너 DB 조회 방법

1. 컨테이너에 접근 : `docker exec -it ${container_name} bash;`
2. mariaDB 실행 : `mariadb -u root -p;` 이후 패스워드 입력
3. Database 조회 : `show databases`;
4. Database 선택 : `use ${database_name};`
5. Table 조회 : `show tables;` 
6. DB schema 조회 : `desc ${table_name};` (각 컬럼들 자료형 조회)
7. DB 데이터 확인 : `select * from ${table_name};`
profile
Everything is connected 🐶 좀 더 나은 개발을 위해

0개의 댓글