Docker BuildKit ?
이때까지 Docker BuildKit 의 존재를 모르고 살아왔다…
docker build 만 열심히 타이핑 하며 이미지를 빌드 해왔는데, 최근에 secret 관리가 필요한 순간이 왔다. BuildKit 을 사용하면 secret 관리 기능이 아주 잘 지원된다고 하여 오늘 알아보고자 한다.
BuildKit 은 기존 Docker 이미지 빌드 시스템을 대체하기 위해 개발된 차세대 빌드 엔진이다. 이 차세대 빌드 엔진은 이하의 특징들을 만족하기 위해 탄생했다.
BuildKit 특징
병렬 처리
기존 Docker 빌드 시스템은 명령어를 순차적으로 실행하는 반면, BuildKit은 서로 독립적인 레이어들을 병렬로 처리할 수 있다. 예를 들어, 여러 단계에서 별도의 종속성이 포함된 패키지들을 설치하는 경우 BuildKit은 이러한 단계를 동시에 처리하여 빌드 시간을 크게 단축시킨다.
효율적인 캐싱
BuildKit 은 보다 효율적인 캐시 메커니즘을 사용하여, 각 빌드 단계의 결과를 개별적으로 캐시하여 부분적으로 재빌드한다.
분산 캐시 (Distributed Caching)
BuildKit 은 분산된 시스템에서 캐시를 공유하는 게 가능해, 여러 서버에서 동일한 빌드 환경을 공유하거나 재사용하여 빌드 성능을 향상 시킨다.
외부 캐시 (External Cache Sources)
S3 같은 외부 저장소에서 캐시 데이터를 불러와 재사용 하는 것이 가능하다.
멀티 스테이지 빌드 최적화
여러개의 스테이지를 가진 Dockerfile을 빌드할 때 BuildKit 을 사용하여 빌드하면 최종 이미지에 필요하지 않은 중간 단계는 건너뛰어 빌드 시간과 최종 이미지 크기를 줄인다.
보안 강화 (Build Secrets)
secret 정보를 안전하게 처리할 수 있는 기능을 제공한다. 예를 들어 환경 변수나 API 키, 혹은 Private Storage에 접근하기 위한 SSH 키 까지 Dockerfile에 직접 노출하지 않고 안전하게 전달할 수 있다.
Dockerfile에 직접 노출되거나 ADD COPY 같은 명령을 사용하지 않더라도, “--secret” 옵션을 사용하여 빌드 도중에만 필요한 시크릿 파일을 임시로 사용하고, 최종 도커 이미지에는 포함되지 않도록 만들 수 있다.
Rootless Mode
BuildKit 은 rootless mode를 지원한다. 이는 컨테이너 내부에서 루트 권한 없이 빌드를 수행할 수 있는 것이기 때문에 보안성을 향상 시키는 데 큰 도움을 준다.
멀티 플랫폼 빌드
Buildkit을 사용하면 하나의 빌드 명령어로 여러 플랫폼에 맞춘 이미지를 동시에 빌드하는 것이 가능하다. 이를 이용하면 x86, ARM 등 다양한 아키텍처에 맞는 이미지를 쉽게 생성할 수 있다.
# linux/amd65, linux/arm64 아키텍처 플랫폼의 이미지를 동시에 빌드
docker buildx build --platform linux/amd64,linux/arm64 .
Shell
복사
네트워크 사용 제어
빌드 단계에서 네트워크 사용을 제한하거나 제어할 수 있다. 예를 들어, 일반적인 빌드 프로세스에서는 네트워크를 사용하다가 네트워크 연결이 필요 없는 단계에서는 네트워크를 차단함으로써 보안성을 강화하는 것이 가능하다.
아래의 예시와 같이 docker build 과정에서 network 옵션을 넣어주는 것으로 빌드 과정에서 어떤 네트워크를 사용하게 할건지 선택하고, 빌드 도중 네트워크가 필요할 때만 network 옵션을 변경하는 것으로 잠깐 동안만 네트워크를 허용할 수 있다.
# 기본적으로는 네트워크를 허용하지 않는 도커 이미지 빌드 명령
DOCKER_BUILDKIT=1 docker build --no-cache --network=none -t myapp .
Shell
복사
# --network=none 상태로 빌드가 시작됐기 때문에, 현재는 네트워크를 허용하지 않는 상태
FROM alpine AS builder
# COPY 명령에 별도의 옵션이 없기 때문에 복사 단계에는 네트워크가 사용되지 않음
COPY . /app
# 네트워크가 반드시 필요한 패키지 설치 단계
# 이 단계에서는 --network=default 로 기본 네트워크를 사용하게 하므로써 네트워크에 연결하도록 설정
RUN \
apk add --no-cache build-base
# 최종 이미지 스테이지에서는 마찬가지로 네트워크가 사용되지 않으므로 보안적으로 안전함
FROM alpine
COPY /app /app
Docker
복사
network 옵션으로 사용 가능한 값은 다음과 같다.
•
none
◦
빌드 중 네트워크 접근을 차단
•
default
◦
기본 네트워크를 사용, 일반적으로 인터넷에 접근이 가능
•
host
◦
호스트 네트워크를 사용, 도커 컨테이너가 호스트의 네트워크 인터페이스를 사용하여 더 빠른 네트워크 통신이 가능
빌드 로그 및 진단 도구 향상
BuildKit 은 빌드 로그와 오류 메시지를 보다 세분화하여 제공하여 빌드 중 발생하는 문제를 더 쉽게 추적할 수 있다. 또한, BuildKit 은 빌드 프로세스에서 발생하는 각 단계의 상세 정보를 제공하여 디버깅 난이도가 훨씬 쉽다.
사용법
Buildkit 을 사용하기 위해선 Docker 18.09 이상의 버전이 필요
BuildKit 을 사용하기 위해선 이하의 2가지 방법 중 하나를 수행하면 된다.
•
환경 변수 설정
◦
환경변수를 사용하는 방법으로써, 가장 쉽고 직관적이다.
DOCKER_BUILDKIT 환경변수의 값을 1로 설정하면 docker build 명령을 수행할 때 자동으로 Buildkit 의 기능이 적용된다.
# 1. 한번만 사용하기
DOCKER_BUILDKIT=1 docker build -t myapp .
# 2. 쉘을 종료 할때까지 사용하기
export DOCKER_BUILDKIT=1
docker build -t myapp .
Shell
복사
•
Docker 데몬 설정
◦
/etc/docker/daemon.json 파일을 수정하는 방법으로써 설정을 따로 변경하기 전까지 영구 적용된다.
◦
vi vim 같은 텍스트 에디터로 /etc/docker/daemon.json 파일에 아래의 내용을 추가한다.
{
"features": {
"buildkit": true
}
}
JSON
복사
◦
파일 수정을 완료 했으면 도커 서비스를 재시작하여 설정을 적용한다.
systemctl restart docker
Shell
복사
설정만 잘 한다면 일반적인 docker build 명령에 BuildKit 이 적용된 것을 확인할 수 있다.