코드스테이츠 백엔드 부트캠프 74일차 - [Cloud] 배포 컨테이너 - Docker

wish17·2023년 3월 30일
0
post-thumbnail

도커 명령어, 옵션 등 사용법

Docker

Docker

  • 실행 환경에 구애받지 않고 애플리케이션을 실행할 수 있게 해주는 프로그램
    • OS에 상관없이 즉시 애플리케이션 실행 환경을 만들 수 있다.
  • 컨테이너 방식으로 애플리케이션을 실행시킨다.
    • 개발을 컨테이너 위에서 진행할 경우, 모든 개발팀이 동일한 환경 하에 개발을 진행할 수 있다.
    • 도커 컨테이너를 EC2 서버에서 실행할 수 있게 하는 서비스인 ECS를 이용하여 애플리케이션 배포를 쉽게 할 수 있다.

컨테이너 방식의 장점

의존성 충돌 문제를 해결해 준다.

  • 개발과 배포 환경을 일치시킨다.
  • 수평 확장을 쉽게 해준다.
  • 각 서버에 새로운 내용을 배포하기 쉽게 만들어준다.

컨테이너 방식이 격리하는 것

프로세스

  • 특정 컨테이너에서 작동하는 프로세스는 기본적으로 그 컨테이너 안에서만 액세스할 수 있다.

  • 컨테이너 안에서 실행되는 프로세스는 다른 컨테이너의 프로세스에게 영향을 줄 수 없다.

네트워크

  • 기본으로 컨테이너 하나에 하나의 IP 주소가 할당되어 있다.

파일 시스템

  • 컨테이너 안에서 사용되는 파일 시스템은 구획화되어 있다. 그래서 해당 컨테이너에서의 명령이나 파일 등의 액세스를 제한할 수 있다.

확장성

접속자가 많아서 서버에 부하가 많이 늘면 트래픽 분산을 위해 프록시 서버를 운영하며, 프록시 서버는 여러 대의 동일한 검색 서버 중 한 군데를 이용할 수 있도록 돕는다. (이러한 서버를 리버스 프록시의 한 종류인 '로드 밸런서'라고 부른다)

이렇게 여러서버에서 애플리케이션을 실행시켜야 할 때, 컨테이너 기술을 이용하면 동일한 애플리케이션 구성(이미지)을 바탕으로 새로운 서버에 해당 애플리케이션을 컨테이너로 실행하고, 로드 밸런서에 이 서버를 추가하기만 하면 된다.

  • 여러 서버 중 몇대만 테스트하고 배포해도 상관X

간단하게 말하자면 컨테이너 방식은
서버 갯수를 늘릴 때, 똑같은 컨테이너 복붙하면 어떤 서버건 똑같이 실행하니 각 서버에 맞춰서 리펙토링할 필요가 없으니 확장성이 좋은거다!!

핵심 키워드

컨테이너

  • 컨테이너는 애플리케이션이 의존성, 네트워크 환경, 파일 시스템에 구애받지 않고, 도커라는 기술 위에 실행될 수 있도록 만든 애플리케이션 상자다.

이미지

  • 애플리케이션 및 애플리케이션 구성을 함께 담아놓은 템플릿

  • 실행되는 모든 컨테이너는 이미지로부터 생성된다.

  • 이미지를 이용해 즉시 컨테이너를 만들 수 있다.

  • 이미지를 이용해 여러 개의 컨테이너를 생성할 수 있다.
    (수평 확장 가능)

  • 기본 이미지(base image)로부터 (마치 git을 사용하는 것처럼) 변경 사항을 추가/커밋해서 또 다른 이미지를 만들 수도 있다.

레지스트리

  • 이미지가 저장되는 곳

  • 대표적인 이미지 레지스트리로는 Docker Hub, Amazon ECR이 있다.

  • 도커 CLI에서 이미지를 이용해 컨테이너를 생성할 때, 호스트 컴퓨터에 이미지가 존재하지 않는다면, 기본 레지스트리로부터 다운로드 받게 된다.


컨테이너 VM 비교

컨테이너와 VM 둘 다 가상화 기술로 개발 및 운영의 효율성을 높이기 위해 사용된다.

컨테이너

  • 애플리케이션과 그 종속성을 패키지화하여 일관된 환경을 제공하는 가벼운 가상화 기술

  • 작동원리: 호스트 OS의 커널과 공유하며, 각 컨테이너는 독립된 프로세스와 파일시스템을 가진다.

