Cloud Foundry 구성을 Cloud Run으로 마이그레이션

Cloud Run으로 마이그레이션하는 각 Cloud Foundry 애플리케이션의 구성 마이그레이션 프로세스를 완료해야 합니다. 구성 마이그레이션은 다음으로 구성됩니다.

  • Cloud Foundry manifest.yaml을 Cloud Run service.yaml로 변환
  • Cloud Run에 배포하기 위해 애플리케이션에 지원 서비스 연결
  • Cloud Run 서비스에 애플리케이션 배포

manifest.yamlservice.yaml로 변환

Cloud Foundry 매니페스트 또는 cf CLI 플래그를 상응하는 Cloud Run 서비스 정의 YAML로 변환해야 합니다.

Cloud Run을 사용하려면 각 애플리케이션에 자체 서비스 YAML 파일이 있어야 합니다. Cloud Foundry 매니페스트의 애플리케이션을 서비스 YAML 파일로 마이그레이션하려면 다음 안내를 따르세요.

  1. 애플리케이션에 대해 다음 표에 나열된 속성을 수집합니다. 애플리케이션 수준에서 수정되지 않은 속성은 전역 Cloud Foundry 플랫폼 구성으로 재정의되었을 수 있습니다. 실제 값을 확인하려면 플랫폼 관리자가 제공한 문서를 참고하세요.

    애플리케이션 속성 cf CLI v6 플래그 설명
    name NAME 인수 Cloud Foundry에서 애플리케이션의 고유한 이름입니다.
    command -c /bin/sh 또는 /bin/bash에서 실행할 명령어
    disk_quota -k 애플리케이션에 할당될 디스크 양입니다.

    유효한 단위는 M, MB, G, r B입니다.

    예상 기본값: 1G

    docker.image --docker-image, -o 실행할 애플리케이션이 포함된 이미지입니다.
    health-check-http-endpoint 해당 사항 없음 상태 확인 유형이 HTTP인 경우 HTTP 상태를 확인하는 데 사용되는 엔드포인트입니다.

    기본값: /

    health-check-invocation-timeout 해당 사항 없음 개별 포트와 HTTP 기반 상태 점검 사이의 시간(초)입니다.

    기본값: 1

    health-check-type --health-check-type, -u 애플리케이션에서 수행할 상태 점검 유형입니다. 유효한 값은 port, http, none, process입니다.

    기본값: port

    instances -i Cloud Foundry가 실행할 앱의 인스턴스 수입니다.

    기본값: 1

    memory -m 애플리케이션의 인스턴스별 메모리 한도입니다.

    유효한 단위는 M, MB, G 또는 GB입니다.

    예상 기본값: 1G

    timeout -t 앱 시작과 첫 번째 상태 점검 사이에 허용되는 시간(초)입니다.

    예상 기본값: 60

  2. Google Cloud 프로젝트 및 Cloud Run 설정에 관한 다음 정보를 수집합니다.

    속성 설명
    project_number 배포하려는 Google Cloud 프로젝트의 프로젝트 번호입니다.
    region 앱을 배포할 리전입니다.
    vpc-access-connector 플랫폼 관리자가 애플리케이션을 사용하고자 하는 VPC 커넥터 이름입니다.
    vpc-access-egress 플랫폼 관리자가 애플리케이션을 사용하고자 하는 VPC 이그레스 이름입니다.
    custom-audiences 애플리케이션에 인증할 수 있는 커스텀 잠재고객입니다.
    serviceAccountName 애플리케이션이 Google Cloud에서 역할을 수행할 ID입니다.
    image 이전 단계에서 생성한 애플리케이션 이미지입니다.
  3. 프로젝트 루트에 있는 service.yaml 파일에 다음 템플릿을 채웁니다.

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  # Set this to be the name of your app
  name: "APP_NAME"
  # Set this to be the project number of the project you're deploying to.
  namespace: "PROJECT_NUMBER"
  labels:
    # Set this to be the region you're deploying in.
    cloud.googleapis.com/location: REGION
    migrated-from: cloud-foundry
  annotations:
    run.googleapis.com/ingress: internal-and-cloud-load-balancing
