OCI 컨테이너로 마이그레이션

이 페이지에서는 OCI 호환 애플리케이션 이미지를 생성하는 동안 Cloud Foundry 빌드 프로세스를 재현하는 데 필요한 빌드 인프라를 설명합니다. 이미 Spring Music 마이그레이션 가이드를 완료한 경우 이 가이드에서 애플리케이션의 특정 마이그레이션 구성을 자세히 살펴볼 수 있습니다.

최신 도구를 사용하여 OCI 이미지를 만드는 방법을 보여주는 다이어그램

시작하기 전에

  1. Cloud Run 설정 페이지의 설명대로 Cloud Run용 새 프로젝트를 설정했는지 확인합니다.
  2. 컨테이너를 저장하기 위한 REGISTRY_URI가 있는지 확인합니다. Cloud Run에서는 Artifact Registry를 사용하는 것이 좋습니다. Docker는 프로젝트를 빌드하기 위한 중간 이미지를 만드는 데 사용됩니다.

Cloud Foundry 호환 빌드 프로세스 설정

이 새로운 프로세스를 지원하려면 두 개의 기본 OCI 컨테이너를 만들어야 합니다.

  • Cloud Foundry의 빌드 프로세스를 미러링하고 애플리케이션 소스 코드를 Cloud Foundry Droplets에 빌드할 수 있는 빌더 이미지입니다.
  • Cloud Foundry 애플리케이션 런타임을 미러링하는 런타임 이미지입니다.

이 프로세스는 플랫폼 관리자가 한 번 이상 실행해야 합니다. 프로세스가 설정되면 Cloud Run으로 마이그레이션해야 하는 모든 Cloud Foundry 애플리케이션에서 빌드 및 실행 이미지를 공유할 수 있습니다.

빌더 이미지 만들기

이 섹션에서는 cflinux3을 기본 이미지로 사용하여 빌드 이미지를 만듭니다. 빌드 이미지는 애플리케이션 이미지를 만드는 빌드 환경으로 사용됩니다.

  1. build/cd라는 디렉터리를 만듭니다.

    mkdir build && cd build
    
  2. build/ 폴더에서 Dockerfile이라는 새 파일을 만들고 다음 코드를 붙여넣습니다.

    ARG CF_LINUX_FS=cloudfoundry/cflinuxfs3
    
    FROM golang:1.20-bullseye AS builder_build
    WORKDIR /build
    RUN ["git", "clone", "--depth=1", "https://github.com/cloudfoundry/buildpackapplifecycle.git"]
    WORKDIR /build/buildpackapplifecycle
    RUN ["go", "mod", "init", "code.cloudfoundry.org/buildpackapplifecycle"]
    RUN ["go", "mod", "tidy"]
    RUN CGO_ENABLD=0 go build -o /builder ./builder/
    
    FROM $CF_LINUX_FS
    # Set up container tools related to building applications
    WORKDIR /lifecycle
    COPY --from=builder_build /builder /lifecycle/builder
    
    # Set up environment to match Cloud Foundry's build.
    # https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html#app-system-env
    WORKDIR /staging/app
    WORKDIR /tmp
    ENV CF_INSTANCE_ADDR=127.0.0.1:8080 \
    CF_INSTANCE_IP=127.0.0.1 \
    CF_INSTANCE_INTERNAL_IP=127.0.0.1 \
    VCAP_APP_HOST=127.0.0.1 \
    CF_INSTANCE_PORT=8080 \
    LANG=en_US.UTF-8 \
    INSTANCE_GUID=00000000-0000-0000-0000-000000000000 \
    VCAP_APPLICATION={} \
    VCAP_SERVICES={} \
    CF_STACK=cflinuxfs3
    
  3. Cloud Build를 사용하여 builder 이미지 빌드 및 게시

    gcloud builds \
        submit --tag "REGISTRY_URI/builder:stable"
    

    REGISTRY_URI를 빌드 이미지를 게시하려는 Artifact Registry의 주소로 바꿉니다. 예를 들면 REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/builder:stable입니다.

