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는 운영 워크플로를 위한 강력한 구성 요소입니다. 더 알아보세요.
- Operation 개념 - 핵심 Operation 기능과 베스트 프랙틱스
- CronOperation - 자동으로 실행되도록 작업 예약하기
- WatchOperation - 리소스가 변경될 때 작업 트리거하기
고급 기능과 예제는 전체 Operations 문서를 탐색해 보세요.
더 알아보기 (Learn more)
- Operation - 일회성 운영 작업 상세
- CronOperation - 예약된 Operations