spec:
  template:
    metadata:
      annotations:
        # Set to the greater of 1 or the `instances` attribute.
        autoscaling.knative.dev/minScale: '1'
        # Set to the greater of 1 or the `instances` attribute.
        autoscaling.knative.dev/maxScale: '1'
        run.googleapis.com/cpu-throttling: CPU_ALLOCATION
        run.googleapis.com/startup-cpu-boost: 'true'
        # Set to true if you rely on sticky sessions. These will be turned
        # on in Cloud Foundry if the server sends a JSESSIONID cookie back
        # on responses.
        run.googleapis.com/sessionAffinity: 'false'
        run.googleapis.com/execution-environment: gen2
        # Set the following values to match what your platform administrator recommends.
        run.googleapis.com/vpc-access-connector: ADMINISTRATOR_PROVIDED
        run.googleapis.com/vpc-access-egress: ADMINISTRATOR_PROVIDED
        run.googleapis.com/custom-audiences: ADMINISTRATOR_PROVIDED
    spec:
      # CF doesn't limit, but CR has a max of 1000.
      containerConcurrency: 1000
      # Default value for gorouter in PCF.
      timeoutSeconds: 900
      # Set the following value to match what your platform administrator recommends.
      serviceAccountName: ADMINISTRATOR_PROVIDED
      containers:
      - name: user-container
        # Set the following value to either:
        # - The image you built for your application in the last section of the guide.
        # - The docker.image attribute of your app's configuration if it's a Docker app.
        image: IMAGE
        # Set `command` based on the following rules:
        # - If your app has no `command` attribute: null.
        # - If your app has a docker.image attribute: ['/bin/sh', '-c']
        # - Otherwise: ['/bin/bash', '-c']
        command: null
        # Set `args` based on the following rules:
        # - If your app has no `command` attribute: null.
        # - If your app has a `command` attribute: ['value of command']
        args: null
        ports:
          # Set name based on the following rules:
          # - If your app is HTTP/2 or gRPC: "h2c"
          # - Else: "http1"
        - name: HTTP1_OR_H2C
          containerPort: 8080
        env:
          # For each key/value pair in your space's running environment variable groups,
          # which can be retried by running `cf running-environment-variable-group`,
          # add the following:
        - name: KEY
          value: VALUE
          # For each key/value pair in your manifest's `env` map, add the following:
        - name: KEY
          value: VALUE
          # Populate MEMORY_LIMIT with the amount of memory supplied to this instance
          # in MiB with 'M' as a suffix.
        - name: MEMORY_LIMIT
          value: '0M'
          # Set the following values in the JSON below:
          # - `application_name` and `name` to match metadata.name in this file.
          # - `application_uris` and `uris` to be the URI you want to assign the app on the
          #    load balancer.
          # - `limits.disk` to be the amount (in MiB) of disk assigned to your app.
          #   The amount will be in the `disk_quota` attribute of the CF manifest, or a
          #   default value for your cluster, typically 1GiB.
          # - `limits.mem` to be the amount (in MiB) of memory assigned to your app.
          #   The amount will be in your `memory` attribute of the CF manifest, or a
          #   default value for your cluster, typically 1GiB.
          # - `space_name` to be the value of metadata.space in this file.
        - name: VCAP_APPLICATION
          value: |-
                  {
                    "application_id": "00000000-0000-0000-0000-000000000000",
                    "application_name": "app-name",
                    "application_uris": [],
                    "limits": {
                      "disk": 1024,
                      "mem": 256
                    },
                    "name": "app-name",
                    "process_id": "00000000-0000-0000-0000-000000000000",
                    "process_type": "web",
                    "space_name": "none",
                    "uris": []
                  }
        resources:
          limits:
            # Set memory limit to be the sum of the memory and disk assigned to your app in CF.
            # 
            # Disk amount will be in the `disk_quota` attribute of the CF manifest, or a
            # default value for your cluster, typically 1GiB.
            #
            # Memory will be in your `memory` attribute of the CF manifest, or a
            # default value for your cluster, typically 1GiB.
            memory: MEMORY_LIMIT
            # Set cpu according to the following calculation:
            #
            # 1. Take the amount of memory in your `memory` attribute of the CF
            #    manifest, or a default value for your cluster, typically 1GiB.
            # 2. Divide that by the total amount of memory on the underlying BOSH VM.
            # 3. Multiply that by the total number of CPUs on the BOSH VM.
            # 4. Find the nearest valid value based on the rules in:
            #    https://cloud.google.com/run/docs/configuring/cpu#setting
            cpu: CPU_LIMIT
        # If `health-check-type` is "process" or "none", delete the startupProbe section.
        startupProbe:
          # If `health-check-type` is "port" or blank, delete the httpGet section.
          httpGet:
            # Set to be the value of `health-check-http-endpoint` or / if blank.
            path: CHECK_PATH
            port: 8080
          # If `health-check-type` is "http", delete the tcpSocket section.
          tcpSocket:
            port: 8080
          # Set to the value of `health-check-invocation-timeout` or 1
          timeoutSeconds: 1
          # Set failure threshold to be the following calculation:
          #
          # 1. Take the `timeout` from the CF manifest, use 60 if unset.
          # 2. Divide by 2.
          # 3. Round up to the nearest integer.
          failureThreshold: 1
          successThreshold: 1
          periodSeconds: 2
        # If `health-check-type` is "process" or "none", delete the livenessProbe section.
        livenessProbe:
          # If `health-check-type` is "port" or blank, delete the httpGet section.
          httpGet:
            # Set to be the value of `health-check-http-endpoint` or / if blank.
            path: CHECK_PATH
            port: 8080
          # If `health-check-type` is "http", delete the tcpSocket section.
          tcpSocket:
            port: 8080
          # Set to the value of `health-check-invocation-timeout` or 1.
          timeoutSeconds: 1
          failureThreshold: 1
          successThreshold: 1
          periodSeconds: 30
  traffic:
  - percent: 100
    latestRevision: true

