Operation
Operation (일회성 운영 작업)
이 기능은 v2에서 도입되었습니다. 자세한 내용은 Crossplane 기능 생명주기 문서를 참고하세요.
출처: 문서
본문
Operation은 함수 파이프라인을 한 번 끝까지 실행해서, 일반적인 리소스 생성 패턴에는 맞지 않는 운영 작업을 수행합니다. 원하는 상태를 계속해서 조정(reconcile)하는 composition과 달리, Operations는 백업, 롤링 업그레이드, 설정 검증, 예약 유지보수 같은 작업에 집중합니다.
Operations는 어떻게 동작하나요? (How operations work)
Operations는 Kubernetes Jobs와 같아서 계속 조정하는 대신 한 번 실행되고 완료됩니다. composition처럼 함수 파이프라인을 사용해 로직을 구현하지만, 리소스 합성 대신 운영 워크플로를 위해 설계되었어요.
apiVersion: ops.crossplane.io/v1alpha1
kind: Operation
metadata:
name: backup-database
spec:
mode: Pipeline
pipeline:
- step: create-backup
functionRef:
name: function-database-backup
input:
apiVersion: fn.crossplane.io/v1beta1
kind: DatabaseBackupInput
database: production-db
retentionDays: 30
이 Operation을 생성하면 Crossplane은 다음을 수행합니다.
- Operation과 그 함수 의존성을 검증합니다.
- 함수 파이프라인을 단계별로 실행합니다.
- 함수가 생성하거나 변경한 리소스를 적용합니다.
- 결과와 완료 상태로 Operation 상태를 업데이트합니다.
⚠️ 중요: Operations는 alpha 기능입니다. Crossplane 인자에
--enable-operations를 추가해서 반드시 활성화해야 해요.
주요 특징 (Key characteristics)
- 완료까지 한 번 실행됩니다 (Kubernetes Jobs처럼).
- 함수 파이프라인을 사용합니다 (Compositions처럼).
- 모든 Kubernetes 리소스를 생성하거나 변경할 수 있습니다.
- 각 단계의 상세 상태와 출력을 제공합니다.
- 실패 시 제한 가능한 재시도를 지원합니다.
Operation 함수 vs composition 함수 (Operation functions vs composition functions)
Operations와 compositions는 모두 함수 파이프라인을 쓰지만 중요한 차이가 있습니다.
Composition Functions:
- 목적: 리소스 생성 및 유지
- 생명주기: 지속적 조정 (continuous reconciliation)
- 입력: 관찰된 복합 리소스
- 출력: 원하는 구성 리소스
- 소유권: owner reference 생성
Operation Functions:
- 목적: 운영 작업 수행
- 생명주기: 한 번 실행 후 완료
- 입력: 필요한 리소스만
- 출력: 모든 Kubernetes 리소스
- 소유권: 소유자 없이 강제 적용 (force apply)
함수는 패키지 메타데이터에 적절한 능력(capabilities)을 선언해서 두 모드를 모두 지원할 수 있어요. 함수 작성자는 함수 패키지를 만들 때 crossplane.yaml 파일에 이렇게 선언합니다.
apiVersion: meta.pkg.crossplane.io/v1
kind: Function
metadata:
name: my-function
spec:
capabilities:
- composition
- operation
이렇게 하면 Crossplane이 함수가 지원하는 모드를 알고, composition 전용 함수를 operations에 사용하려는 실수를 피할 수 있어요.
일반적인 사용 사례 (Common use cases)
📝 참고: 아래 예제는 설명을 위한 가상의 함수를 사용합니다. 출시 시점에는
function-python만 operations를 지원해요.
롤링 업그레이드 (Rolling upgrades)
통제된 롤링 업그레이드에 Operations를 사용하세요.
apiVersion: ops.crossplane.io/v1alpha1
kind: Operation
metadata:
name: cluster-upgrade
spec:
mode: Pipeline
pipeline:
- step: rolling-upgrade
functionRef:
name: function-cluster-upgrade
input:
apiVersion: fn.crossplane.io/v1beta1
kind: ClusterUpgradeInput
targetVersion: "1.28"
batches: [0.25, 0.5, 1.0] # 25%, 50%, then 100%
healthChecks: [Synced, Ready]
일회성 유지보수 (One-time maintenance)
특정 유지보수 작업에 Operations를 사용하세요.
apiVersion: ops.crossplane.io/v1alpha1
kind: Operation
metadata:
name: certificate-rotation
spec:
mode: Pipeline
pipeline:
- step: rotate-certificates
functionRef:
name: function-cert-rotation
input:
apiVersion: fn.crossplane.io/v1beta1
kind: CertRotationInput
targetCertificates:
matchLabels:
rotate: "true"
고급 구성 (Advanced configuration)
재시도 동작 (Retry behavior)
Operations는 실패 시 자동으로 재시도합니다. 시도 횟수를 제어하려면 재시도 한계를 구성하세요.
apiVersion: ops.crossplane.io/v1alpha1
kind: Operation
metadata:
name: resilient-operation
spec:
retryLimit: 10 # Try up to 10 times before giving up (default: 5)
mode: Pipeline
pipeline:
- step: flaky-task
functionRef:
name: function-flaky-task
input:
apiVersion: fn.crossplane.io/v1beta1
kind: FlakyTaskInput
# Task that might fail due to temporary issues
timeout: "30s"
재시도 동작:
- 각 재시도는 전체 파이프라인을 초기화합니다. 3단계 중 2단계가 실패하면 재시도는 1단계부터 시작해요.
- Operations는 지수 백오프(exponential backoff)를 사용합니다. 1초, 2초, 4초, 8초, 16초, 32초, 그리고 최대 60초.
- Operations는
status.failures에 실패 횟수를 기록합니다. retryLimit에 도달하면 Operation은Succeeded=False가 됩니다.
자격 증명 (Credentials)
Operations는 Secrets를 통해 함수에 자격 증명을 제공할 수 있어요.
apiVersion: ops.crossplane.io/v1alpha1
kind: Operation
metadata:
name: secure-backup
spec:
mode: Pipeline
pipeline:
- step: backup-with-credentials
functionRef:
name: function-backup
credentials:
- name: backup-creds
source: Secret
secretRef:
namespace: crossplane-system
name: backup-credentials
key: api-key
- name: database-creds
source: Secret
secretRef:
namespace: crossplane-system
name: database-credentials
key: connection-string
input:
apiVersion: fn.crossplane.io/v1beta1
kind: BackupInput
destination: s3://my-backup-bucket
여러 파이프라인 단계 (Multiple pipeline steps)
복잡한 작업은 여러 파이프라인 단계를 사용할 수 있어요.
apiVersion: ops.crossplane.io/v1alpha1
kind: Operation
metadata:
name: multi-step-deployment
spec:
mode: Pipeline
pipeline:
- step: validate-config
functionRef:
name: function-validator
input:
apiVersion: fn.crossplane.io/v1beta1
kind: ValidatorInput
configName: app-config
- step: backup-current
functionRef:
name: function-backup
input:
apiVersion: fn.crossplane.io/v1beta1
kind: BackupInput
target: current-deployment
- step: deploy-new-version
functionRef:
name: function-deploy
input:
apiVersion: fn.crossplane.io/v1beta1
kind: DeployInput
image: myapp:v2.0.0
strategy: rollingUpdate
- step: verify-health
functionRef:
name: function-health-check
input:
apiVersion: fn.crossplane.io/v1beta1
kind: HealthCheckInput
timeout: 300s
healthEndpoint: /health
RBAC 권한 (RBAC permissions)
Operation이 Crossplane이 기본적으로 권한을 갖지 않는 리소스에 접근해야 한다면, Crossplane에 집계(aggregate)되는 ClusterRole을 만드세요.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: operation-additional-permissions
labels:
rbac.crossplane.io/aggregate-to-crossplane: "true"
rules:
# Additional permissions for Operations
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "list", "patch", "update"]
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list"]
# Add other resources your Operations need to access
이 ClusterRole은 Crossplane의 메인 ClusterRole에 자동으로 집계되어, Crossplane 서비스 계정이 Operation에 필요한 권한을 갖게 됩니다.
📝 참고: RBAC 매니저는 Crossplane 리소스(MR, XR 등)에 대한 Crossplane 접근을 자동으로 부여해요. 다른 Kubernetes 리소스에 대해서만 추가 ClusterRole을 만들면 됩니다.
RBAC 구성에 대한 자세한 내용은 Compositions RBAC 문서를 참고하세요.
함수 응답 캐시 (Function response cache)
📝 참고: 함수 응답 캐싱은 alpha 기능입니다.
--enable-function-response-cachefeature flag로 활성화할 수 있어요.
Operations는 이런 조건에 해당할 때 성능 향상을 위해 함수 응답 캐싱을 사용할 수 있습니다.
- 동일한 입력으로 같은 함수를 자주 호출할 때
- 비용이 큰 계산이나 외부 API 호출을 수행하는 함수를 사용할 때
- CronOperation이나 WatchOperation을 통해 자주 실행될 때
캐시는 Compositions와 동일한 방식으로 동작합니다. TTL(수명) 값을 가진 함수 응답이 만료될 때까지 캐시되어 동일한 요청을 재사용합니다.
함수 응답 캐싱은 이런 Operations에 도움이 됩니다.
- 비용이 큰 검사를 사용해 구성을 검증할 때
- 상태 정보를 위해 외부 시스템을 조회할 때
- 자주 바뀌지 않는 복잡한 계산을 수행할 때
캐시 구성에 대한 자세한 내용은 Function response cache 문서를 참고하세요.
필요 리소스 (Required resources)
Operations는 함수가 접근할 리소스를 미리 로드할 수 있어요.
apiVersion: ops.crossplane.io/v1alpha1
kind: Operation
metadata:
name: resource-aware-operation
spec:
mode: Pipeline
pipeline:
- step: process-deployment
functionRef:
name: function-processor
requirements:
requiredResources:
- requirementName: app-deployment
apiVersion: apps/v1
kind: Deployment
name: my-app
namespace: production
- requirementName: app-service
apiVersion: v1
kind: Service
name: my-app-service
namespace: production
input:
apiVersion: fn.crossplane.io/v1beta1
kind: ProcessorInput
action: upgrade
함수는 표준 요청 구조를 통해 이 리소스들에 접근합니다.
from crossplane.function import request, response
def operate(req, rsp):
# Access required resources
deployment = request.get_required_resource(req, "app-deployment")
service = request.get_required_resource(req, "app-service")
if not deployment or not service:
response.set_output(rsp, {"error": "Required resources not found"})
return
# Process the resources
new_replicas = deployment["spec"]["replicas"] * 2
# Return updated resources with full GVK and metadata for server-side apply
rsp.desired.resources["app-deployment"].resource.update({
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": deployment["metadata"]["name"],
"namespace": deployment["metadata"]["namespace"]
},
"spec": {"replicas": new_replicas}
})
상태와 모니터링 (Status and monitoring)
Operations는 풍부한 상태 정보를 제공합니다.
status:
conditions:
- type: Synced
status: "True"
reason: ReconcileSuccess
- type: Succeeded
status: "True"
reason: PipelineSuccess
- type: ValidPipeline
status: "True"
reason: ValidPipeline
failures: 1 # Number of retry attempts
pipeline:
- step: create-backup
output:
backupId: "backup-20240115-103000"
size: "2.3GB"
appliedResourceRefs:
- apiVersion: "v1"
kind: "Secret"
namespace: "production"
name: "backup-secret"
- apiVersion: "apps/v1"
kind: "Deployment"
name: "updated-deployment"
주요 상태 필드:
conditions: 표준 Crossplane 조건(Synced)과 Operation 고유 조건.Succeeded: 작업이 성공적으로 완료되면 True, 실패하면 False.ValidPipeline: 모든 함수가 필요한 operation 능력을 가졌으면 True.failures: 작업이 실패하고 재시도한 횟수.pipeline: 진행 상황 추적을 위한 각 함수 단계의 출력.appliedResourceRefs: Operation이 생성하거나 수정한 모든 리소스에 대한 참조.
이벤트 (Events)
Operations는 중요한 활동에 대해 Kubernetes 이벤트를 발생시킵니다.
- 함수 실행 결과와 경고
- 리소스 적용 실패
- Operation 생명주기 이벤트 (생성, 완료, 실패)
Operations 트러블슈팅 (Troubleshooting operations)
Operation 상태를 확인하세요.
$ kubectl get operation my-operation -o wide
상세 정보를 확인하세요.
$ kubectl describe operation my-operation
일반적인 실패 시나리오:
- Operations가 아무것도 하지 않음 - Operations 기능이 활성화되지 않음:
# Operation exists but has no status conditions and never progresses
status: {}
해결 방법: Crossplane 시작 인자에 --enable-operations를 추가해서 Operations를 활성화하세요.
- ValidPipeline 조건이 False - 함수가 operations를 지원하지 않음:
conditions:
- type: ValidPipeline
status: "False"
reason: InvalidFunctionCapability
message: "Function function-name doesn't support operations"
해결 방법: operation 능력을 선언한 함수를 사용하세요.
- Succeeded 조건이 False - 함수 실행이 실패함:
conditions:
- type: Succeeded
status: "False"
reason: PipelineFailure
message: "Function returned error: connection timeout"
해결 방법: 함수 로그를 확인하고 근본 문제를 해결하세요.
- 리소스 적용 실패 - 상세 내용은 이벤트를 확인:
$ kubectl get events --field-selector involvedObject.name=my-operation
함수 실행을 디버깅하세요.
# View function logs
$ kubectl logs -n crossplane-system deployment/function-python
# Check operation events
$ kubectl get events --field-selector involvedObject.kind=Operation
# Inspect operation status in detail
$ kubectl get operation my-operation -o jsonpath='{.status.pipeline}' | jq '.'
리소스 관리 (Resource management)
Operations는 서버 사이드 애플라이(server-side apply)와 강제 소유권(force ownership)을 사용해 모든 Kubernetes 리소스를 생성하거나 변경할 수 있습니다. 즉:
Operations가 할 수 있는 것:
- 어떤 종류든 새 리소스를 생성
- 특정 필드의 소유권을 가져와 기존 리소스 변경
- 다른 컨트롤러와 충돌할 수 있는 변경 적용
Operations가 할 수 없는 것:
- 리소스 삭제 (alpha 구현의 현재 제한)
- owner reference 설정 (리소스가 가비지 컬렉션되지 않음)
- 원하는 상태를 지속적으로 유지 (한 번 실행됨)
⚠️ 중요: 다른 컨트롤러가 관리하는 리소스를 변경하는 Operations는 주의해서 사용하세요. Operations는 변경 적용 시 강제로 소유권을 가져가므로 충돌이 발생할 수 있어요.
Operation 테스트하기 (Test an operation)
Crossplane CLI를 사용하면 어떤 Operation의 출력이든 미리 볼 수 있어요. Crossplane 컨트롤 플레인이 없어도 됩니다. Crossplane CLI는 Docker Engine을 사용해 함수를 실행합니다.
💡 Tip: Crossplane CLI 설치 및 사용법은 Crossplane CLI 문서를 참고하세요.
⚠️ 중요: CLI는
crossplane operation render같은 alpha 명령을 기본적으로 숨겨요.crossplane config set features.enableAlpha true를 실행하면 보이게 할 수 있습니다.
⚠️ 중요:
crossplane operation render실행에는 Docker가 필요합니다.
operation, composition 함수, 그리고 필요한 리소스를 제공해서 출력을 로컬에서 렌더링하세요.
$ crossplane operation render operation.yaml functions.yaml --required-resources=ingress.yaml
crossplane operation render는 Operation 상태와 operation 함수가 생성하거나 수정한 리소스를 출력합니다. 이 명령은 Operation을 클러스터에 적용했을 때 어떤 일이 일어날지 보여줘요.
---
# Operation status showing function results
apiVersion: ops.crossplane.io/v1alpha1
kind: Operation
metadata:
name: ingress-cert-monitor
status:
conditions:
- type: Succeeded
status: "True"
reason: PipelineSuccess
pipeline:
- step: check-ingress-certificate
output:
certificateExpires: "Sep 29 08:34:02 2025 GMT"
daysUntilExpiry: 53
hostname: google.com
ingressName: example-app
status: ok
---
# Modified Ingress resource with certificate annotations
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-monitor.crossplane.io/expires: Sep 29 08:34:02 2025 GMT
cert-monitor.crossplane.io/days-until-expiry: "53"
cert-monitor.crossplane.io/status: ok
name: example-app
namespace: default
spec:
# ... ingress spec unchanged
--required-resources를 사용해 operation 함수가 접근해야 하는 리소스를 제공하세요. 여러 파일이나 글로브(glob) 패턴을 지정할 수 있어요.
# Multiple specific files
$ crossplane operation render operation.yaml functions.yaml \
--required-resources=deployment.yaml,service.yaml,configmap.yaml
# Glob pattern for all YAML files in a directory
$ crossplane operation render operation.yaml functions.yaml \
--required-resources="resources/*.yaml"
💡 Tip:
crossplane operation render명령으로 클러스터에 배포하기 전에 Operations를 로컬에서 테스트해 보세요. 이 명령은 함수 로직과 필요 리소스 접근 패턴의 검증에 도움이 됩니다.
베스트 프랙티스 (Best practices)
Operation 고유 프랙티스
- 롤백 계획: 가능하면 Operation을 되돌릴 수 있게 설계하세요. Operations는 Compositions처럼 자동 롤백하지 않기 때문이에요.
- Operation을 멱등(idempotent)하게 만들기: 중간에 실패해도 재시도가 안전해야 합니다.
- 필요 리소스 사용: 실행 중에 요청하는 대신 필요한 리소스를 미리 함수에 넣어 효율성을 높이세요.
함수 개발
- 능력 선언: Operations 지원을 위해 함수 메타데이터에 operation 능력을 명시적으로 선언하세요.
- 의미 있는 출력 반환: 모니터링과 디버깅을 위해 operation이 수행한 작업을 추적하는 데
output필드를 사용하세요.
다음 단계 (Next steps)
- Operations 시작하기 - 첫 Operation 만들기
- CronOperation - 예약된 Operations 알아보기
- WatchOperation - 반응형 Operations 알아보기
더 알아보기 (Learn more)
- CronOperation - cron 일정으로 작업 예약하기
- WatchOperation - 리소스 변경에 반응하는 작업 만들기