런타임 이미지 만들기

이 섹션에서는 cflinux3을 기본 이미지로 사용하여 실행 이미지를 만듭니다. 실행 이미지는 최종 애플리케이션 이미지를 만들 때 기본 이미지로 사용됩니다.

  1. run/cd라는 디렉터리를 만듭니다.

    mkdir run && cd run
    
  2. run/ 폴더에서 다음 코드를 사용하여 entrypoint.bash라는 새 셸 스크립트를 만듭니다.

    #!/usr/bin/env bash
    set -e
    
    if [[ "$@" == "" ]]; then
    exec /lifecycle/launcher "/home/vcap/app" "" ""
    else
    exec /lifecycle/launcher "/home/vcap/app" "$@" ""
    fi
    
  3. run/ 폴더에서 Dockerfile이라는 새 파일을 만들고 다음 코드를 붙여넣습니다.

    ARG CF_LINUX_FS=cloudfoundry/cflinuxfs3
    
    FROM golang:1.20-bullseye AS launcher_build
    WORKDIR /build
    RUN ["git", "clone", "--depth=1", "https://github.com/cloudfoundry/buildpackapplifecycle.git"]
    WORKDIR /build/buildpackapplifecycle
    RUN ["go", "mod", "init", "code.cloudfoundry.org/buildpackapplifecycle"]
    RUN ["go", "mod", "tidy"]
    RUN CGO_ENABLD=0 go build -o /launcher ./launcher/
    
    FROM $CF_LINUX_FS
    # Set up container tools related to launching the application
    WORKDIR /lifecycle
    COPY entrypoint.bash /lifecycle/entrypoint.bash
    RUN ["chmod", "+rx", "/lifecycle/entrypoint.bash"]
    COPY --from=launcher_build /launcher /lifecycle/launcher
    
    # Set up environment to match Cloud Foundry
    WORKDIR /home/vcap
    USER vcap:vcap
    ENTRYPOINT ["/lifecycle/entrypoint.bash"]
    
    # Expose 8080 to allow app to be run on Cloud Foundry,
    # and PORT so the container can be run locally.
    # These do nothing on Cloud Run.
    EXPOSE 8080/tcp
    # Set up environment variables similar to Cloud Foundry.
    ENV CF_INSTANCE_ADDR=127.0.0.1:8080 \
    CF_INSTANCE_IP=127.0.0.1 \
    INSTANCE_IP=127.0.0.1 \
    CF_INSTANCE_INTERNAL_IP=127.0.0.1 \
    VCAP_APP_HOST=127.0.0.1 \
    CF_INSTANCE_PORT=80 \
    LANG=en_US.UTF-8 \
    CF_INSTANCE_GUID=00000000-0000-0000-0000-000000000000 \
    INSTANCE_GUID=00000000-0000-0000-0000-000000000000 \
    CF_INSTANCE_INDEX=0 \
    INSTANCE_INDEX=0 \
    PORT=8080 \
    VCAP_APP_PORT=8080 \
    VCAP_APPLICATION={} \
    VCAP_SERVICES={}
    
  4. Cloud Build를 사용하여 runtime 이미지 빌드 및 게시:

    gcloud builds submit \
        --tag "REGISTRY_URI/runtime:stable"
    

    REGISTRY_URI를 빌드 이미지를 게시하려는 Artifact Registry의 주소로 바꿉니다. 예를 들면 REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/runtime:stable.입니다.

Cloud Foundry 애플리케이션을 OCI 이미지로 빌드

Cloud Run으로 마이그레이션된 각 애플리케이션에는 Cloud Foundry가 애플리케이션을 실행하는 방법과 일치하는 자체 Dockerfile이 필요합니다. Dockerfile은 다음을 수행합니다.

  • 빌더 이미지를 로드합니다.
  • v2 빌드팩 수명 주기를 실행하여 droplet을 만듭니다.
  • Droplet의 콘텐츠를 추출합니다.
  • 실행 이미지에 droplet의 콘텐츠를 로드하여 실행 가능한 애플리케이션 이미지를 만듭니다.

