기본 이미지 자동 업데이트 구성

Cloud Run에서 기본 이미지에 대한 자동 업데이트를 구성하면 Google이 기본 이미지의 운영체제 및 언어 런타임 구성요소에 보안 패치를 자동으로 적용할 수 있습니다. 기본 이미지가 업데이트되도록 서비스를 다시 빌드하거나 다시 배포할 필요가 없습니다. 기본 이미지가 업데이트될 때 새 버전이 생성되지 않습니다.

다음 다이어그램은 애플리케이션 코드와 종속 항목('앱 이미지')이 언어 런타임, OS 패키지, 운영체제('기본 이미지') 위에 어떻게 구축되는지 보여줍니다. 기본 이미지의 구성요소는 Google에서 자동으로 업데이트합니다.

Cloud Run 기본 이미지 다이어그램

기본 이미지 자동 업데이트를 구성하려면 다음 단계를 따르세요.

  • 호환되는 Cloud Run 기본 이미지를 선택합니다.
  • 실행 중인 서비스를 안전하게 재설정하는 기능을 유지하는 방식으로 애플리케이션 이미지를 빌드하고 배포합니다.

기본 이미지 선택

기본 이미지는 대부분의 컨테이너 기반 개발 워크플로의 시작 지점입니다. 개발자는 기본 이미지를 사용하는 것부터 시작해서 그 위에 필요한 라이브러리, 바이너리, 구성 파일을 추가하여 애플리케이션을 실행합니다.

Google Cloud 빌드팩은 서버리스 애플리케이션 빌드를 위한 기본 이미지를 게시하고 유지관리합니다. 이러한 기본 이미지는 Ubuntu Linux 배포를 기반으로 합니다.

Cloud Run은 Google Cloud 빌드팩 기본 이미지를 사용하는 자동 기본 이미지만 지원합니다.

Google Cloud 빌드팩을 선택할 때는 다음을 고려해야 합니다.

  • 스택: 스택은 Linux 배포 버전과 OpenSSL, curl과 같은 시스템 패키지로 구성됩니다.
  • 언어: 애플리케이션에서 사용하는 프로그래밍 언어의 특정 버전입니다.

기본 이미지 변형에 대한 자세한 내용은 런타임 기본 이미지를 참조하세요.

애플리케이션 이미지 빌드

자동 업데이트가 사용 설정된 서비스는 기본 운영체제 레이어를 생략하는 애플리케이션 이미지를 제공해야 합니다. 이 작업을 실행하는 두 가지 방법은 다음과 같습니다.

소스에서 배포

Cloud Run 소스에서 배포 기능을 사용하여 서비스가 자동 업데이트를 수신할 수 있도록 코드를 빌드하고 배포할 수 있습니다. 이렇게 하려면 애플리케이션을 만들 때 --base-image 플래그를 제공해야 합니다.

예를 들어 자동 기본 이미지 업데이트가 사용 설정된 Node.js 서비스 또는 함수를 배포하려면 다음 명령어를 사용합니다.

gcloud beta run deploy \
  --source . \
  --base-image nodejs20

scratch로 빌드

또한 빌드 도구 모음을 사용하여 자동 기본 이미지 업데이트와 호환되는 애플리케이션 컨테이너 이미지를 만들 수 있습니다.

자동 기본 이미지 업데이트로 Cloud Run 서비스를 배포하면 애플리케이션 컨테이너 이미지가 기본 컨테이너 이미지 위에 레이어링됩니다. 애플리케이션 컨테이너 이미지에는 애플리케이션만 포함해야 하고, 기본 컨테이너 이미지에서 제공되는 운영체제나 런타임은 포함하지 않아야 합니다.

애플리케이션 컨테이너 이미지를 만들려면 다음 안내를 따르세요.

  1. 다음을 실행하는 다단계 Dockerfile을 만듭니다.
    1. 필요한 종속 항목이 포함된 적합한 기본 이미지를 사용하여 애플리케이션을 빌드합니다.
    2. 빌드된 구성요소를 스크래치 이미지에 복사합니다.
  2. 애플리케이션 컨테이너 이미지를 빌드하고 이를 Artifact Registry에 푸시합니다.
  3. 애플리케이션 컨테이너 이미지를 Cloud Run에 배포하고 기본 이미지를 지정합니다.

다단계 Dockerfile 만들기

