본문으로 건너뛰기
Kreath Archive
TechProjectsBooksAbout
TechProjectsBooksAbout
TechProjectsBooksAbout
© 2026 Kreath. All rights reserved.
홈TechProjectsBooksAbout
//
  1. 홈
  2. 테크
  3. 8장: Crossplane - 인프라를 코드로 관리하기
2026년 5월 30일·인프라·

8장: Crossplane - 인프라를 코드로 관리하기

Crossplane의 아키텍처, Provider와 Managed Resource, XRD와 Composition을 활용한 인프라 추상화, GitOps 통합, Terraform과의 비교를 다룹니다.

12분777자7개 섹션
kubernetesci-cdinfrastructureautomationobservability
공유
kubernetes-gitops8 / 10
12345678910
이전7장: 비용 최적화와 리소스 관리다음9장: 보안 강화와 정책 관리

7장까지 Kubernetes 내부의 워크로드와 노드 관리를 다루었습니다. 하지만 실제 서비스 운영에서는 Kubernetes 외부의 클라우드 인프라도 관리해야 합니다. RDS 데이터베이스, S3 버킷, VPC 네트워크, IAM 역할 등을 누가, 어떻게 프로비저닝하고 관리할 것인가의 문제입니다. 이번 장에서는 이 문제를 Kubernetes 네이티브 방식으로 해결하는 Crossplane을 다루겠습니다.

Crossplane이란

Crossplane은 Kubernetes API를 확장하여 클라우드 인프라를 선언적으로 관리하는 CNCF 프로젝트입니다. 5장에서 배운 컨트롤러 패턴과 CRD를 활용하여, Kubernetes의 kubectl apply만으로 AWS RDS, GCP Cloud SQL, Azure Database 같은 클라우드 리소스를 프로비저닝할 수 있습니다.

핵심 철학

기존 방식:
  개발자 → "DB 필요" → 인프라 팀 티켓 → Terraform 실행 → 며칠 후 제공

Crossplane 방식:
  개발자 → kubectl apply database.yaml → 수 분 내 프로비저닝

Crossplane의 핵심 가치는 인프라 셀프서비스입니다. 플랫폼 팀이 안전한 추상화 계층을 제공하고, 개발팀이 직접 필요한 인프라를 프로비저닝하는 모델을 가능하게 합니다.

아키텍처

핵심 개념

Provider: 클라우드 API와 통신하는 컨트롤러입니다. AWS, GCP, Azure 등 각 클라우드에 대한 Provider가 존재합니다.

Managed Resource (MR): 클라우드 리소스 하나에 대응하는 CRD입니다. 예를 들어 RDSInstance는 AWS RDS 인스턴스에 대응합니다.

Composite Resource Definition (XRD): 여러 Managed Resource를 묶어 새로운 추상화를 정의하는 스키마입니다.

Composition: XRD에 정의된 추상화를 실제 Managed Resource로 매핑하는 규칙입니다.

Claim (XRC): 개발자가 사용하는 네임스페이스 스코프의 리소스 요청입니다.

Provider와 Managed Resource

Provider 설치

provider-aws.yaml
yaml
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-aws-rds
spec:
  package: xpkg.upbound.io/upbound/provider-aws-rds:v1.14.0
  runtimeConfigRef:
    name: default
---
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-aws-s3
spec:
  package: xpkg.upbound.io/upbound/provider-aws-s3:v1.14.0

Provider 인증 설정

provider-config.yaml
yaml
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: IRSA  # EKS IRSA (IAM Roles for Service Accounts)
Warning

Crossplane Provider에 부여되는 IAM 권한은 최소 권한 원칙을 반드시 따라야 합니다. Provider가 생성/관리할 리소스에 대한 권한만 부여하십시오. 예를 들어 RDS Provider에는 RDS 관련 권한만, S3 Provider에는 S3 관련 권한만 부여합니다.

Managed Resource 사용

rds-instance.yaml
yaml
apiVersion: rds.aws.upbound.io/v1beta2
kind: Instance
metadata:
  name: production-postgres
spec:
  forProvider:
    region: ap-northeast-2
    instanceClass: db.r6g.large
    engine: postgres
    engineVersion: "16.3"
    allocatedStorage: 100
    storageType: gp3
    storageEncrypted: true
    multiAz: true
    dbName: appdb
    masterUsername: admin
    masterPasswordSecretRef:
      name: rds-master-password
      namespace: crossplane-system
      key: password
    vpcSecurityGroupIdRefs:
      - name: rds-security-group
    dbSubnetGroupNameRef:
      name: rds-subnet-group
    backupRetentionPeriod: 7
    deletionProtection: true
    tags:
      managed-by: crossplane
      environment: production
  providerConfigRef:
    name: default
  writeConnectionSecretToRef:
    name: rds-connection
    namespace: production

위 YAML을 kubectl apply하면 Crossplane의 AWS Provider가 실제 RDS 인스턴스를 프로비저닝하고, 접속 정보를 Kubernetes Secret으로 자동 생성합니다.

