개요
Kaniko 캐시는 Google 자체 Artifact Registry와 같은 컨테이너 이미지 레지스트리 내에 중간 레이어를 저장하고 색인을 생성하여 컨테이너 빌드 아티팩트를 캐시합니다. 추가 사용 사례에 대한 자세한 내용은 GitHub의 Kaniko 저장소를 참조하세요.
Kaniko 캐시는 다음과 같이 작동합니다.
Cloud Build는 빌드 과정에서 컨테이너 이미지 레이어를 레지스트리에 직접 업로드하므로, 명시적 푸시 단계가 없습니다. 모든 레이어가 성공적으로 빌드되면 해당 레이어가 포함된 이미지 매니페스트가 레지스트리에 기록됩니다.
Kaniko는 해당 레이어를 만든 Dockerfile 지시문과 그보다 앞선 모든 지시문의 콘텐츠에 따라
FROM
줄의 이미지 다이제스트까지 각 레이어를 캐시합니다.
빌드에서 Kaniko 캐시 사용 설정
다음과 같이 cloudbuild.yaml
파일의 cloud-builders/docker
작업자를 kaniko-project/executor
작업자로 바꿔서 Docker 빌드에 Kaniko 캐시를 사용 설정할 수 있습니다.
Kaniko 빌드
steps:
- name: 'gcr.io/kaniko-project/executor:latest'
args:
- --destination=${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/${_IMAGE}
- --cache=true
- --cache-ttl=XXh
Docker 빌드
steps:
- name: gcr.io/cloud-builders/docker
args: ['build', '-t', '${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/${_IMAGE}', '.']
images:
- '${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/${_IMAGE}'
각 항목의 의미는 다음과 같습니다.
--destination=${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/${_IMAGE}
는 대상 컨테이너 이미지입니다. Cloud Build는 Dockerfile이 포함된 프로젝트의PROJECT_ID
를 자동으로 대체합니다.LOCATION
,REPOSITORY
,IMAGE
는 사용자 정의 대체 항목입니다.LOCATION
은 이미지가 저장된 저장소의 리전 또는 멀티 리전 위치입니다(예:us-east1
).REPOSITORY
는 이미지가 저장된 저장소의 이름입니다.IMAGE
는 이미지의 이름입니다.--cache=true
는 Kaniko 캐시를 사용 설정합니다.--cache-ttl=XXh
는 캐시 만료 시간을 설정합니다. 여기서XX
는 캐시 만료까지의 시간입니다. 캐시 만료 시간 구성을 참조하세요.
gcloud builds submit --tag [IMAGE]
명령어를 사용하여 빌드를 실행하는 경우 아래와 같이 builds/use_kaniko
속성을 True
로 설정하여 Kaniko 캐시를 사용 설정할 수 있습니다.
gcloud config set builds/use_kaniko True
예: Node.js 빌드에서 Kaniko 캐시 사용
이 예에서는 일반 Dockerfile 권장사항에 따라 Node.js 앱의 증분식 빌드를 실행하는 방법을 보여줍니다. 이 방법은 다른 모든 지원되는 언어로 빌드하는 데 적용됩니다.
여기서는 각 빌드 사이에 변경될 가능성이 적은 지시문을 Dockerfile의 맨 위로 옮기고 변경될 가능성이 많은 지시문을 맨 아래로 옮깁니다. 이렇게 하면 증분식 빌드가 가능해져 빌드 속도가 빨라질 수 있습니다.
다음 Dockerfile을 살펴보세요.
FROM node:8
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
CMD [ "npm", "start" ]
이 Dockerfile은 다음을 수행합니다.
Node.js 권장사항에 따라 Node.js 앱을 설치합니다.
이미지가 실행되면 앱을 실행합니다.
Cloud Build에 교차 빌드 이미지 레이어 캐시가 없으므로 이 빌드를 실행하면 빌드가 실행될 때마다 Cloud Build가 각 단계를 실행해야 합니다. 그러나 Kaniko 캐시를 사용 설정한 채로 이 빌드를 실행하면 다음과 같은 결과가 발생합니다.
처음 실행할 때 Cloud Build는 모든 단계를 실행하고 각 지시문이 컨테이너 이미지 레지스트리에 레이어를 기록합니다.
Kaniko는 각 레이어를 생성한 지시문 및 모든 선행 지시문의 콘텐츠에서 발생된 캐시 키로 해당 레이어에 태그를 지정합니다.
다음 번에 Cloud Build가 동일한 Dockerfile에서 빌드를 실행할 때 파일이 변경되었는지 여부를 확인합니다. 변경되지 않았으면 Cloud Build가 레지스트리에 저장된 캐시된 레이어를 사용하여 빌드를 완료하므로, 빌드가 더 빨리 완료될 수 있습니다. 아래 내용을 참조하세요.
FROM node:8 # no change -> cached!
COPY package*.json ./ # no change -> cached!
RUN npm install # no change -> cached!
COPY . . # no change -> cached!
CMD [ "npm", "start" ] # metadata, nothing to do
package.json
파일을 수정할 경우 파일 콘텐츠는 변경되지 않았으므로 Cloud Build가 COPY
단계 전에 지시문을 실행할 필요가 없습니다.
그러나 package.json
파일을 수정하면 COPY
단계가 수정되므로 Cloud Build가 COPY
단계 이후의 모든 단계를 다시 실행해야 합니다. 아래 내용을 참조하세요.
FROM node:8 # no change -> cached!
COPY package*.json ./ # changed, must re-run
RUN npm install # preceding layer changed
COPY . . # preceding layer changed
CMD [ "npm", "start" ] # metadata, nothing to do
가장 일반적인 시나리오로 앱의 콘텐츠만 변경되고 종속 항목은 변경되지 않았다면 package.json
파일은 변경되지 않은 채로 유지되고 Cloud Build가 최종 COPY . .
단계만 다시 실행하면 됩니다. 따라서 이 단계에서 소스 콘텐츠를 컨테이너 이미지 레지스트리의 레이어에 복사만 하면 되므로 빌드 속도가 빨라집니다.
FROM node:8 # no change -> cached!
COPY package*.json ./ # no change -> cached!
RUN npm install # no change -> cached!
COPY . . # changed, must re-run
CMD [ "npm", "start" ] # metadata, nothing to do
캐시 만료 시간 구성
--cache-ttl
플래그는 Kaniko에게 특정 만료 시간 내에 푸시되지 않은 캐시의 레이어를 무시하도록 지시합니다.
구문은 --cache-ttl=XXh
이고, 여기서 XX
는 시간입니다. 예를 들어 --cache-ttl=6h
는 캐시 만료 시간을 6시간으로 설정합니다. gcloud builds submit --tag [IMAGE]
명령어를 사용하여 빌드를 실행하는 경우 --cache-ttl
플래그의 기본값은 6시간입니다. 직접 Kaniko 실행자 이미지를 사용한다면 기본값은 2주입니다.
종속 항목이 자주 변경되지 않을 것으로 예상될 때는 만료 시간이 길수록 빌드가 빨라지고, 만료 시간이 짧을수록 캐시된 레이어의 사용량이 줄어드는 대신 빌드가 업데이트된 종속 항목(예: Maven 패키지 또는 Node.js 모듈)을 신속하게 가져올 수 있습니다.
명령줄에서 캐시 만료 시간을 설정하려면 다음 명령어를 실행합니다.
gcloud config set builds/kaniko_cache_ttl XX
여기서 XX
는 캐시 만료 시간(시)입니다.
Node.js 예시에서 RUN npm install
지시문의 출력은 변경되지 않은 채로 유지되므로, 캐시된 경우에도 정기적으로 지시문을 다시 실행해야 합니다. --cache-ttl
매개변수를 6시간으로 설정하는 것이 좋습니다. 이렇게 하면 해당 지시문의 콘텐츠 변경 여부에 관계없이 Cloud Build는 빌드가 실행될 때마다가 아닌 작업일당 최소 한 번 지시문을 실행합니다.