최종 애플리케이션 이미지는 Cloud Foundry 및 Cloud Run과 모두 호환되므로 마이그레이션을 A/B 테스트하여 예상치 못한 동작을 디버깅할 수 있습니다.

이 프로세스는 마이그레이션해야 하는 각 애플리케이션에 대해 애플리케이션팀에서 수행해야 합니다.

배포된 Cloud Foundry 애플리케이션에서 빌드 정보 수집

  1. 애플리케이션 스택을 살펴봅니다. 스택은 cf push-s 플래그 또는 애플리케이션 매니페스트의 stack 필드를 통해 제공됩니다.

    1. 스택이 Windows인 경우 애플리케이션이 Cloud Run과 호환되지 않을 수 있습니다. 계속하기 전에 애플리케이션을 Linux로 포팅해야 합니다.
    2. 스택이 비어 있거나 cflinuxfs3 또는 cflinuxfs4인 경우 애플리케이션을 Cloud Run으로 마이그레이션할 수 있습니다.
  2. 애플리케이션 빌드팩 목록을 수집합니다. 빌드팩은 cf push-b 플래그, 애플리케이션 매니페스트의 buildpack 필드 또는 애플리케이션 매니페스트의 buildpacks 필드를 통해 제공됩니다.

    1. 빌드팩이 지정되지 않은 경우 빌드팩이 자동으로 감지된다는 의미입니다. Cloud Foundry의 가장 최근 애플리케이션 배포에서 감지된 빌드팩 목록을 확인하거나 경로를 알고 있는 경우 이를 명시적으로 지정합니다.
    2. 빌드팩이 URL인 경우 URL을 기록해 두고 다음 단계로 진행합니다.
    3. 닉네임을 사용하는 빌드팩의 경우 다음 표를 사용하여 빌드팩을 URL에 매핑합니다.

      닉네임 URL
      staticfile_buildpack https://github.com/cloudfoundry/staticfile-buildpack
      java_buildpack https://github.com/cloudfoundry/java-buildpack
      ruby_buildpack https://github.com/cloudfoundry/ruby-buildpack
      dotnet_core_buildpack https://github.com/cloudfoundry/dotnet-core-buildpack
      nodejs_buildpack https://github.com/cloudfoundry/nodejs-buildpack
      go_buildpack https://github.com/cloudfoundry/go-buildpack
      python_buildpack https://github.com/cloudfoundry/python-buildpack
      php_buildpack https://github.com/cloudfoundry/php-buildpack
      binary_buildpack https://github.com/cloudfoundry/binary-buildpack
      nginx_buildpack https://github.com/cloudfoundry/nginx-buildpack

      덜 일반적인 빌드팩의 소스는 Cloud Foundry GitHub 조직에서 찾을 수 있습니다.

  3. 이미지의 소스 코드 위치를 수집합니다. 소스는 애플리케이션 매니페스트의 path 속성 또는 cf push 명령어의 -p 플래그를 통해 제공됩니다. 소스가 정의되지 않은 경우 현재 디렉터리를 참조합니다.

  4. 소스 코드 디렉터리에 .cfignore 파일이 있는지 확인합니다. 있는 경우 .gcloudignore.라는 파일로 옮깁니다.

Cloud Foundry 애플리케이션 빌드

이 단계에서는 빌드 요소를 다음 폴더 구조로 정리합니다.

