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

Operations로 시작하기

원문 보기 위키 갱신

Operations로 시작하기 (Get Started with Operations)

이 기능은 v2에서 도입되었습니다. 자세한 내용은 Crossplane 기능 생명주기 문서를 참고하세요.

출처: 문서

본문

이 가이드는 Crossplane Operations를 사용해 day-two 운영 작업을 자동화하는 방법을 보여줍니다. 웹사이트의 SSL 인증서 만료를 확인하는 Operation을 만듭니다.

Crossplane은 이것을 Operations라고 부릅니다. Operations는 인증서 모니터링, 롤링 업그레이드, 예약 유지보수처럼 일반적인 리소스 생성 패턴에 맞지 않는 작업을 수행하기 위해 함수 파이프라인을 실행합니다.

Operation은 이렇게 생겼습니다.

apiVersion: ops.crossplane.io/v1alpha1
kind: Operation
metadata:
  name: check-cert-expiry
spec:
  mode: Pipeline
  pipeline:
  - step: check-certificate
    functionRef:
      name: crossplane-contrib-function-python
    input:
      apiVersion: python.fn.crossplane.io/v1beta1
      kind: Script
      script: |
        import ssl
        import socket
        from datetime import datetime

        from crossplane.function import request, response

        def operate(req, rsp):
            hostname = "google.com"
            port = 443

            # Get SSL certificate info
            context = ssl.create_default_context()
            with socket.create_connection((hostname, port)) as sock:
                with context.wrap_socket(sock, server_hostname=hostname) as ssock:
                    cert = ssock.getpeercert()

            # Parse expiration date
            expiry_date = datetime.strptime(cert['notAfter'], '%b %d %H:%M:%S %Y %Z')
            days_until_expiry = (expiry_date - datetime.now()).days

            # Return results in operation output
            response.set_output(rsp, {
                "hostname": hostname,
                "certificateExpires": cert['notAfter'],
                "daysUntilExpiry": days_until_expiry,
                "status": "warning" if days_until_expiry < 30 else "ok"
            })

Operation은 Kubernetes Job처럼 한 번 완료까지 실행됩니다. Operation을 만들면 Crossplane이 함수 파이프라인을 실행합니다. 함수는 google.com의 SSL 인증서 만료를 확인하고 결과를 operation의 출력에 반환합니다.

이 기본 예제는 개념을 보여줍니다. 아래 워크스루에서는 Kubernetes Ingress 리소스를 읽고 모니터링 도구용 인증서 만료 정보로 어노테이션을 추가하는 더 현실적인 Operation을 만듭니다.

사전 요구 사항 (Prerequisites)

이 가이드에는 다음이 필요합니다.

  • 최소 2 GB RAM 이상의 Kubernetes 클러스터
  • Operations가 활성화된 Kubernetes 클러스터에 설치된 Crossplane v2 프리뷰

💡 Tip: Crossplane 시작 인자에 --enable-operations를 추가해 Operations를 활성화하세요. Helm을 사용하는 경우:

$ helm upgrade --install crossplane crossplane-stable/crossplane \
  --namespace crossplane-system \
  --set args='{"--enable-operations"}'

Operation 만들기 (Create an operation)

첫 번째 Operation을 만드는 단계는 다음과 같습니다.

  • 인증서 확인용 샘플 Ingress 생성
  • operation에 사용할 함수 설치
  • Ingress를 확인하는 Operation 생성
  • Operation이 실행되는 동안 확인

샘플 Ingress 생성하기

실제 호스트 이름을 참조하지만 실제 트래픽은 라우팅하지 않는 Ingress를 만드세요.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-app
  namespace: default
spec:
  rules:
  - host: google.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nonexistent-service
            port:
              number: 80
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/operations/ingress.yaml

Ingress 권한 부여하기

Operations는 Ingresses에 접근하고 변경할 권한이 필요합니다. Crossplane에 Ingresses 접근 권한을 부여하는 ClusterRole을 만드세요.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: operations-ingress-access
  labels:
    rbac.crossplane.io/aggregate-to-crossplane: "true"
rules:
- apiGroups: ["networking.k8s.io"]
  resources: ["ingresses"]
  verbs: ["get", "list", "watch", "patch", "update"]
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/operations/ingress-rbac.yaml

함수 설치하기

Operations는 operation 함수를 사용해 로직을 구현합니다. composition과 operations를 모두 지원하는 Python 함수를 사용하세요. Python 지원을 설치하려면 이 함수를 만드세요.

apiVersion: pkg.crossplane.io/v1
kind: Function
metadata:
  name: crossplane-contrib-function-python
spec:
  package: xpkg.crossplane.io/crossplane-contrib/function-python:v0.2.0
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/operations/function.yaml

Crossplane이 함수를 설치했는지 확인하세요.

$ kubectl get -f https://docs.crossplane.io/latest/manifests/get-started/operations/function.yaml
NAME                                 INSTALLED   HEALTHY   PACKAGE                                                        AGE
crossplane-contrib-function-python   True        True      xpkg.crossplane.io/crossplane-contrib/function-python:v0.2.0   12s

Operation 만들기

Ingress 인증서를 모니터링하는 이 Operation을 만드세요.

apiVersion: ops.crossplane.io/v1alpha1
kind: Operation
metadata:
  name: ingress-cert-monitor
