출처 : 패캠 gitops
Dockerfile 기초
Dockerfile 정의 : 컨테이너의 구성정보를 프로비저닝한 텍스트 template 파일
Dockerfile 흐름 : Dockerfile -> docker build -> image registry(dockerhub) -> deploy docker image
Dockerfile 명령어 : https://docs.docker.com/engine/reference/builder/
빌드 명령어 : docker build -t IMAGE_NAME:TAG [-f DOCKERFILE_NAME] DOCKERFILE_LOCATION
Dockerfile 최적화 : 경량의 컨테이너 서비스 제공
dockerfile 작성 고려 사항 : https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
빌드시간, 이미지 크기, 재사용성, 보안, 유지보수성 등
최적화 목적 : 컨테이너의 경량의 가상화 서비스
- 기존의 base image 들 또한 지향점에 필요한 프로그램, 라이브러리, 실행파일만 보유한다.
- 애플리케이션에 필요한 추가 구성 요소를 포함시키는 경우 복잡성, 의존성 문제를 피해야 하고 빠른 컨테이너 배포를 위해 최소한의 설정과 구성을 권장한다.
최적화1 : 불필요한 바이너리 제거.
- 불필요한 패키지 설치 배제, 설치된 패키지는 autoremove, clear로 정리
- 개발환경과 동일한 버전 설치 : apt install -y --no-install-recommends <패키지>
- '.dockerignore' 파일 : '.gitignore'와 같은 역할. 빌드에 불필요한 파일을 제외한다.
최적화2 : 경량화된 base image 선택(alpine, scratch...)
- scratch : Go언어(gcc 컴파일)를 사용하여 정적 링크 바이너리를 만들어서 Dockerfile에 참조하면 애플리케이션으로만 구성된 경량화 된 이미지 구성 가능.
-
- Alpine Linux : minimal 보다 더 경량화된 base image. 잠재적인 취약점이 비교적 적어 보안에 이점
최적화3 : multi-stage build 최종 이미지 크기 최소화
https://docs.docker.com/build/building/multi-stage/
- multi-stage build(다단계 빌드) : 여러개의 base image를 사용한 docker build
- Dockerfile FROM 명령어를 복수로 작성하여 분리도니 작업 공간(stage)을 제공
- 1st stage(빌드도구)에서 생성된 실행파일 등을 두 번째 stage에 제공, 마지막에 실행된 stage 작업이 Docker image로 최종 생성되어 이미지 크기가 감소. 마지막 이미지를 alpine 사용.
최적화4 : Dockerfile Layer 최소화
- Layer 최대 : 127줄
- Layer 압축 : RUN apt update && apt install -y package1 && apt install -y package2 && apt clean && rm -rf /var/lib/apt/lists/*
최적화5 : one application - on container
- 장점키워드 : 애플리케이션 확장성, 버전관리, 소스코드 모듈화, 장애 발생 서비스 지속성 보장, 수평 확장성, 컨테이너의 재사용성, 컨테이너 리소스 제어 편의성.
- 하나의 컨테이너에 복수의 애플리케이션을 설정하면 결합성이 높아지고 확장성이 떨어진다.
- 하나의 컨테이너에 하나의 애플리케이션 동작은 컨테이너 간의 독립성을 보장함과 동시에 애플리케이션 버전관리, 소스코드 모듈화 등 장정이 있다.
- 모놀리식 구성보다 결합 해제된 애플리케이션(Decouple applications) 설계, 마이크로서비스(MSA) 지향적 설계를 고려해야 장애 발생하여도 애플리케이션 자체가 유지될 수 있다.
- 컨테이너의 재사용성 예시 : 3-Tier 웹 서비스
- 컨테이너에 여러 애플리케이션 작동하면 리소스(CPU,MEM,I/O) 소비도 높아진다.
최적화6 : using cache
- Docerkfile을 통해 이미지를 빌드하면 자동으로 각 명령어 단위로 캐싱(caching, 임시 이미지 생성)한다.
- 동일한 명령의 실행은 이 캐싱을 통해 재사용(Using cache 출력)되기 떄문에 빌드 속도를 빠르게 하고, 캐싱에 사용된 명령줄이 변경이 되면(캐시 사용시 checksum을 통해 검증) 기존 캐싱은 사용하지 못하고 재 캐싱된다.
- 캐싱 효과를 높이기 위해 명령어의 위치를 명확히 해야 한다. 일정하게 유지될 명령은 Dockerfile의 상단에 배치된(패키지 설치 등의 단계)하고, 변경될 수 있는 명령은 하단에 배치(COPY 같은 빌드 단계)하면 기존 캐시를 부정할 가능성이 줄어든다.
최적화7 : 보안 강화
- Dockerfile은 사용자를 지정하지 않으면 root 사용자를 사용한다. root 권한이 필수는 아니다.
- Docker container 실행 시 암시적으로 Docker Host에 대한 root acces 권한을 갖게 되어 잠재적인 보안 문제를 갖게 된다. 따라서, 의도하자면 컨테이너 애플리케이션 실행을 통해 Docker Host에 대한 권한이 쉽게 상승(escalation)하게 된다.
- 예로, 이미지는 컨테이너 보안 측면에서 첫번째 고려 대상이다. 이미지가 보호되지 않고 제대로 구성되지 않으면 다른 여러가지 수단에 의해 컨테이너의 경계를 벗어나 호스트에 액세스할 수 있기 때문에 컨테이너 이미지의 공격 대상 영역을 줄이는 노력이 요구된다.
- 이미지 서명이 사용되면 Docker는 매니페스트의 서명을 확인하여 콘텐츠가 신뢰할 수 있는 소스에서 생성되었고 위조, 변조가 발생하지 않았음을 보장한다.
- Docker Signer (docker trust sign)
- Notary (by Harbor)
- DCT (Docker Contents Trust) -> export DOCKER_CONTENT_TRUST=1
- Dockerfile 에서 USER 명령어 사용으로 root 사용자 접근을 억제한다. USER 명령은 RUN, ENTRYPOINT 또는 CMD 명령을 실행하기 위한 특정 사용자를 지정할 경우 사용한다.
- 일반적으로 이미지 안에 무엇이 있는지 모르므로 Docker hub에서 인증된 이미지만 사용하고, 이미지에 취약성이 있는지 확인 후 사용을 권장
- 취약성 목록 : https://vulnerablecontainers.org
- 익숙하지 않은 이미지를 사용하는 경우 'DIVE'를 사용하여 이미지 검사 수행한다.
- SETUID, SETGID 비트가 있는 모든 바이너리를 찾아 제거해야 한다. 이러한 바이너리는 권한 상승에 사용될 수 있다.
'Infra > IaC' 카테고리의 다른 글
[Docker] Swarm mode (0) | 2023.10.26 |
---|---|
[Docker] compose (0) | 2023.10.26 |
[Docker] docker volume 데이터 지속성 및 데이터 관리 (1) | 2023.10.26 |
[Docker] 리소스 모니터링과 자원 할당 관리 (0) | 2023.10.24 |
[Docker] Network 관리 (2) | 2023.10.20 |