본문 바로가기
WIKI 기술 지식 베이스

Crossplane과 Argo CD 구성하기

원문 보기 위키 갱신

Crossplane과 Argo CD 구성하기 (Configuring Crossplane with Argo CD)

Argo CD와 Crossplane은 훌륭한 조합입니다. Argo CD는 GitOps를 제공하고, Crossplane은 모든 리소스에 대해 어떤 Kubernetes 클러스터든 유니버설 컨트롤 플레인(Universal Control Plane)으로 바꿔줍니다. 둘이 제대로 함께 동작하려면 구성 세부 사항이 필요합니다.

출처: 문서

본문

이 문서는 이러한 요구 사항을 이해하는 데 도움을 줍니다. Crossplane과 함께 Argo CD 버전 2.4.8 이상을 사용하는 것이 좋습니다.

Argo CD는 Git 리포지토리에 저장된 Kubernetes 리소스 매니페스트를 Kubernetes 클러스터에서 실행 중인 것과 동기화합니다 (GitOps). Argo CD는 리소스를 추적하는 방법을 구성하는 여러 방법이 있습니다. Crossplane과 함께 사용할 때는 Annotation 기반 리소스 추적을 사용하도록 Argo CD를 구성해야 합니다. 자세한 내용은 Argo CD 문서를 참고하세요.

Crossplane으로 Argo CD 구성하기

리소스 추적 방법 설정

Crossplane 관련 객체를 포함하는 Application 리소스를 추적하려면 Argo CD가 annotation 메커니즘을 사용하도록 구성하세요. argocd Namespace의 argocd-cm ConfigMap을 다음과 같이 편집합니다.

apiVersion: v1
kind: ConfigMap
data:
  application.resourceTrackingMethod: annotation

상태(health) 설정

Argo CD는 Kubernetes 리소스에 대한 내장 상태 평가가 있습니다. 커뮤니티는 Argo의 리포지토리에서 일부 검사를 직접 지원합니다. 예를 들어 pkg.crossplane.io의 Provider는 이미 존재하므로 추가 구성이 필요 없습니다.

Argo CD는 인스턴스별로 이러한 검사를 커스터마이즈할 수도 있으며, 이것이 Provider의 CRD 지원을 제공하는 데 사용되는 메커니즘입니다. argocd Namespace의 argocd-cm ConfigMap을 편집해 구성하세요.

📝 참고: ProviderConfig는 상태가 없을 수도 있고 status.users 필드가 있을 수도 있습니다.