spec:
  mode: Pipeline
  pipeline:
  - step: check-ingress-certificate
    functionRef:
      name: crossplane-contrib-function-python
    requirements:
      requiredResources:
      - requirementName: ingress
        apiVersion: networking.k8s.io/v1
        kind: Ingress
        name: example-app
        namespace: default
    input:
      apiVersion: python.fn.crossplane.io/v1beta1
      kind: Script
      script: |
        import ssl
        import socket
        from datetime import datetime

        from crossplane.function import request, response

        def operate(req, rsp):
            # Get the Ingress resource
            ingress = request.get_required_resource(req, "ingress")
            if not ingress:
                response.set_output(rsp, {"error": "No ingress resource found"})
                return

            # Extract hostname from Ingress rules
            hostname = ingress["spec"]["rules"][0]["host"]
            port = 443

            # Get SSL certificate info
            context = ssl.create_default_context()
            with socket.create_connection((hostname, port)) as sock:
                with context.wrap_socket(sock, server_hostname=hostname) as ssock:
                    cert = ssock.getpeercert()

            # Parse expiration date
            expiry_date = datetime.strptime(cert['notAfter'], '%b %d %H:%M:%S %Y %Z')
            days_until_expiry = (expiry_date - datetime.now()).days

            # Add warning if certificate expires soon
            if days_until_expiry < 30:
                response.warning(rsp, f"Certificate for {hostname} expires in {days_until_expiry} days")

            # Annotate the Ingress with certificate expiry info
            rsp.desired.resources["ingress"].resource.update({
                "apiVersion": "networking.k8s.io/v1",
                "kind": "Ingress",
                "metadata": {
                    "name": ingress["metadata"]["name"],
                    "namespace": ingress["metadata"]["namespace"],
                    "annotations": {
                        "cert-monitor.crossplane.io/expires": cert['notAfter'],
                        "cert-monitor.crossplane.io/days-until-expiry": str(days_until_expiry),
                        "cert-monitor.crossplane.io/status": "warning" if days_until_expiry < 30 else "ok"
                    }
                }
            })

            # Return results in operation output for monitoring
            response.set_output(rsp, {
                "ingressName": ingress["metadata"]["name"],
                "hostname": hostname,
                "certificateExpires": cert['notAfter'],
                "daysUntilExpiry": days_until_expiry,
                "status": "warning" if days_until_expiry < 30 else "ok"
            })
$ kubectl apply -f https://docs.crossplane.io/latest/manifests/get-started/operations/operation.yaml

Operation 확인하기

Operation이 성공적으로 실행되는지 확인하세요.

$ kubectl get -f https://docs.crossplane.io/latest/manifests/get-started/operations/operation.yaml
NAME                   SYNCED   SUCCEEDED   AGE
ingress-cert-monitor   True     True        15s

💡 Tip: Operations는 성공적으로 완료되면 SUCCEEDED=True를 표시합니다.

Operation의 상세 상태를 확인하세요.

$ kubectl describe operation ingress-cert-monitor
# ... metadata ...
Status:
  Conditions:
    Last Transition Time:  2024-01-15T10:30:15Z
    Reason:                PipelineSuccess
    Status:                True
    Type:                  Succeeded
    Last Transition Time:  2024-01-15T10:30:15Z
    Reason:                ValidPipeline
    Status:                True
    Type:                  ValidPipeline
  Pipeline:
    Output:
      Certificate Expires:   Sep 29 08:34:02 2025 GMT
      Days Until Expiry:     54
      Hostname:              google.com
      Ingress Name:          example-app
      Status:                ok
    Step:                    check-ingress-certificate

💡 Tip: status.pipeline 필드는 각 함수 단계가 반환한 출력을 보여줍니다. 이 필드를 사용해 operation이 수행한 작업을 추적하세요.

Operation이 Ingress에 인증서 정보를 어노테이션으로 추가했는지 확인하세요.

$ kubectl get ingress example-app -o yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-monitor.crossplane.io/days-until-expiry: "54"
    cert-monitor.crossplane.io/expires: Sep 29 08:34:02 2025 GMT
    cert-monitor.crossplane.io/status: ok
  name: example-app
  namespace: default
spec:
  # ... ingress spec ...

💡 Tip: 이 패턴은 Operations가 기존 Kubernetes 리소스를 읽고 변경하는 방법을 모두 보여줍니다. Operation은 다른 도구가 모니터링과 알림에 사용할 수 있는 인증서 만료 정보로 Ingress에 어노테이션을 추가했어요.

정리하기 (Clean up)

생성한 리소스를 삭제하세요.

$ kubectl delete -f https://docs.crossplane.io/latest/manifests/get-started/operations/operation.yaml
$ kubectl delete -f https://docs.crossplane.io/latest/manifests/get-started/operations/ingress.yaml
$ kubectl delete -f https://docs.crossplane.io/latest/manifests/get-started/operations/ingress-rbac.yaml
$ kubectl delete -f https://docs.crossplane.io/latest/manifests/get-started/operations/function.yaml

다음 단계 (Next steps)

Operations는 운영 워크플로를 위한 강력한 구성 요소입니다. 더 알아보세요.

고급 기능과 예제는 전체 Operations 문서를 탐색해 보세요.

더 알아보기 (Learn more)