VM (가상 머신)

  • 하드웨어를 에뮬레이션하여 물리적 서버 위에 다양한 OS와 애플리케이션을 실행할 수 있는 환경

  • 작동원리: 하이퍼바이저를 통해 물리적 자원을 가상화하고 각각의 VM에 할당한다.

공통점 및 차이점


격리

공통점: 둘 다 프로세스, 네트워크, 파일 시스템을 격리할 수 있다.

차이점: 컨테이너는 프로세스 수준에서 격리되어 있고, VM은 완전한 OS 수준에서 격리된다.

작동원리

컨테이너는 호스트 OS의 커널을 공유하고, VM은 하이퍼바이저를 통해 자원을 가상화한다.

컴퓨팅 자원

컨테이너의 자원 사용이 더 효율적이다.
VM은 만들고 실행하는 과정에서 많은 컴퓨팅 자원을 필요로 한다.

OS

공통점: 둘 다 여러 애플리케이션을 독립적으로 실행할 수 있는 환경을 제공한다.

차이점: 컨테이너는 호스트 OS와 같은 커널을 사용하고, VM은 각각 독립적인 OS를 가진다.

차이점 요약

특징

컨테이너

가상 머신

정의

애플리케이션의 코드, 라이브러리 및 애플리케이션 실행 환경을 구성하는 기타 종속 구성 요소가 포함된 소프트웨어 코드 패키지다.

물리적 시스템의 디지털 복제본이다. 물리적 하드웨어를 여러 환경으로 분할한다.

가상화

운영 체제를 가상화한다.

기반 물리적 인프라를 가상화한다.

캡슐화

애플리케이션 또는 애플리케이션 구성 요소를 실행하는 데 필요하며 운영 체제보다 상위에 있는 소프트웨어 계층이다.

운영 체제, 그 위의 모든 소프트웨어 계층, 그리고 여러 애플리케이션을 포함한다.

기술

컨테이너 엔진은 기반 운영 체제와 리소스를 조율한다. 

하이퍼바이저는 기반 운영 체제 또는 하드웨어와 조율된다. 

크기

상대적으로 더 작다(MB 단위).

상대적으로 훨씬 더 크다(GB 단위).

제어

컨테이너 외부 환경에 대한 제어 권한이 적다.

전체 환경을 보다 효과적으로 제어할 수 있다.

유연성

더 유연합니다. 온프레미스 환경과 클라우드 중심 환경 간에 신속하게 마이그레이션할 수 있다.

유연성이 떨어진다. 마이그레이션에 어려움이 있다.

확장성

확장성이 뛰어납니다. 마이크로서비스를 통해 세분화된 확장이 가능하다.

확장하는 데 비용이 많이 들 수 있다. 비용 효율적인 확장을 위해서는 온프레미스에서 클라우드 인스턴스로 전환해야 한다.

  컨테이너에 대해 자세히 알아보기 상 머신에 대해 자세히 알아보기

 



Docker CLI

도커를 이용하는 데 있어서 명령어, 옵션 등 사용법은 Docker docs에서 확인 가능

이미지 주소

Registry_Account/Repository_Name:Tag

//예시
docker/whalesay:latest
danielkraic/asciiquarium:latest

레지스트리(Registry)

  • Docker Hub
  • 도커 이미지를 관리하는 공간이다.
  • 특별히 다른 것을 지정하지 않는다면, 도커 허브(Docker Hub)를 기본 레지스트리로 설정한다.
  • 레지스트리는 Docker Hub, Private Docker Hub, 회사 내부용 레지스트리 등으로 나뉠 수 있다.

레포지토리(Repository)

  • 레지스트리 내에 도커 이미지가 저장되는 공간이다.
  • 이미지 이름이 사용되기도 한다.
  • GitHub의 레포지토리와 유사하게 생각하면 된다.

태그(Tag)

  • 같은 이미지라고 할지라도 버전 별로 안의 내용이 조금은 다를 수 있다.
  • 해당 이미지를 설명하는 버전 정보를 주로 입력한다.
  • 특별히 다른 것을 지정하지 않는다면 latest 태그를 붙인 이미지를 가져온다.

실습

실습환경 설정

윈도우 환경에서 우분투를 이용해 실습을 진행했다.

  • 우분투에서 Docker Engine + Docker Compose 설치
  • Docker Desktop설치
    • Docker Desktop을 실행해야지만 우분투에서 Docker 명령어가 동작함
    • sudo systemctl start docker를 써서 실행하라는건 맥os인듯