모든 지원 서비스 연결

Spring 또는 Steeltoe와 같은 Cloud Foundry 애플리케이션에서 서비스 삽입 및 검색을 허용하려면 VCAP_SERVICES 환경 변수를 구성해야 합니다. 마이그레이션하는 각 애플리케이션에 대해 이 작업을 실행해야 합니다. 자세한 내용은 Cloud Foundry VCAP_SERVICES 문서를 참조하세요.

애플리케이션이 이미 Cloud Foundry에서 실행 중이고 Cloud Run에서 동일한 서비스에 연결하려 할 때는 기존 환경 변수를 사용할 수 있습니다. 그렇지 않으면 새 VCAP_SERVICES를 만들어야 합니다.

VCAP_SERVICES 환경 변수를 구성하려면 다음 안내를 따르세요.

  1. 기존 VCAP_SERVICES의 경우에 다음을 수행합니다.

    1. cf env APP_NAME을 실행하여 VCAP_SERVICES 환경 변수를 가져옵니다.
    2. 그래도 문제가 해결되지 않으면
      1. Cloud Foundry에서 애플리케이션에 연결합니다. cf ssh APP_NAME
      2. env 명령어를 실행하고 VCAP_SERVICES의 출력을 가져옵니다.
      3. exit를 실행하여 SSH 세션을 종료합니다.
    3. VCAP_SERVICES 값을 vcap.json이라는 새 파일에 저장합니다.
  2. 서비스를 추가하거나 Cloud Foundry와 다른 서비스에 연결하려면 새 VCAP_SERVICES를 만듭니다.

    1. 텍스트 편집기에서 빈 JSON 맵 {}을 만듭니다.
    2. 추가하려는 각 서비스에 대해 다음을 실행합니다.
    3. 앱에서 VCAP_SERVICES를 파싱하는 데 사용하는 라이브러리의 문서를 참고하여 추가하려는 유형의 결합을 발견하는 방법을 알아보세요.
    4. 서비스 제공업체의 이름이 없는 경우 일반적으로 mysql, postgresql 또는 elasticsearch와 같은 서비스 제공업체의 이름으로 맵에 키를 추가합니다. 값을 빈 배열로 설정합니다.
    5. 다음 속성을 사용하여 배열에 객체를 추가합니다.

      1. 일반적으로 서비스를 검색/바인딩하는 데 사용되지 않는 메타데이터:

        • binding_name: 서비스에 대한 애플리케이션 권한을 부여하는 리소스를 나타내는 문자열입니다. 데이터베이스 사용자 이름, 방화벽 규칙, 서비스 계정 이름 등이 될 수 있습니다.
        • instance_name: 지원 서비스 이름을 나타내는 문자열입니다. 데이터베이스 이름, 임의의 값, 전역 서비스의 센티널 값일 수 있습니다.
        • name: 존재하는 경우 binding_name이고, 그렇지 않으면 instance_name입니다. 이 값은 일반적으로 중요하지 않습니다.
        • label: 이 바인딩이 중첩된 VCAP_SERVICES 맵의 키 값입니다.
        • plan: 서비스 요금제의 이름입니다. 예: '사용자 제공', '고가용성'
      2. 서비스를 검색/바인딩하는 데 자주 사용되는 값:

        • tags: 라이브러리가 호환되는 서비스를 찾는 데 도움이 되는 태그 목록입니다. 여기에는 서비스의 일반적인 이름(예: MySQL 및 MariaDB의 경우 mysql, Redis 또는 Cloud Memorystore의 경우 redis, Postgres 호환 데이터베이스의 경우 postgres)이 포함되는 경우가 많습니다.
        • credentials: 클라이언트 라이브러리에서 연결을 수행하는 데 사용하는 사용자 인증 정보가 포함된 객체입니다. 대부분의 클라이언트 라이브러리는 서비스의 표준 URI 또는 JDBC 형식이 포함된 uri 필드를 사용합니다.
    6. 내용을 vcap.json으로 저장합니다.

