콘텐츠로 이동

2022 10 03 도커

2022-10-03 도커 멘토링

Docker 기초

  • 윈도우 -> HyperV -> Ubuntu(WSL) -> Docker
  • Images
    • 불변임 변경 불가
    • readOnly
    • layer를 하나씩
  • 캐시 삭제
    • apt repo cache 남는게 일반적 (약 35MB)
    • 따라서 DockerFile에서 불필요한 내용을 삭제하도록 할 수 있음
      • 논리적으로 삭제
      • RUN apt clean && rm -rf /var/lib/apt/lists/*
    • 그런데 이전 레이어들에 대해서 위에 올라가기 떄문에 이미지 용량이 작아지지 않아
      • 변경 layer들이 변경 불가 겹칠 수 있으니까
      • 베이스 이미지 겹치니까 재사용하니까 용량이 그대로
      • 기존 명령어를 그대로 쓴다면 그 이미지 위에다가 덮어씌움
    • 따라서 새로운 이미지 만들 때만 캐시를 날려줄 거야.
  • 기초 명령어
    • docker run <image>:<tag>
    • docker run -d (백그라운드 데몬)
      • -p (publish: 포트바인딩)
      • -e (환경변수 정의)
      • --link (2개 이상의 컨테이너 서로 연결)
      • -v (볼륨 바인딩)

Docker 심화

  • 컨테이너 환경에서 바이너리 파일 X
    • 바이너리 파일 같은거 OS 따라 다르겠지?
    • 그러면 이런거 컨테이너에 넣지마
  • 멀티 스테이지로 빌드

    • Golang 같은 경우 나온 빌드 파일을 패키지에 직접 넣는게 뇌절의 지름길
      • 플랫폼 독립적이지 않기 때문
    • 이렇게 하면 플랫폼에 종속적으로 그냥 돌려서 뚝딱 => 이미지 커짐
      FROM golang:alpine 
      ADD . .
      RUN go build main.go
      CMD["./main"]
      
    • 아래와 같이 하면 도커 이미지 매우 작게할 수 있음
      # Build Stage - intermediate image (as를 붙인 임시 참조)
      FROM golang:alpine AS builder
      ADD . .
      RUN go build main.go
      
      # Package Stage
      FROM alpine
      COPY --from=builder /go/main . 
      CMD["./main"]
      
  • 빌드 자체도 원래 스크립트 안에서 해주고, 이미지 용량에선 빼주자!
    • 참고: https://github.com/lovehyun/tutorial-docker/blob/master/6.java/Dockerfile.v4
      # First stage: complete build environment
      FROM maven:3.5.0-jdk-8-alpine AS builder
      
      # add pom.xml and source code
      ADD ./pom.xml pom.xml
      ADD ./src src/
      
      # package jar
      RUN mvn clean package
      
      # Second stage: minimal runtime environment
      FROM openjdk:8-jre-alpine
      
      # copy jar from the first stage
      COPY --from=builder target/my-app-1.0-SNAPSHOT.jar my-app-1.0-SNAPSHOT.jar
      
      EXPOSE 8080
      
      CMD ["java", "-jar", "my-app-1.0-SNAPSHOT.jar"]
      

docker-compose

  • docker-compose.yml 템플릿
    version: '3'
    
    # 몇개의 컨테이너 배포할거야?
    services:
      web:
        # 내가 배포할 웹서비스 도커 옵션
      db:
        # 내가 배포할 DB 도커 옵션
    
    volumes:
      # 필요시
    
    networks:
      # 필요시
    
  • 써보자

    version: '3'
    
    # 몇개의 컨테이너 배포할거야?
    services:
      my-nginx:
        # 내가 배포할 웹서비스 도커 옵션
        image: nginx:1.18   
        ports:
    
          - "8000:80"
          - "9000:90" # 다양하게 포트 오픈 가능 ex) WAS 여러 포트 열어두면 이렇게 하면 가능
      db:
        image: mysql:5.7
        ports: 
    
          - "3306:3306"
        environment:
    
          - "MYSQL_ALLOW_EMPTY_PASSWORD=true"
        volumes: 
    
          - my-db2:/var/lib/mysql # 이건 호스트의 /var/lib/docker/volumes 에 저장되어 있음 => 여기로 직접 마운트
    
    volumes:
      my-db2:
    

    • docker-compose up : 생성하여 구동
    • docker-compose down : 죽임

이미지 사이즈

  • 도커 컨테이너 안에 들어가서 작업하고 commit 치면 그만큼 또 늘어남

도커 디버깅

  • docker logs -f my-app3
  • docker exec -it docker-id bash

Nginx 설정

  • 죽었을때 백업 설정
    upstream my-apps {
      server 127.0.0.1:8001;
      server 127.0.0.1:8002 backup;
      server 127.0.0.1:8003 backup;
    }
    
  • 가중치
    upstream my-apps {
      server 127.0.0.1:8001 weight=5;
      server 127.0.0.1:8002;
      server 127.0.0.1:8003;
    }