이 가이드에서는 Node.js 애플리케이션이 사용됩니다. 이 가이드는 언어별로 적용되지 않으며 애플리케이션과 언어에 맞게 맞춤설정할 수 있습니다.

  • 다음을 사용하여 프로젝트의 루트 디렉터리에 Dockerfile을 만듭니다.

    # This Dockerfile will produce an image that only includes the Node.js app and *not* the Node.js runtime.
    # The resulting image will not run locally. It is intented at being layered on top of a Node.js base image.
    
    FROM node:20-slim as builder
    
    # Create and change to the app directory.
    WORKDIR /usr/src/app
    
    # Copy application dependency manifests to the container image and install
    # production dependencies.
    COPY package*.json ./
    RUN npm install --only=production
    
    # Copy local code to the container image.
    COPY . ./
    
    # Copy the application source code and depenencies onto a scratch image.
    FROM scratch
    COPY --from=builder --chown=33:33 /usr/src/app/ ./
    
    # Run the web service on container startup.
    CMD [ "node", "index.js" ]
    

이 Dockerfile은 다단계 빌드를 사용하여 애플리케이션 소스 코드와 종속 항목을 scratch 이미지에 복사합니다. 이 이미지는 Cloud Run 관리 기본 이미지에서 런타임에 제공할 운영체제, 패키지, 런타임 구성요소를 생략합니다.

애플리케이션 이미지 빌드

애플리케이션 이미지를 빌드하고 이를 Artifact Registry에 업로드합니다. Cloud Build로 Dockerfile을 빌드하고 Artifact Registry에 업로드하는 방법에 관한 자세한 내용은 컨테이너 빌드를 참조하세요.

애플리케이션 이미지 배포

이제 애플리케이션과 가장 호환 가능한 기본 이미지를 사용하여 사용 설정된 자동 업데이트로 애플리케이션 이미지를 배포할 수 있습니다. 이 예시에서는 us-central1의 Node.js 20 런타임을 사용합니다. 기본 이미지 변형에 대한 자세한 내용은 런타임 기본 이미지를 참조하세요.

필요한 역할 및 권한에 대한 자세한 내용은 Cloud Run에 컨테이너 이미지 배포를 참조하세요.

gcloud

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. 애플리케이션 이미지를 배포할 때 Node.js 20 런타임의 자동 업데이트를 사용 설정하려면 다음 명령어를 실행합니다.

    gcloud beta run deploy SERVICE \
    --image APP_IMAGE \
    --base-image BASE_IMAGE

    다음과 같이 바꿉니다.

    • SERVICE를 배포할 서비스의 이름으로 바꿉니다.
    • APP_IMAGE를 애플리케이션 컨테이너 이미지의 URL로 바꿉니다.
    • BASE_IMAGE를 기본 이미지의 URL(예: nodejs20 또는 us-central1-docker.pkg.dev/serverless-runtimes/google-22/runtimes/nodejs20)로 바꿉니다. 기본 이미지 변형에 대한 자세한 내용은 런타임 기본 이미지를 참조하세요.

YAML

  1. 새 서비스를 만드는 경우에는 이 단계를 건너뜁니다. 기존 서비스를 업데이트하는 경우 YAML 구성을 다운로드합니다.

    gcloud run services describe SERVICE --format export > service.yaml
  2. runtimeClassNamerun.googleapis.com/base-images 주석을 업데이트합니다.

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
    name: SERVICE
    annotations:
      ...
      run.googleapis.com/launch-stage: BETA
      ...
    spec:
    template:
      metadata:
        annotations:
          run.googleapis.com/base-images: '{"NAME":"BASE_IMAGE"}'
        spec:
          containers:
          - name: NAME
            image: APP_IMAGE
          runtimeClassName: run.googleapis.com/linux-base-image-update

    다음과 같이 바꿉니다.

    • SERVICE를 배포할 서비스의 이름으로 바꿉니다.
    • APP_IMAGE를 애플리케이션 컨테이너 이미지의 URL로 바꿉니다.
    • BASE_IMAGE를 기본 이미지의 URL(예: us-central1-docker.pkg.dev/serverless-runtimes/google-22/runtimes/nodejs20)로 바꿉니다. 기본 이미지 변형에 대한 자세한 내용은 런타임 기본 이미지를 참조하세요.

로컬에서 실행하도록 컨테이너 이미지 재조합