혹시라도 Desktop키고도 명령어 안되면 아래 명령어 사용

# run : 실행한다.
# --privileged : 호스트의 모든 장치를 사용한다는 의미 (기본적으로 도커의 컨테이너는 보안상의 이유로 호스트 장치에 접근할수 없게 되어 있다.)
# -d : 백그라운드로 실행..
# --name centos : 컨테이너 이름은 centos로 지정
# centos : 이미지 이름
# /sbin/init : sbin/init를 실행

docker run --privileged -d --name centos centos /sbin/init

기본 명령어 정리

//docker 실행 window환경에서는 안됨 ㅠㅡㅠ
sudo systemctl start docker

//docker/whalesay의 최신 이미지를 받아오기
docker image pull [이미지이름]

//이미지 리스트를 출력
docker image ls

// 이미지 실행(컨테이너 생성)
docker container run [컨테이너이름] [이미지 주소] [컨테이너 실행과 동시에 동작할 명령어] [명령어에 넘겨질 파라미터]
docker container run --name [컨테이너 이름] [이미지 주소] [컨테이너 실행과 동시에 동작할 명령어] [명령어에 넘겨질 파라미터]

docker container run --name 컨테이너_이름 docker/whalesay:latest cowsay boo


// 컨테이너 삭제
docker container rm [컨테이너 이름]

// 이미지 정보(이름, 용량 등) 확인
docker image ls

// 이미지 지우기
docker image rm [이미지주소]
docker rmi

docker image rm docker/whalesay
docker rmi docker/whalesay

// 이미지 실행(컨테이너 생성) + 컨테이너 실행 + 컨테이너 삭제
docker container run --name 컨테이너_이름 --rm docker/whalesay cowsay boo

// danielkraic라는 사람이 올린 이미지 asciiquarium 를 실행
docker container run -it --rm danielkraic/asciiquarium:latest
  • it : -i, -t 를 동시에 사용한 옵션이다. 사용자와 컨테이너 간에 인터렉션(interaction)이 필요하다면 이 옵션을 사용한다. 이 예제에서는 출력되는 화면을 사용자가 지속적으로 보기 위해서 사용하였습니다. 예를 들어 Python 명령이 필요하거나 추가로 다른 입력을 받는다면, 이 옵션을 지정한 뒤 사용한다.

  • container 는 ctrl + c 로 종료할 수 있다.

로컬에 있는 파일과 도커 이미지를 연결하는 방법

  1. CP(Copy)

    • 호스트와 컨테이너 사이에 파일을 복사(Copy)
    • docker container cp ./[복사할 파일 로컬 경로] [컨테이너_이름]:[저장할 웹 경로]
  2. Docker Volume

    • 호스트와 컨테이너 사이에 공간을 마운트(Mount)

httpd 웹 서버

  • 도커 이미지인 httpd(http daemon)를 사용해 웹 서버에 접속할 수 있다.

  • httpd(http daemon)은 Apache HTTP Server를 실행할 수 있는 오픈소스 웹 서버 소프트웨어다.

  • httpd 는 /usr/local/apache2/htdocs/ 경로에 웹 서버와 관련된 파일들이 저장되어 있다면, 해당 파일을 기반으로 웹 서버가 실행되도록 한다.

httpd 사용법

  1. httpd 컨테이너 생성 + 실행
docker container run --name [컨테이너_이름] -p 818:80 httpd
  • -p 옵션은 로컬호스트의 포트와 컨테이너의 포트를 연결한다.
    위 명령어에서 818포트가 로컬호스트의 포트이고, 80번은 컨테이너의 포트다.

  • httpd 는 일정 시간 연결 기록이 없으면, 서버 가동이 중지된다.

cf. 이후과정은 다른텝에서 수행하거나 -d 옵션을 이용해서 백그라운드 실행하자.

  1. 애플리케이션 폴더를 웹 경로에 복사
// 현재 폴더의 파일을 뒤 경로에 복사
docker container cp ./[복사할 파일 로컬 경로] [httpd컨테이너_이름]:[저장할 웹 경로]
sudo docker container cp ./ httpdserver:/usr/local/apache2/htdocs/

Docker 이미지 만들기

