“Crossplane v2 업그레이드, 진짜 안전할까?” `beta upgrade check`로 깨지는 지점 먼저 잡기

도입부: Crossplane v2는 대체로 v1.x에서 무리 없이 넘어갈 수 있지만, 몇 가지 breaking change를 밟는 순간 업그레이드가 ‘운영 사고’로 변할 수 있습니다. 이 글에서는 v1.20.9에 추가된 crossplane beta upgrade check업그레이드 전 위험 요소를 자동 탐지하고, CI 게이트로 운영 안정성을 높이는 방법을 정리합니다.

Crossplane v2 업그레이드에서 진짜 불안한 지점

Crossplane은 OpenTofu(Terraform 계열)처럼 “한 번 apply하고 끝”이 아니라, 클러스터 안에서 지속적으로 reconcile(조정)하는 컨트롤 플레인입니다. 그래서 업그레이드 안정성도 “변경의 계획 가능성”보다는, 다음 질문으로 귀결되는 경우가 많습니다.

  • 지금 내 클러스터가 v2에서 제거/변경된 기능을 쓰고 있나?
  • 쓰고 있다면 어떤 리소스가, 어떻게, 어느 정도로 깨지나?
  • 업그레이드 전에 무엇을 고쳐야 하고, 그걸 자동으로 막을 수(게이트) 있나?

v2에서 특히 체감이 큰 변화 축으로는 Composition의 함수 파이프라인(Composition Functions) 방향성이 자주 언급됩니다. 이건 Crossplane이 “템플릿 조합 도구”에서 더 나아가, 조합 로직 자체를 컨트롤 플레인 내부의 확장 런타임으로 끌어들이는 변화입니다. 운영 안정성 관점에서는 강력한 가드레일을 만들 수 있는 반면, 함수 런타임/버전/실패가 새로운 리스크 포인트가 될 수도 있습니다.

그런데 현실적으로는, “우리 클러스터가 지금 당장 어디가 깨질지”를 사람 눈으로 전수 점검하기가 어렵습니다. 이 지점을 노린 도구가 바로 beta upgrade check입니다.

crossplane beta upgrade check란?

Crossplane v1.20.9에 포함된 crossplane beta upgrade check는 **읽기 전용(read-only)**으로 라이브 클러스터를 스캔해서,

  • v2 업그레이드 시 문제가 될 수 있는 항목을 찾아내고
  • 무엇이 왜 문제인지, 어떻게 고쳐야 하는지까지
  • 정확하게 리포트합니다.

특히 중요한 포인트는 다음 두 가지입니다.

  1. 텍스트/JSON 출력 지원
    사람이 보기 좋은 텍스트로도, 자동화에 적합한 JSON으로도 결과를 받을 수 있습니다.

  2. 문제 발견 시 non-zero 종료 코드
    즉, “문제 있으면 실패”로 만들 수 있어 CI에서 업그레이드 준비 상태를 게이트할 수 있습니다. 운영 안정성에서 이게 꽤 큰 차이를 만듭니다. “업그레이드 해보고 깨지면 롤백”이 아니라, “깨지는 변경을 업그레이드 전에 발견하고 차단”할 수 있기 때문입니다.

실전: 업그레이드 전 클러스터 스캔하기 (CLI v1.20)

Crossplane v1.20 CLI 문서에 beta upgrade check가 커맨드 레퍼런스로 포함되어 있고, v1.20.9 릴리스에서 이 기능이 “v2 준비를 돕는 핵심 추가점”으로 들어왔습니다.

기본 사용 흐름은 다음처럼 가져가면 좋습니다.

# (예시) 현재 kube-context 기준으로 v2 업그레이드 위험 요소 점검
crossplane beta upgrade check

자동화/리포팅을 염두에 두면 JSON 출력이 유리합니다.

# (예시) JSON 출력으로 결과를 받아 CI/파이프라인에서 파싱
crossplane beta upgrade check --output json

여기서 핵심은 “체크 결과가 0이 아니면 파이프라인 실패”로 만들 수 있다는 점입니다. 제 경험상 업그레이드에서 가장 무서운 건 기술적 난이도보다도, **‘놓친 것’**이기 때문에, 이런 형태의 기계적 게이트가 효과가 큽니다.

CI 게이트로 운영 안정성 올리기: “업그레이드 가능 상태”를 정의하기

beta upgrade check를 CI에 넣으면, v2 업그레이드 준비를 다음처럼 “정의 가능한 상태”로 만들 수 있습니다.

  • 업그레이드 체크가 항상 성공(Exit 0) 해야만 머지 가능
  • 실패 시 리포트(JSON)를 아티팩트로 남겨 수정 가이드를 바로 확인
  • 특정 브랜치/환경(예: staging)에서 주기적으로 돌려 드리프트처럼 업그레이드 준비 상태가 나빠지는 것도 조기 감지

간단한 GitHub Actions 예시는 이런 형태가 됩니다.

name: crossplane-v2-upgrade-gate

on:
  pull_request:

jobs:
  upgrade-check:
    runs-on: ubuntu-latest
    steps:
      - name: Set kubeconfig
        run: |
          # 환경에 맞게 kubeconfig 주입 (예: OIDC, secret, self-hosted runner 등)
          echo "configure kubeconfig here"

      - name: Run Crossplane upgrade check
        run: |
          crossplane beta upgrade check --output json > upgrade-check.json

      - name: Upload report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: crossplane-upgrade-check
          path: upgrade-check.json

설계 포인트는 한 가지입니다. “문제 발견 = 실패”를 강제하고, 실패 시엔 리포트를 남겨서 수정이 바로 이어지게 만드는 겁니다. 이렇게 하면 업그레이드가 이벤트성 작업이 아니라, 평소처럼 관리되는 “품질 기준”으로 바뀝니다.

OpenTofu 대비 “안정성”에서 v2가 경쟁력이 생기는 지점

대화에서 제가 가장 크게 느낀 결론은 이거였습니다.

  • OpenTofu의 안정성은 “변경 전 Plan 기반의 예측 가능성/재현성”에 강점이 있고
  • Crossplane(v2 포함)의 안정성은 “운영 중 지속 reconcile + 정책/스키마/조합 로직으로 가드레일을 강제”하는 데 강점이 있습니다.

v2에서 Composition Functions 방향성이 강해질수록, Crossplane은 정책 위반을 사후 복구(reconcile)로만 다루는 게 아니라, 조합 로직 단계에서 더 강하게 “사전 차단/표준화”할 여지가 커집니다. 반면, 함수 런타임이 새로운 장애 지점이 될 수 있으니 관측성/버전 관리/실패 격리 설계가 같이 따라가야 합니다.

그리고 그 “업그레이드로 인한 불안정” 자체를 줄이기 위한 장치가 beta upgrade check라고 저는 이해했습니다. 업그레이드가 두려운 이유는 대부분 “깨지는 변경을 모른 채 들어가는 것”이니까요.

마무리

Crossplane v2는 호환성이 높은 편이지만, 운영 안정성 관점에서 중요한 건 “대부분 된다”가 아니라 “내 클러스터는 진짜 안전한가”를 증명하는 절차입니다. crossplane beta upgrade check를 CI 게이트로 붙이면, v2 업그레이드는 더 이상 감(感)으로 하는 작업이 아니라 자동 검증되는 변경 관리가 됩니다.

참고 자료