리눅스데브코스 [16주차 - 2]<리눅스 컨테이너와 Docker (5)>

심우열·2023년 8월 8일
0

1. 컨테이너 이미지 크기에 대한 고찰

1. 이미지는 레지스트리를 통해 공유될 수 있다

  • 이미지는 공간을 차지
  • 차지하는 공간이 크면 전송비용, 보관 비용이 증가

2. 이미지는 컨테이너로 전개될 수 있다

  • 이미지를 전개하면 내용이 컨테이너 스토리지를 구성
  • 이미지의 크기 == 컨테이너가 차지하는 공간의 크기
  • 운영 시스템의 디스크 공간 비용 증가
  • 컨테이너 전개 전환 시간 증가

3. 따라서 이미지는 가급적 작게

  • 전송 비용, 보관 비용 절감
  • 컨테이어 운영 비용 절감
  • 빠른 컨테이너 전개 속도

2. 이미지 크기를 줄이는 방법

컨테이너 전개 후 동작에 필요한 것만 남기기

  • 운영에 불필요한 파일은 있지 않아도 됨

ex)

  • man 문서
    -> 쉘 사용자는 필요하지만 동작하는 애플리케이션은 필요로 하지 않음

1. Multi Stage Build 이전

Dockerfile로 이미지 생성시 리소스를 직접 정리

  • 개발 버전과 프로덕션 버전을 나눠서 관리
  • 프로덕션 버전에선는 가급적 레이어를 적게 생성
    -> RUN 구문을 최대한 적게 사용

방법

  • 첫번째 개발 단계 이미지를 빌드
  • 아티팩트를 복사하기 위해 컨테이너를 생성
  • 생성된 컨테이너에서 아티팩트를 추출해 두번째 프로덕션 단계 이미지를 빌드

예시

#!/bin/sh
echo Building alexellis2/href-counter:build
docker build -t alexellis2/href-counter:build . -f build.Dockerfile
docker container create --name extract alexellis2/href-counter:build
docker container cp extract:/go/src/github.com/alexellis/href-counter/app ./app
docker container rm -f extract
echo Building alexellis2/href-counter:latest
docker build --no-cache -t alexellis2/href-counter:latest .
rm ./app

2. Multi Stage Build

1. Multi Stage Build란?

하나의 Dockerfile에서 앞의 상황을 작성

  • 각기 서로 다른 베이스 이미지를 사용하고
  • 각 단계간 필요한 파일을 복사할 수 있음

2. Multi Stage Build 예시

# syntax=docker/dockerfile:1
# 빌드 단계
FROM golang:1.16
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go ./
RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o app .
# 프로덕션 단계
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app ./
CMD ["./app"]

--from=0 은 FROM 구문을 기점으로 index를 나누어 지정하는 방식

  • Dockerfile에 수정이 발생하면 index가 변경되거나 찾기 힘들다는 단점

-> From 구문에 이름을 주어 이를 해결

3. Multi Stage Build 각 단계에 이름 부여

# 빌드 단계
FROM golang:1.16 AS builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go ./
RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o app .
# 프로덕션 단계
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app ./
CMD ["./app"]

FROM golang:1.16 AS builder

-> COPY --from=builder /go/src/github.com/alexellis/href-counter/app ./

4. 단계 이름을 사용해 특정 단계 까지만 진행

docker build --target builder -t w10sim/MultiStageBuild:latest

builder 단계까지만 진행

  • 특정 빌드 단계의 디버깅 혹은 테스팅에 유용

5. 이전 단계를 새 단계로 사용

# syntax=docker/dockerfile:1
FROM alpine:latest AS builder
RUN apk --no-cache add build-base

FROM builder AS build1
COPY source1.cpp source.cpp
RUN g++ -o /binary source.cpp

FROM builder AS build2
COPY source2.cpp source.cpp
RUN g++ -o /binary source.cpp

3. 새롭게 지원되는 Buildkit