자동 기본 이미지 업데이트에 사용되는 애플리케이션 컨테이너 이미지는 scratch로 빌드되며 기본 이미지 업데이트가 사용 설정된 경우 Cloud Run 외부에서 실행할 수 없습니다. 호환되는 기본 이미지 위에 애플리케이션 이미지의 기반을 변경하여 애플리케이션 이미지를 실행 가능하게 만들 수 있습니다.

  1. Docker Community Edition(CE)을 워크스테이션에 설치합니다.

  2. 애플리케이션 이미지 다운로드

    docker pull APP_IMAGE
    

    다음과 같이 바꿉니다.

    • APP_IMAGE를 컨테이너 이미지의 URL로 바꿉니다.
  3. 기본 이미지를 다운로드합니다.

    docker pull BASE_IMAGE
    

    다음과 같이 바꿉니다.

    • BASE_IMAGE를 호환되는 기본 이미지의 URL로 바꿉니다. 사용 가능한 기본 이미지 목록은 Google Cloud의 빌드팩 기본 이미지에서 찾을 수 있습니다. 예를 들어 google-22를 사용하여 Node.JS 20 애플리케이션을 만든 경우 스택us-central1-docker.pkg.dev/serverless-runtimes/google-22/runtimes/nodejs20:latest가 선택됩니다.
  4. 이미지 재조합

pack CLI

  1. Pack CLI를 설치합니다.

  2. pack rebase를 사용하여 이미지를 결합합니다.

    pack rebase $APP_IMAGE \
        --run-image=$NEW_BASE_IMAGE \
        --force
    

Docker

Dockerfile을 사용하여 앱 이미지의 모든 파일을 다시 기본 이미지에 복사합니다.

ARG APP_IMAGE
ARG NEW_BASE_IMAGE

# first copy all files from the app image onto the builder image
FROM ${APP_IMAGE} as app
FROM ${NEW_BASE_IMAGE} as builder
COPY --from=app / /

# restore the app image config by copying everything from previous step back
# back onto the app image
FROM ${APP_IMAGE}
COPY --from=builder / /

이미지를 빌드합니다.

docker build \
    -t IMAGE \
    --build-arg APP_IMAGE=APP_IMAGE \
    --build-arg NEW_BASE_IMAGE=BASE_IMAGE \
    .

자동 업데이트 사용 중지

소스에서 배포하는 경우

소스에서 배포할 때 --no-automatic-updates 플래그를 사용하여 자동 기본 이미지 업데이트를 사용 중지할 수 있습니다. 다음 예시는 Node.js 서비스에 대해 자동 기본 이미지 업데이트를 사용 중지하는 방법을 보여줍니다.

gcloud

gcloud beta run deploy SERVICE \
    --source . \
    --base-image nodejs20 \
    --no-automatic-updates

컨테이너 이미지를 배포하는 경우

스크래치로 빌드된 컨테이너 이미지를 사용하는 서비스에 대해 기본 이미지 업데이트를 사용 중지하려면 기본 이미지가 포함된 새 컨테이너 이미지를 배포하고 기본 이미지를 삭제해야 합니다.

gcloud

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. 자동 기본 이미지 업데이트를 사용 중지하려면 다음 명령어를 실행합니다.

    gcloud beta run deploy SERVICE \
        --image IMAGE \
        --base-image ""

    다음과 같이 바꿉니다.

    • SERVICE를 배포할 서비스의 이름으로 바꿉니다.
    • IMAGE를 앱, 런타임, OS가 포함된 컨테이너 이미지의 URL로 바꿉니다.

YAML

  1. 새 서비스를 만드는 경우에는 이 단계를 건너뜁니다. 기존 서비스를 업데이트하는 경우 YAML 구성을 다운로드합니다.

    gcloud run services describe SERVICE --format export > service.yaml
  2. run.googleapis.com/base-images 주석을 삭제합니다.

  3. runtimeClassName 속성을 삭제합니다.

  4. image에서 앱, 런타임, OS가 포함된 컨테이너 이미지를 사용합니다.

  5. 다음 명령어를 사용하여 서비스를 만들거나 업데이트합니다.

    gcloud run services replace service.yaml

알려진 제한사항

  • 자동 기본 이미지 업데이트는 Google Cloud의 빌드팩 기본 이미지만 지원합니다. 자체 기본 이미지를 사용할 수는 없습니다.

  • 컴파일된 언어를 사용하는 애플리케이션은 자동 기본 이미지 업데이트로 인해 다시 컴파일되지 않습니다.

  • 애플리케이션 이미지의 보안 스캔이 완료되지 않았을 수 있습니다. 이제 애플리케이션 이미지가 scratch로 빌드되므로 보안 스캐너에서 이미지의 애플리케이션 부분만 스캔합니다. 컨테이너 보안을 더 완벽하게 파악하려면 상응하는 Google 제공 기본 이미지에서도 스캔을 실행해야 합니다. 기본 이미지를 다운로드하고 오픈소스 도구를 사용하여 스캔을 실행할 수 있습니다.