practical

Docker 컨테이너 모범사례

waterclean101 2023. 11. 19. 11:09

MLOps 실전 가이드

 

MLOps 실전 가이드

머신러닝 모델의 안정적인 운영과 성공적인 CI/CD를 위한 MLOps 엔지니어링 노하우

m.hanbit.co.kr

 

첫 번째 모범 사례: 린터linter 사용

새로운 언어나 도구를 배우기 시작할 때 사용 규칙이나 패턴을 익힐 때 그 언어나 도구의 린터를 찾아보는 것이 도움이 된다.

린터(linter):

  • 린터(Linter)는 소프트웨어 개발에서 사용되는 도구로, 소스 코드를 분석하여 프로그래밍 에러, 버그, 스타일 오류, 의심스러운 구조 등을 찾아내는 역할을 한다.
  • 코드의 품질을 향상시키고 일관된 코딩 스타일을 유지하는 데 도움을 준다.

린터의 주요 기능

  • 코딩 스타일 검사: 코드 포맷팅과 코딩 컨벤션(들여쓰기, 브래킷 사용, 변수 이름 규칙 등)을 검사한다. 일관된 코딩 스타일을 유지하게 도와준다.
  • 프로그래밍 오류 탐지: 문법 오류, 타입 오류 등의 기본적인 프로그래밍 실수를 발견한다.
  • 코드 품질 향상: 불필요하거나 중복된 코드, 비효율적인 알고리즘 등을 지적한다.
  • 보안 취약점 경고: 잠재적인 보안 취약점을 식별하여 경고한다.

언어별 린터 예

  • JavaScript: ESLint, JSLint, JSHint
  • Python: Pylint, flake8, pep8
  • Java: Checkstyle, PMD, FindBugs

 

Docker 린터 예시

  1. Hadolint: 가장 인기 있는 Dockerfile 린터 중 하나. Dockerfile에 대한 베스트 프랙티스와 스타일 가이드를 기반으로 코드를 검사한다. ShellCheck와 통합되어 있어, RUN 명령어 안의 쉘 스크립트도 검사할 수 있다.
  2. Dockerfilelint: Dockerfile의 일반적인 문제와 안티 패턴을 감지한다. 명령어 형식, 구조, 불필요한 명령어 사용 등을 검사한다.

Hadolint

이 린터는 사용하기 편하도록 컨테이너 이미지로 패키징되어 있다.

FROM centos:8 RUN dnf install -y python38 
RUN pip install pytest ENTRYPOINT ["/bin/bash"]
$ docker run --rm -i hadolint/hadolint < Dockerfile

DL3013 Pin versions in pip.
Instead of 'pip install <package>' use 'pip install <package><version>'

린터를 이용하면 도커파일을 작성하면서 놓쳤던 것들에 대한 괜찮은 제안을 받아볼 수 있다는 장점이 있고 '자동화'의 측면에서도 노동량을 절약할 기회를 얻을 수 있다는 장점이 있다. 자동화된 린팅은 반복적인 배포 작업 시 버그 발생 위험을 줄이고 배포 프로세스의 중요한 부분에 온전히 신경쓸 수 있도록 돕는다.

 

두 번째 모범 사례: 명령어 통합

컨테이너 기반 개발에서는 최대한 컨테이너를 작게 유지하려고 노력하는 경향이 있다. 모든 컨테이너 도구도 마찬가지로 컨테이너 크기를 최대한 작게 유지하기 위해 노력한다.

도커파일에서는 RUN 명령이 등장할 때마다 하나의 새로운 레이어가 생성된다. 당연히 컨테이너 이미지를 만드는 데 사용되는 레이어가 적어야 컨테이너의 크기가 작아질 것이다.

RUN apk add --no-cache python3 && python3 -m ensurepip && pip3 install pytest 

명령의 끝에 &&을 사용해서 여러 명령어를 하나로 묶어 단일 레이어로 만들 수 있다. 위 설치 명령어를 여러 줄의 RUN 명령어로 분할하면 컨테이너는 훨씬 커질 것이다. 의존하는 패키지가 많아질수록 이 차이를 명백해진다.

 

세 번째 모범 사례: 취약성 분석

컨테이너는 직접 작성한 프로그램뿐 아니라 컨테이너가 빌드될 때 설치되었던 라이브러리들이 함께 담겨 있다. 컨테이너는 빌드될 때 애플리케이션 구동에 필요한 의존성들을 풀(Pull) 하는 일종의 운영체제와 같다.

예를 들어 컨테이너에서 플라스크와 같은 웹 프레임워크를 이용해서 모델을 서비스하는 경우 플라스크 자체뿐 아니라 플라스크의 수많은 종속성을 다운로드받게 된다. 이중 하나 때문에 보안 취약점 Common Vulnerabilities and Exposures (CVE)이 생길 수 있다는 사실을 알고 있어야 한다. 해커가 CVE를 이용해 공격하는 경우 시스템이 완전히 멈춰버릴 가능성이 있어서 위험하다.

많은 보안 솔루션이 이러한 취약점들로 인해 발생하는 위험을 줄이기 위해 컨테이너의 취약성을 검사하고 보고하는 작업에 특화되어 있다. 이러한 보안 도구들은 애플리케이션을 실행하기 위해 설치하는 각종 라이브러리들과 운영체제의 패키지들을 살펴보며 취약성 보고서를 제공한다.

Anchore 사가 공개한 grype는 쉽게 설치하여 빠르게 사용해볼 수 있는 컨테이너 이미지 보안 도구이다. Docker 이미지, OCI(Open Container Initiative) 이미지, 파일 시스템 디렉토리에 대한 취약점 검사를 지원하고 다양한 패키지 포맷(예: Debian, RPM, NPM, RubyGems 등)의 검사도 가능하다. 또한 CI/CD 파이프라인에 Grype를 통합하여 자동화된 취약점 검사를 구현할 수 있다.

grype은 아래 명령어를 이용해 설치하고 사용할 수 있다.

$ curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh-s

Docker 이미지 검사:

$ grype docker.io/library/<이미지이름>

# 이미 build & run 한 컨테이너라면
$ grype <이미지 ID or 이름>

파일 시스템 디렉토리 검사:

$ grype dir:/path/to/directory

특정 파일 검사:

$ grype sbom:file.sbom

<참고> Grype는 컨테이너의 실행 상태가 아닌 컨테이너를 생성한 이미지에 대해 취약점 검사를 수행한다. 즉, 컨테이너의 현재 상태나 변경사항에 대해서는 검사하지 않는다.