Managed-By URL 어노테이션

Managed-By URL 어노테이션 (Managed By URL Annotation)

argocd.argoproj.io/managed-by-url 어노테이션은 Application 리소스가 어떤 Argo CD 인스턴스가 그것을 관리하는지 지정할 수 있게 해줘요. 여러 Argo CD 인스턴스를 사용할 때 UI의 애플리케이션 링크가 올바른 관리 인스턴스를 가리키도록 하려면 유용해요.

출처: 문서

본문

개요 (Overview)

argocd.argoproj.io/managed-by-url 어노테이션은 Application 리소스가 어떤 Argo CD 인스턴스가 그것을 관리하는지 지정할 수 있게 해줘요. 이것은 여러 Argo CD 인스턴스가 있고 UI의 애플리케이션 링크가 올바른 관리 인스턴스를 가리켜야 할 때 유용해요.

사용 사례 (Use Case)

app-of-apps 패턴으로 여러 Argo CD 인스턴스를 사용할 때:

  • 기본(primary) Argo CD 인스턴스가 부모 Application을 만들어요
  • 부모 Application은 보조(secondary) Argo CD 인스턴스가 관리하는 자식 Application을 배포해요
  • 어노테이션이 없으면 기본 인스턴스 UI에서 자식 Application을 클릭하면 기본 인스턴스에서 열려고 시도해요(잘못됨)
  • 어노테이션이 있으면 자식 Application이 보조 인스턴스에서 올바르게 열려요

managed-by-url 어노테이션은 애플리케이션 링크가 올바른 Argo CD 인스턴스로 리다이렉트되도록 보장해요.

[!NOTE] 이 어노테이션은 서로 다른 팀이 각자 Argo CD 인스턴스를 갖는 멀티 테넌트 설정이나, 중앙 인스턴스가 여러 엣지 인스턴스를 관리하는 hub-and-spoke 아키텍처에서 특히 유용해요.

예시 (Example)

이 예시는 부모 Application이 Git 리포지토리에서 자식 Application을 배포하는 app-of-apps 패턴을 보여줘요.

1단계: 부모 Application 만들기 (Create Parent Application)

기본 Argo CD 인스턴스에 부모 Application을 만드세요:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: parent-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/YOUR-ORG/my-apps-repo.git
    targetRevision: main
    path: path-to-child-app
  destination:
    server: https://kubernetes.default.svc
    namespace: namespace-b
  syncPolicy:
    automated:
      selfHeal: true
      prune: true

2단계: Git 리포지토리에 자식 Application 만들기 (Create Child Application in Git Repository)

Git 리포지토리 apps/child-apps/child-app.yaml에서 managed-by-url 어노테이션을 추가하세요:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: child-app
  namespace: namespace-b
  annotations:
    argocd.argoproj.io/managed-by-url: "http://localhost:8081" # replace with actual secondary ArgoCD URL in real setup
spec:
  project: default
  source:
    repoURL: https://github.com/YOUR-ORG/my-apps-repo.git
    targetRevision: HEAD
    path: path-to-child-app
  destination:
    server: https://kubernetes.default.svc
    namespace: namespace-b
  syncPolicy:
    automated:
      selfHeal: true
      prune: true

결과 (Result)

기본 인스턴스의 UI에서 부모 Application을 볼 때:

  • 부모 Application은 Git에서 동기화되고 자식 Application을 배포해요
  • 리소스 트리에서 child-app을 클릭하면 https://secondary-argocd.example.com/applications/namespace-b/child-app으로 이동해요
  • 링크는 실제로 관리하는 올바른 Argo CD 인스턴스에서 자식 Application을 열어요

구성 (Configuration)

어노테이션 형식 (Annotation Format)

필드
어노테이션 argocd.argoproj.io/managed-by-url
대상 Application
유효한 HTTP(S) URL
필수 여부 아니요

URL 검증 (URL Validation)