apiVersion: v1
kind: ConfigMap
data:
  application.resourceTrackingMethod: annotation
  resource.customizations: |
    "*.upbound.io/*":
      health.lua: |
        health_status = {
          status = "Progressing",
          message = "Provisioning ..."
        }

        local function contains (table, val)
          for i, v in ipairs(table) do
            if v == val then
              return true
            end
          end
          return false
        end

        local has_no_status = {
          "ClusterProviderConfig",
          "ProviderConfig",
          "ProviderConfigUsage"
        }

        if obj.status == nil or next(obj.status) == nil and contains(has_no_status, obj.kind) then
          health_status.status = "Healthy"
          health_status.message = "Resource is up-to-date."
          return health_status
        end

        if obj.status == nil or next(obj.status) == nil or obj.status.conditions == nil then
          if (obj.kind == "ProviderConfig" or obj.kind == "ClusterProviderConfig") and obj.status.users ~= nil then
            health_status.status = "Healthy"
            health_status.message = "Resource is in use."
            return health_status
          end
          return health_status
        end

        for i, condition in ipairs(obj.status.conditions) do
          if condition.type == "LastAsyncOperation" then
            if condition.status == "False" then
              health_status.status = "Degraded"
              health_status.message = condition.message
              return health_status
            end
          end

          if condition.type == "Synced" then
            if condition.status == "False" then
              health_status.status = "Degraded"
              health_status.message = condition.message
              return health_status
            end
          end

          if condition.type == "Ready" then
            if condition.status == "True" then
              health_status.status = "Healthy"
              health_status.message = "Resource is up-to-date."
            end
          end
        end

        return health_status

    "*.crossplane.io/*":
      health.lua: |
        health_status = {
          status = "Progressing",
          message = "Provisioning ..."
        }

        local function contains (table, val)
          for i, v in ipairs(table) do
            if v == val then
              return true
            end
          end
          return false
        end

        local has_no_status = {
          "Composition",
          "CompositionRevision",
          "DeploymentRuntimeConfig",
          "ClusterProviderConfig",
          "ProviderConfig",
          "ProviderConfigUsage"
        }
        if obj.status == nil or next(obj.status) == nil and contains(has_no_status, obj.kind) then
            health_status.status = "Healthy"
            health_status.message = "Resource is up-to-date."
          return health_status
        end

        if obj.status == nil or next(obj.status) == nil or obj.status.conditions == nil then
          if (obj.kind == "ProviderConfig" or obj.kind == "ClusterProviderConfig") and obj.status.users ~= nil then
            health_status.status = "Healthy"
            health_status.message = "Resource is in use."
            return health_status
          end
          return health_status
        end

        for i, condition in ipairs(obj.status.conditions) do
          if condition.type == "LastAsyncOperation" then
            if condition.status == "False" then
              health_status.status = "Degraded"
              health_status.message = condition.message
              return health_status
            end
          end

          if condition.type == "Synced" then
            if condition.status == "False" then
              health_status.status = "Degraded"
              health_status.message = condition.message
              return health_status
            end
          end

          if condition.type == "Installed" then
            if condition.status == "False" then
              health_status.status = "Degraded"
              health_status.message = condition.message
              return health_status
            end
          end

          if contains({"Ready", "Healthy", "Offered", "Established", "ValidPipeline", "RevisionHealthy"}, condition.type) then
            if condition.status == "True" or (condition.type == "Established" and condition.reason == "InactiveManagedResource") then
              health_status.status = "Healthy"
              health_status.message = "Resource is up-to-date."
            end
          end
        end

        return health_status

리소스 제외 설정

Crossplane provider는 관리하는 각 관리 리소스(MR)에 대해 ProviderConfigUsage를 생성합니다. 이 리소스는 MR과 ProviderConfig 사이의 관계를 나타내어, 사용자가 ProviderConfig를 삭제할 때 컨트롤러가 finalizer로 사용할 수 있게 합니다. Crossplane의 최종 사용자는 이 리소스와 상호 작용할 필요가 없습니다.

리소스와 유형이 증가하면 Argo CD UI 반응성에 영향을 줄 수 있습니다. 이 수를 낮게 유지하기 위해 Crossplane은 모든 ProviderConfigUsage 리소스를 Argo CD UI에서 숨기는 것을 권장합니다. argocd Namespace의 argocd-cm ConfigMap을 편집해 리소스 제외를 구성하세요.

apiVersion: v1
kind: ConfigMap
data:
    resource.exclusions: |
      - apiGroups:
        - "*"
        kinds:
        - ProviderConfigUsage

apiGroups로 "*"를 사용하면 모든 Crossplane Provider에 대해 메커니즘이 활성화됩니다.

Kubernetes 클라이언트 QPS 증가

컨트롤 플레인에서 CRD 수가 증가하면 Argo CD Application Controller가 Kubernetes API에 보내야 하는 쿼리 수가 늘어납니다. 이런 경우 Argo CD Kubernetes 클라이언트의 rate limit을 늘릴 수 있습니다. 여러 CRD와의 호환성을 개선하려면 환경 변수 ARGOCD_K8S_CLIENT_QPS를 300으로 설정하세요. ARGOCD_K8S_CLIENT_QPS의 기본값은 50이며, 값을 수정하면 ARGOCD_K8S_CLIENT_BURST(기본적으로 ARGOCD_K8S_CLIENT_QPS x 2)도 업데이트됩니다.

더 알아보기 (Learn more)