Cloud Run 리소스에 사용자 인증 정보 연결

사용자 인증 정보를 첨부하려면 다음 단계를 따르세요.

  1. VCAP_SERVICES 환경 변수 콘텐츠를 저장할 보안 비밀을 만들고 다음 명령어로 버전 출력을 기록합니다.

    gcloud secrets create APP_NAME-vcap \
      --replication-policy="automatic" \
      --data-file=vcap.json
    
  2. 애플리케이션의 서비스 계정에 보안 비밀을 읽을 수 있는 권한을 부여합니다.

    gcloud secrets add-iam-policy-binding APP_NAME-vcap \
      --member="serviceaccount:app-service-account" \
      --role="roles/secretmanager.secretAccessor"
    
  3. spec.template.spec.containers[0].env array의 애플리케이션 service.yaml에 다음 환경 변수를 추가합니다.

    - name: VCAP_SERVICES
      valueFrom: 
        secretKeyRef:
          key: Version output by step 1
          name: APP_NAME-vcap
    

일반적인 백업 서비스용 템플릿

다음 섹션에서는 일반적으로 사용되는 지원 서비스에 대한 정보를 제공합니다.

MySQL

MySQL 라이브러리는 일반적으로 mysql 태그를 예상합니다. 일반적으로 credentials에는 다음 키가 포함됩니다.

  • uri 템플릿: mysql://username:password@host:port/dbname. MySQL 문서는 URI 문자열을 만드는 데 유용합니다. 포트는 일반적으로 3306입니다.
  • username: 일부 라이브러리에 필요한 연결 사용자 이름(uri에 포함된 경우에도 해당)입니다.
  • password: 일부 비밀번호에 포함된 연결 비밀번호(uri에 포함된 경우에도 해당)입니다.

Redis

Redis 라이브러리는 일반적으로 redis 태그를 예상합니다. credentials에는 일반적으로 다음 키가 포함됩니다.

  • uri 템플릿: redis://:password@host:port/dbunumber.

IANA Redis URI 문서는 URI 문자열을 만드는 데 유용합니다. 포트는 일반적으로 6379입니다.

RabbitMQ

RabbitMQ 라이브러리는 일반적으로 rabbitmq 태그와 credentials의 다음 키가 필요합니다.

  • uri 템플릿: amqp://username:password@host:port/vhost?query.

RabbitMQ 문서는 URI 문자열을 만드는 데 유용합니다. 포트는 일반적으로 5672입니다.

사용자 제공 서비스

사용자 제공 서비스는 Cloud Foundry의 특수한 유형의 서비스로, 사용자 인증 정보를 삽입할 수 있습니다. 라벨은 항상 user-provided입니다. 태그는 -t 플래그를 통해 cf create-user-provided-service에 전달된 값이고 사용자 인증 정보는 -p 플래그의 콘텐츠입니다.

애플리케이션 배포

완전히 마이그레이션된 Cloud Foundry 애플리케이션을 Cloud Run 서비스에 배포하려면 다음 안내를 따르세요.

  1. 아직 설정하지 않았으면 Cloud Run 환경을 설정합니다.

  2. 다음 명령어를 실행합니다.

    gcloud run services replace service.yaml
    

    그런 다음 배포가 완료될 때까지 잠시 기다립니다. 성공하면 명령줄에 서비스 URL이 표시됩니다.

  3. 웹브라우저에서 서비스 URL을 열고 배포한 서비스로 이동합니다.

수고하셨습니다. Cloud Foundry 애플리케이션을 Cloud Run으로 마이그레이션했습니다.