XRD와 Composition

Managed Resource를 직접 사용하면 클라우드 세부사항이 노출됩니다. XRD와 Composition을 활용하면 개발자에게 단순한 인터페이스를 제공하면서, 플랫폼 팀이 내부 구현을 제어할 수 있습니다.

XRD 정의

xrd-database.yaml
yaml
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: xdatabases.platform.example.com
spec:
  group: platform.example.com
  names:
    kind: XDatabase
    plural: xdatabases
  claimNames:
    kind: Database
    plural: databases
  versions:
    - name: v1alpha1
      served: true
      referenceable: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              required: [size, engine]
              properties:
                size:
                  type: string
                  enum: [small, medium, large]
                  description: "데이터베이스 크기"
                engine:
                  type: string
                  enum: [postgres, mysql]
                  description: "데이터베이스 엔진"
                version:
                  type: string
                  default: "16.3"
                  description: "엔진 버전"
                highAvailability:
                  type: boolean
                  default: false
                  description: "Multi-AZ 활성화"
            status:
              type: object
              properties:
                endpoint:
                  type: string
                port:
                  type: integer
                status:
                  type: string

Composition 정의

composition-database.yaml
yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: database-aws
  labels:
    provider: aws
    crossplane.io/xrd: xdatabases.platform.example.com
spec:
  compositeTypeRef:
    apiVersion: platform.example.com/v1alpha1
    kind: XDatabase
  resources:
    - name: rds-instance
      base:
        apiVersion: rds.aws.upbound.io/v1beta2
        kind: Instance
        spec:
          forProvider:
            region: ap-northeast-2
            storageType: gp3
            storageEncrypted: true
            backupRetentionPeriod: 7
            deletionProtection: true
          providerConfigRef:
            name: default
      patches:
        # size → instanceClass 매핑
        - type: FromCompositeFieldPath
          fromFieldPath: spec.size
          toFieldPath: spec.forProvider.instanceClass
          transforms:
            - type: map
              map:
                small: db.t4g.medium
                medium: db.r6g.large
                large: db.r6g.xlarge
        # size → allocatedStorage 매핑
        - type: FromCompositeFieldPath
          fromFieldPath: spec.size
          toFieldPath: spec.forProvider.allocatedStorage
          transforms:
            - type: map
              map:
                small: "50"
                medium: "100"
                large: "500"
            - type: convert
              convert:
                toType: int64
        # engine 매핑
        - type: FromCompositeFieldPath
          fromFieldPath: spec.engine
          toFieldPath: spec.forProvider.engine
        # version 매핑
        - type: FromCompositeFieldPath
          fromFieldPath: spec.version
          toFieldPath: spec.forProvider.engineVersion
        # HA 매핑
        - type: FromCompositeFieldPath
          fromFieldPath: spec.highAvailability
          toFieldPath: spec.forProvider.multiAz
        # 상태 역전파
        - type: ToCompositeFieldPath
          fromFieldPath: status.atProvider.endpoint
          toFieldPath: status.endpoint
      connectionDetails:
        - name: host
          fromFieldPath: status.atProvider.endpoint
        - name: port
          fromFieldPath: status.atProvider.port
          type: FromFieldPath
        - name: username
          fromFieldPath: spec.forProvider.masterUsername
          type: FromFieldPath
 
    - name: security-group
      base:
        apiVersion: ec2.aws.upbound.io/v1beta1
        kind: SecurityGroup
        spec:
          forProvider:
            region: ap-northeast-2
            description: "Database security group managed by Crossplane"
            vpcIdRef:
              name: main-vpc
      patches:
        - type: FromCompositeFieldPath
          fromFieldPath: metadata.name
          toFieldPath: spec.forProvider.name
          transforms:
            - type: string
              string:
                fmt: "%s-db-sg"

Claim (개발자 인터페이스)

개발자는 복잡한 AWS 세부사항 없이 단순한 Claim만 작성합니다.

database-claim.yaml
yaml
apiVersion: platform.example.com/v1alpha1
kind: Database
metadata:
  name: payment-db
  namespace: payment
spec:
  size: medium
  engine: postgres
  version: "16.3"
  highAvailability: true
Info

이 단순한 Claim 하나로 RDS 인스턴스, 보안 그룹, 서브넷 그룹이 자동으로 생성되고, 접속 정보가 Kubernetes Secret으로 주입됩니다. 개발자는 AWS 콘솔에 접근하지 않고도 필요한 데이터베이스를 확보할 수 있습니다.

GitOps 통합

Crossplane 리소스는 모두 Kubernetes CRD이므로 ArgoCD나 Flux로 자연스럽게 관리됩니다.

infrastructure/
  crossplane/
    providers/
      provider-aws-rds.yaml
      provider-aws-s3.yaml
      provider-aws-ec2.yaml
      provider-config.yaml
    platform-api/
      xrd-database.yaml
      composition-database-aws.yaml
      xrd-cache.yaml
      composition-cache-aws.yaml
  claims/
    production/
      payment-db.yaml
      session-cache.yaml
    staging/
      payment-db.yaml
      session-cache.yaml