.
├── cloudbuild.yaml
├── Dockerfile
├── .gcloudignore
└── src
    ├── go.mod
    └── main.go
  • cloudbuild.yaml은 구체적인 빌드 지침을 Cloud Build에 제공합니다.
  • Dockerfile은 빌드를 사용하고 이전 단계의 이미지를 실행하여 애플리케이션 이미지를 만듭니다.
  • src/에는 애플리케이션 소스 코드가 포함되어 있습니다.
  1. 다음 콘텐츠로 디렉터리에 Dockerfile이라는 파일을 만듭니다.

    ARG BUILD_IMAGE
    ARG RUN_IMAGE
    FROM $BUILD_IMAGE as build
    
    COPY src /staging/app
    COPY src /tmp/app
    
    ARG BUILDPACKS
    RUN /lifecycle/builder \
    -buildArtifactsCacheDir=/tmp/cache \
    -buildDir=/tmp/app \
    -buildpacksDir=/tmp/buildpacks \
    -outputBuildArtifactsCache=/tmp/output-cache \
    -outputDroplet=/tmp/droplet \
    -outputMetadata=/tmp/result.json \
    "-buildpackOrder=${BUILDPACKS}" \
    "-skipDetect=true"
    
    FROM $RUN_IMAGE
    COPY --from=build /tmp/droplet droplet
    RUN tar -xzf droplet && rm droplet
    
  2. 다음 콘텐츠로 디렉터리에 cloudbuild.yaml이라는 파일을 만듭니다.

    steps:
    - name: gcr.io/cloud-builders/docker
      args:
      - 'build'
      - '--network'
      - 'cloudbuild'
      - '--tag'
      - '${_TAG}'
      - '--build-arg'
      - 'BUILD_IMAGE=${_BUILD_IMAGE}'
      - '--build-arg'
      - 'RUN_IMAGE=${_RUN_IMAGE}'
      - '--build-arg'
      - 'BUILDPACKS=${_BUILDPACKS}'
      - '.'
    images:
    - "${_TAG}"
    options:
      # Substitute build environment variables as an array of KEY=VALUE formatted strings here.
      env: []
    substitutions:
      _BUILD_IMAGE: BUILD_IMAGE_URI
      _RUN_IMAGE:  RUN_IMAGE_URI
      _BUILDPACKS: BUILDPACK_URL
      _TAG: APP_ARTIFACT_REGISTRY/APP_NAME:latest
    
    • BUILD_IMAGE_URI를 이전 단계에서 만든 빌드 이미지의 URI로 바꿉니다.
    • RUN_IMAGE_URI를 이전 단계에서 만든 실행 이미지의 URI로 바꿉니다.
    • BUILDPACK_URL을 애플리케이션에서 사용하는 빌드팩의 URL로 바꿉니다. 여러 빌드팩이 포함된 쉼표로 구분된 목록일 수 있습니다.
  3. .cfignore 파일이 있으면 이름이 .gcloudignore인 디렉터리에 복사합니다.

  4. 디렉터리에 src라는 디렉터리를 만듭니다.

  5. 애플리케이션의 콘텐츠를 src:에 복사합니다.

    1. 소스가 ZIP 파일(.jar 파일 포함)인 경우 콘텐츠의 압축을 src로 풉니다.
    2. 소스 코드가 디렉터리인 경우 콘텐츠를 src에 복사합니다.
  6. gcloud builds submit .을 실행하여 애플리케이션을 빌드합니다.

알려진 비호환성

  • VCAP_SERVICES와 같이 Cloud Foundry 삽입 환경 변수를 사용하는 빌드팩은 작동하지 않습니다. 대신 언어의 관리 시스템을 사용하여 삽입 항목에 대한 종속 항목을 명시적으로 선언해야 합니다.
  • 이 방식으로 생성된 이미지에 패치를 적용하려면 최신 버전의 빌드 및 실행 이미지를 사용하여 이미지를 다시 빌드해야 합니다. Cloud Foundry에서 실행하는 경우 BOSH 스템셀 업데이트로 애플리케이션 이미지가 자동으로 패치되지 않습니다.
  • 빌드는 Cloud Foundry 클러스터와 다른 네트워크 환경에서 수행되므로 내부 패키지 미러에 액세스할 수 있는 커스텀 Cloud Build 풀을 설정해야 할 수 있습니다.

다음 단계