1. 구동한 Docker Container를 이미지로 만드는 방법

 docker container commit [httpd 컨테이너_이름] [만든 이미지 주소 명명]
 docker container commit 컨테이너_이름 my_pacman:1.0
 docker container commit httpdserver my_pacman:1.0
  • 생성된 이미지를 900 포트에서 웹 서버로 구동
docker run --name [컨테이너_이름] -p 900:80 [이미지 주소]
docker run --name my_web2 -p 900:80 my_pacman:1.0

2. Docker Image 빌드를 위한 파일인 Dockerfile 로 만드는 방법

Dockerfile

  • 이미지 파일의 설명서
  • 이미지 만드는 파일

(1) - Dockerfile을 작성

# 베이스 이미지를 httpd:2.4 로 사용
FROM httpd:2.4

# 컨테이너 내의 작업 디렉토리를 설정
WORKDIR /usr/local/apache2

# 호스트의 현재 경로(./)에 있는 파일을 생성할 이미지 /usr/local/apache2/htdocs/ 에 복사합니다.
COPY ./ /usr/local/apache2/htdocs/ 

# 호스트의 파일 경로를 지정하고, 이를 생성할 이미지 /usr/local/apache2/htdocs/에 복사한다.
COPY {웹 서버 실행에 필요한 파일의 경로 1} /usr/local/apache2/htdocs/
COPY {웹 서버 실행에 필요한 파일의 경로 2} /usr/local/apache2/htdocs/

(2) - Dockerfile 빌드 (이미지 생성)

docker build --tag 이미지명 .

(3) - 컨테이너 생성 및 실행

docker container run --name [만들 컨테이너_이름] -p 8181:80 [실행할 이미지]

컨테이너 속 들어가기

//입장
docker exec -it 컨테이너_이름 bash

//나오기
exit

위 명령어를 사용하여 컨테이너 내부에 들어가 파일을 생성하거나 수정한 뒤, exit로 나오면 변경 사항은 해당 컨테이너 내부에 일시적으로 저장된다.

그러나 이렇게 변경한 내용은 컨테이너의 기본 파일 시스템에만 저장되기 때문에, 컨테이너를 삭제하거나 재시작할 경우 변경 사항이 사라질 수 있다.

컨테이너에서 변경한 내용을 영구적으로 보존하려면 아래 명령어처럼 볼륨(Volume) 기능을 사용해야 한다.

docker container run --name [컨테이너_이름] -p 8181:80 -v my_volume:/usr/local/apache2/htdocs httpd

위 예시들처럼 -v 옵션을 사용하여 컨테이너 내부의 디렉토리와 호스트의 디렉토리를 연결하거나 도커에서 관리되는 볼륨을 사용하면, 컨테이너 내부에서 변경한 파일이 호스트에도 영구적으로 저장된다. 이를 통해 컨테이너를 재시작하거나 삭제해도 변경 사항이 유지된다.


n 개의 Docker Image를 다루는 방식

  • Docker compose docs를 이용하면 여러개의 이미지를 한번에 다룰 수 있다.
    • ex) 프론트 + 백엔드 + 데이터베이스 3개 한번에 사용

1. docker-compose.yaml 파일 생성

nano docker-compose.yaml

위 명령어를 이용해 docker-compose.yaml파일을 만들고 아래와 같은 방식으로 구성한다.
(cf. yaml, yml은 같은 확장자다.)

version: '3.8'
        
services:
  nginx:
    image: sebcontents/client
    restart: 'always'
    ports:
      - "8080:80"
    container_name: client
        
  spring:
    image: 0xnsky/server-spring
    restart: 'always'
    ports:
      - "4999:3000"
    container_name: server-spring
    volumes:
      - "./volumefolder:/data"
        
  mysql:
    image: mysql:latest
    restart: 'always'
    ports:
      - "3307:3306"
    container_name: database
    environment:
      MYSQL_ROOT_PASSWORD: root_계정_비밀번호
      MYSQL_DATABASE: 초기_생성_데이터베이스
      MYSQL_USER: 유저_이름
      MYSQL_PASSWORD: 유저_패스워드

2. yml 파일 실행

docker-compose up -d


추가적으로 오픈소스 게임들을 이용해 aws EC2 서버에 올려봤다.
(첨부한 아래 링크는 23.04.15 이후 닫힘)

http://ec2-3-35-13-60.ap-northeast-2.compute.amazonaws.com:818/

http://ec2-3-35-13-60.ap-northeast-2.compute.amazonaws.com:443/

0개의 댓글