1. 기존 builder와 buildkit의 차이점

기존의 Builder

  • 어떤 단계를 지정하면 해당 단계에 선행한 모든 단계를 처리
  • 불필요해도 선행해서 기술했다면 실행(의존관계 처리 안함)

Buildkit

  • 의존관계 분석에 따라, 의존성이 있는 선행 단계만 처리

2. Buildkit 사용 방법

1. 예시

# syntax=docker/dockerfile:1
FROM ubuntu AS base
RUN echo "base"
FROM base AS stage1
RUN echo "stage1"
FROM base AS stage2
RUN echo "stage2"

2. Buildkit을 이용한 빌드

DOCKER_BUILDKIT=1 docker build --no-cache -f Dockerfile --target stage2
  • DOCKER_BUILDKIT=1 : BUILDKIT 활성화
  • stage 1은 실행이 되지 않는것을 알 수 있다

3. 직접 해보기

1. 예시 선택

Rhymond/product-compare-react

2. 예시 분석

  • React + Redux + Bootstrap +SASS 사용

빌드 준비물

  • Node JS
  • NPM or YARN

3. 직접 빌드 해보기

1. ubuntu 20.04 환경 사용

docker run -it --name product-compare-react-builder -p 8000:80 -p 3000:3000 ubuntu:20.04 /bin/bash

  • 8000 : nginx
  • 3000: react

2. NodeJS 와 NPM 설치

apt update
apt install nodejs npm
node --version
npm --version

NodeJS의 버전이 너무 낮아 삭제후 재설치

apt purge --auto-remove nodejs npm
apt install -y curl
curl -sL https://deb.nodesource.com/setup_14.x | bash -
apt install -y nodejs
node --version
npm --version

3. Git Clone 해오기

apt install -y git
mkdir /app
cd /app
git clone https://github.com/Rhymond/product-compare-react.git

4. 빌드해보기

1. 필요한 의존성 준비

cd /app/product-compare-react
npm install

오류 발생

2. python2.x 설치 후 의존성 준비

apt install -y python2 build-essential
PYTHON=/usr/bin/python2 npm install

오류 발생

3. --no-fund 옵션 사용

npm install --no-fund

성공

4. 빌드

npm run build

5. 서비스 실행 해보기

npm start

localhost:3000

4. 빌드 결과를 Nginx로 서비스 하기

  • 빌드 결과물 위치: /app/product-compare-react/build

1. Nginx 설치하기

# ctrl+c 로 서비스 중지
apt install -y nginx

2. Nginx 실행

service nginx start

3. 접속해보기

localhost:8000

4. 빌드 내용 넣고 재접속

cp –R /app/product-compare-react/build/* /var/www/html/

localhost:8000

4. Dockerfile로 해보기

1. 빌드 단계

1. Dockerfile

FROM node:14 as builder
RUN mkdir /app
WORKDIR /app
RUN git clone https://github.com/Rhymond/product-compare-react.git
WORKDIR /app/product-compare-react
RUN npm install && npm run build

2. 이미지 빌드

docker build .

3. 이미지 확인

2. 런타임 단계: Nginx

1. Dockerfile

FROM nginx:latest
COPY --from=builder /app/product-compare-react/build /usr/share/nginx/html

2. 이미지 빌드

docker build -t w10sim/react:example .

3. 이미지 확인

3. 실행해보기

docker run -p 8000:80 w10sim/react:example

localhost:8000

4. Docker Compose Build and Deploy

1. Docker-compose.yml 작성

  • Dockerfile 과 같은 위치에!
services:
  webapp:
    image: w10sim/react:example
    build: .
    ports:
      - "8000:80"

2. Docker Compose 빌드 실행

1. 기존 cache 내용 지우기

docker system prune -af

2. docker compose 빌드

docker compose up

3. 실행해보기

localhost:8000

profile
Dev Ops, "Git, Linux, Docker, Kubernetes, ansible, " .

0개의 댓글