어노테이션 값은 반드시 유효한 HTTP(S) URL이어야 해요:

  • https://argocd.example.com
  • https://argocd.example.com:8080
  • http://localhost:8080 (개발용)
  • argocd.example.com (프로토콜 누락)
  • javascript:alert(1) (잘못된 프로토콜)

잘못된 URL은 Application이 생성되거나 업데이트되는 것을 막아요.

동작 방식 (Behavior)

애플리케이션 링크를 생성할 때 Argo CD는:

  • 어노테이션 없음: 현재 인스턴스의 기본 URL을 사용해요
  • 어노테이션 있음: 어노테이션의 URL을 사용해요
  • 잘못된 어노테이션: 현재 인스턴스의 기본 URL로 폴백하고 경고를 기록해요

[!WARNING] 어노테이션의 URL이 사용자 브라우저에서 접근 가능한지 확인하세요. 내부 배포의 경우 내부 DNS 이름을 사용하거나 적절한 네트워크 접근을 구성하세요.

로컬 테스트 (Testing Locally)

두 개의 로컬 Argo CD 인스턴스로 어노테이션을 테스트하려면:

# Install primary instance
kubectl create namespace argocd
kubectl apply -n argocd --server-side --force-conflicts -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# Install secondary instance
kubectl create namespace namespace-b
kubectl apply -n namespace-b --server-side --force-conflicts -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# Port forward both instances
kubectl port-forward -n argocd svc/argocd-server 8080:443 &
kubectl port-forward -n namespace-b svc/argocd-server 8081:443 &

# Wait for Argo CD to be ready
kubectl wait --for=condition=available --timeout=300s deployment/argocd-server -n argocd

# Get the admin password for primary instance
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo

그런 다음:

  1. 브라우저에서 http://localhost:8080을 여세요
  2. 사용자 이름 admin과 위 명령의 비밀번호로 로그인하세요
  3. parent-app Application으로 이동하세요
  4. 리소스 트리에서 child-app을 클릭하세요
  5. http://localhost:8081/applications/namespace-b/child-app으로 리다이렉트되어야 해요

보조 인스턴스에 로그인하고 child-app에 접근하려면 비밀번호를 얻기 위해 명령을 반복해야 해요:

# Get the admin password for secondary instance
kubectl -n namespace-b get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo

문제 해결 (Troubleshooting)

어노테이션이 있는지 확인하세요:

kubectl get application child-app -n instance-b -o jsonpath='{.metadata.annotations.argocd\.argoproj\.io/managed-by-url}'

예상 출력: http://localhost:8081 같은 완전한 URL 또는 설정된 URL(즉, https://secondary-argocd.example.com)

어노테이션이 있는데도 링크가 동작하지 않는다면:

  • 브라우저에서 URL에 접근 가능한지 확인하세요
  • 브라우저 콘솔에서 오류를 확인하세요
  • URL 형식이 올바른지 확인하세요(http:// 또는 https:// 포함)

Application 생성 실패 (Application Creation Fails)

Application 생성이 "invalid managed-by URL" 오류로 실패하면:

  • ✅ URL에 프로토콜(https:// 또는 http://)이 포함되어 있는지
  • ✅ URL에 오타가 없는지
  • ✅ URL에 유효한 문자만 사용했는지
  • ✅ URL이 잠재적으로 악성 스킴(예: javascript:)이 아닌지

중첩 애플리케이션이 동작하지 않는 경우 (Nested Applications Not Working)

app-of-apps 패턴의 경우 확인하세요:

  1. Git의 자식 Application YAML에 어노테이션이 포함되어 있는지
  2. 부모 Application이 성공적으로 동기화되었는지
  3. 클러스터에 자식 Application이 생성되었는지

자식 Application이 존재하는지 확인하세요:

kubectl get application CHILD-APP-NAME -n NAMESPACE

함께 보기 (See Also)

더 알아보기 (Learn more)