argocd-crossplane-app.yaml
yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: crossplane-platform
  namespace: argocd
spec:
  project: infrastructure
  source:
    repoURL: https://github.com/org/infra-manifests.git
    targetRevision: main
    path: infrastructure/crossplane
  destination:
    server: https://kubernetes.default.svc
    namespace: crossplane-system
  syncPolicy:
    automated:
      prune: false  # 인프라 리소스는 자동 삭제 비활성화
      selfHeal: true
Warning

인프라 리소스를 관리하는 ArgoCD Application에서는 prune: false를 설정하는 것을 강력히 권장합니다. Git에서 실수로 파일을 삭제했을 때 실제 클라우드 리소스(데이터베이스, 네트워크 등)가 함께 삭제되는 사고를 방지합니다.

Terraform과의 비교

Crossplane과 Terraform은 모두 인프라를 코드로 관리하지만, 근본적인 접근 방식이 다릅니다.

기준CrossplaneTerraform
실행 모델지속적 조정 (컨트롤러)일회성 실행 (apply)
상태 관리Kubernetes etcdtfstate 파일
드리프트 감지자동 (실시간)수동 (terraform plan)
APIKubernetes CRDHCL / Provider
추상화XRD + CompositionModule
셀프서비스Claim으로 자연스럽게 지원Terraform Cloud/Atlantis 필요
생태계성장 중 (AWS, GCP, Azure 주요 리소스)매우 성숙 (거의 모든 리소스)

어떤 것을 선택할까

Crossplane이 적합한 경우:

  • Kubernetes 중심의 운영 환경
  • 개발자 셀프서비스 플랫폼 구축
  • GitOps 파이프라인과의 자연스러운 통합
  • 실시간 드리프트 감지와 자동 복구가 필요한 경우

Terraform이 적합한 경우:

  • Kubernetes를 사용하지 않는 환경
  • 매우 다양한 클라우드 리소스를 관리하는 경우 (Provider 생태계 활용)
  • 기존 Terraform 코드베이스가 큰 경우
  • 팀이 HCL에 익숙한 경우
Tip

두 도구를 배타적으로 선택할 필요는 없습니다. 네트워크, DNS 같은 기반 인프라는 Terraform으로 관리하고, 애플리케이션 수준의 인프라(데이터베이스, 캐시, 큐)는 Crossplane으로 관리하는 하이브리드 전략이 실무에서 효과적입니다.

정리

Crossplane은 Kubernetes API를 통해 클라우드 인프라를 선언적으로 관리하는 강력한 도구입니다. XRD와 Composition을 활용한 추상화 계층은 플랫폼 엔지니어링의 핵심 패턴이며, GitOps와의 자연스러운 통합은 인프라 관리의 일관성을 크게 향상시킵니다. 5장에서 배운 컨트롤러 패턴이 인프라 관리 영역까지 확장된 것으로 이해할 수 있습니다.

다음 장에서는 Kubernetes 운영의 또 다른 중요한 축인 보안 강화와 정책 관리를 살펴보겠습니다. OPA/Gatekeeper, Kyverno, 시크릿 관리, 이미지 서명 등 프로덕션 환경에 필수적인 보안 요소를 다룹니다.

이 글이 도움이 되셨나요?

관련 글

인프라

7장: 비용 최적화와 리소스 관리

Kubernetes 리소스 requests/limits 모범 사례, VPA/HPA 전략, Goldilocks, Kubecost/OpenCost, 스팟 인스턴스, 네임스페이스 쿼터, FinOps 실천법을 다룹니다.

2026년 5월 27일·14분
인프라

9장: 보안 강화와 정책 관리

OPA/Gatekeeper, Kyverno, Pod Security Standards, RBAC 모범 사례, External Secrets Operator, 공급망 보안(SLSA, Sigstore), 이미지 서명을 다룹니다.

2026년 6월 3일·11분
인프라

6장: Karpenter - 차세대 노드 오토스케일링

Karpenter의 아키텍처, Cluster Autoscaler와의 비교, NodePool/EC2NodeClass CRD, 통합과 중단 관리, 스팟 인스턴스 전략, GPU 노드 프로비저닝을 다룹니다.

2026년 5월 25일·11분
이전 글7장: 비용 최적화와 리소스 관리
다음 글9장: 보안 강화와 정책 관리

댓글

목차

약 12분 남음
  • Crossplane이란
    • 핵심 철학
  • 아키텍처
    • 핵심 개념
  • Provider와 Managed Resource
    • Provider 설치
    • Provider 인증 설정
    • Managed Resource 사용
  • XRD와 Composition
    • XRD 정의
    • Composition 정의
    • Claim (개발자 인터페이스)
  • GitOps 통합
  • Terraform과의 비교
    • 어떤 것을 선택할까
  • 정리