OpenShift Serverless Adoption Guide
Executive Summary
ๅฎขๆท็ฎๅๅจ AWS ไธ่ฟ่กๅคง้ Lambda ๅฝๆฐ๏ผๆฏไธชไบๅๅ้ฝ้่ฆๅ็ฌ็ CI/CD ๆต็จใ่ฟๅธฆๆฅไบๅทจๅคง็่ฟ็ปดๅผ้ๅๅๅ้ๅฎ้ฃ้ฉใ้่ฟ้็จ Red Hat OpenShift Serverless๏ผๅบไบ Knative๏ผ๏ผๅฎขๆทๅฏไปฅๅฐๆๆ serverless ๅทฅไฝ่ด่ฝฝ็ปไธๅฐไธไธชๅนณๅฐ๏ผไฝฟ็จไธๅฅ CI/CD ๆต็จ๏ผๅฏ็งปๆคๅฐ้จ็ฝฒๅฐ AWS๏ผROSA๏ผใAzure๏ผARO๏ผใ้ฟ้ไบๅ GCP โโ ๅๆถๅฉ็จ scale-to-zero ๅไธ็จๆบๅจๆฑ ๆฅๆๅคงๅๆๆฌ่็บฆใ
ๅฎๆต้ช่ฏๆ่ฆ
ๆฌๆนๆกๅทฒๅจ ROSA HCP 4.20.21 ้็พคไธๅฎๆ็ซฏๅฐ็ซฏ้ช่ฏ๏ผไธ AWS Lambda ่ฟ่กไบ็ดๆฅๅฏนๆฏๆต่ฏ๏ผ
| ๆๆ | AWS Lambda | OpenShift Serverless (Knative) |
|---|---|---|
| ๅทๅฏๅจๅปถ่ฟ | ~292ms | ~1.67s |
| ็ญ่ฏทๆฑๅปถ่ฟ | ~44-55ms | ~28-30ms |
| Scale-to-Zero | ่ชๅจ๏ผ~15min๏ผ | ่ชๅจ๏ผ~90s๏ผๅฏ้ ็ฝฎ๏ผ |
| ้จ็ฝฒๅคๆๅบฆ | 11 ไธช CLI ๅฝไปค๏ผ3 ไธช AWS ๆๅก | 1 ไธช oc apply ๅฝไปค |
| ๅคไบๆฏๆ | ไป AWS | ROSA / ARO / OCP๏ผไปปๆไบ๏ผ |
| CI/CD ็ฎก้ | ๆฏไธชไบๅ็ฌ็ปดๆค | ไธๅฅ็ฎก้้้ ๆๆ้็พค |
ๆญคๅค๏ผ้ๅฏนๅฎขๆท็นๅซๅ ณๆณจ็ ๅทฅไฝๆต็ผๆ ่ฝๅ๏ผๆไปฌ่ฟๅฏนๆฏไบ SonataFlow (Serverless Logic) ๅ AWS Step Functions๏ผ
| ๆๆ | AWS Step Functions | SonataFlow on ROSA |
|---|---|---|
| ๅทฅไฝๆตๆง่กๅปถ่ฟ | ~2ms (Express) | ~46ms (็ญ่ฏทๆฑ) |
| ้ฆๆฌก่ฏทๆฑ | ~962ms (ๅซ CLI ๅผ้) | ~220ms |
| ๅทฅไฝๆต่ง่ | ASL (AWS ไธๆ) | CNCF Serverless Workflow (ๅผๆพๆ ๅ) |
| ๅคไบๅฏ็งปๆค | โ ไป AWS | โ ไปปไฝ OCP ้็พค |
| K8s ๅ็ | โ | โ CRD + Operator |
่ฏฆ็ปๆต่ฏๆญฅ้ชคๅๅฎๆดๅฝไปค่พๅบ่ง
steps.md
1. ๆถๆๆฆ่ง
1.1 ๅฝๅ็ถๆ vs.ย ็ฎๆ ็ถๆ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๅฝๅ็ถๆ โ
โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ AWS โ โ CI/CD for โ โ ๆฏไธชไบๅ็ฌ็ CI/CD ็ฎก้ โ
โ โ Lambda โโโโโโ AWS Lambda โ โ AWS ไธๅฑ SDK, ่งฆๅๅจ, IAM โ
โ โ (ๅคไธช) โ โ (SAM/CDK) โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ Azure โ โ CI/CD for โ โ ๅฆไธๅฅๅ็ฌ็็ฎก้ โ
โ โ Functionsโโโโโโ Azure Func โ โ Azure ไธๅฑ bindings, triggers โ
โ โ (ๆชๆฅ) โ โ (func CLI) โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ
โ ้ฎ้ข: N ไธชไบ ร M ไธชๅฝๆฐ = NรM ๆก CI/CD ็ฎก้ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ ่ฟ็งป โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ็ฎๆ ็ถๆ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ไธๅฅ็ปไธ็ CI/CD Pipeline โ โ
โ โ (Tekton / OpenShift Pipelines โ โ
โ โ + OpenShift GitOps/ArgoCD) โ โ
โ โโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโ โ
โ โ ๅฎนๅจ้ๅ (OCI) โ โ
โ โ + Knative Service YAML โ โ
โ โโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โผ โผ โผ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ ROSA โ โ ARO โ โ OCP on โ โ
โ โ (AWS) โ โ (Azure) โ โ Ali/GCP โ โ
โ โ Knative โ โ Knative โ โ Knative โ โ
โ โ Serving โ โ Serving โ โ Serving โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ
โ ็ปๆ: 1 ๆก็ฎก้ ร M ไธชๅฝๆฐ = M ๆก CI/CD ็ฎก้๏ผไบๆ ๅ
ณ๏ผ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
1.2 ่ฏฆ็ป็ปไปถๆถๆ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ OpenShift ้็พค (ROSA / ARO / OCP) โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ๆงๅถ้ข (Hosted CP / Master Nodes) โ โ
โ โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ โ
โ โ โ API Server โ โ etcd โ โ Controllers โ โ โ
โ โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Serverless ๅบ็ก็ปไปถ (่ฟ่กๅจ Worker / Infra ่็น) โ โ
โ โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ Knative Serving โ โ Knative Eventing โ โ Kourier Ingress โ โ โ
โ โ โ Controller โ โ Controller โ โ Gateway โ โ โ
โ โ โ Activator โ โ PingSource Adapter โ โ (่ชๅจ TLS ่ทฏ็ฑ) โ โ โ
โ โ โ Autoscaler โ โ IMC Controller โ โ โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ไธ็จ Serverless ๆบๅจๆฑ (่ชๅจๆฉ็ผฉ 0 โ N) โ โ
โ โ โ โ
โ โ Node Taint: serverless=true:NoSchedule โ โ
โ โ Node Label: node-role.kubernetes.io/serverless="" โ โ
โ โ โ โ
โ โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ โ
โ โ โ Knative โ โ Knative โ โ Knative โ . . . โ Knative โ โ โ
โ โ โService Aโ โService Bโ โService Cโ โService Nโ โ โ
โ โ โ(pods) โ โ(pods) โ โ(pods) โ โ(pods) โ โ โ
โ โ โ scale โ โ scale โ โ scale โ โ scale โ โ โ
โ โ โ 1โ100 โ โ 0โ50 โ โ to zero โ โ to zero โ โ โ
โ โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ โ
โ โ โ โ
โ โ ๆๆ pod ็ผฉ้ถ โ ้็พค่ชๅจ็ผฉๅฎน็งป้ค่็น โ ่ฎก็ฎๆๆฌ $0 โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
2. ๅฎๆฝๆญฅ้ชค
Phase 1: ๅฎ่ฃ OpenShift Serverless๏ผ็ฌฌ 1-2 ๅจ๏ผ
Step 1.1: ๅฎ่ฃ OpenShift Serverless Operator
# ๅๅปบ Operator ๆ้็ namespaceใOperatorGroup ๅ Subscription
cat <<EOF | oc apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: openshift-serverless
---
apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
name: serverless-operators
namespace: openshift-serverless
spec: {}
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: serverless-operator
namespace: openshift-serverless
spec:
channel: stable
installPlanApproval: Automatic
name: serverless-operator
source: redhat-operators
sourceNamespace: openshift-marketplace
EOF
# ้ช่ฏ Operator ๅฎ่ฃ
ๅฎๆ๏ผ็บฆ 60 ็ง๏ผ
oc get csv -n openshift-serverless
# ้ขๆ่พๅบ: serverless-operator.v1.37.1 ... Succeededๅฎๆต็ปๆ: Serverless Operator v1.37.1 ๅจ็บฆ 60 ็งๅ ๅฎ่ฃ ๆๅใ
ๅฎๆนๆๆกฃ: ๅฎ่ฃ OpenShift Serverless
Step 1.2: ๅฎ่ฃ Knative Serving
cat <<EOF | oc apply -f -
apiVersion: operator.knative.dev/v1beta1
kind: KnativeServing
metadata:
name: knative-serving
namespace: knative-serving
spec:
ingress:
kourier:
enabled: true
config:
network:
ingress-class: kourier.ingress.networking.knative.dev
autoscaler:
enable-scale-to-zero: "true"
scale-to-zero-grace-period: "30s"
stable-window: "60s"
defaults:
revision-timeout-seconds: "300"
EOF
# ็ญๅพ
ๅฐฑ็ปช๏ผ็บฆ 50 ็ง๏ผ
oc wait --for=condition=Ready knativeserving/knative-serving \
-n knative-serving --timeout=300sๅฎๆต็ปๆ: KnativeServing (Knative 1.17) ๅจ็บฆ 50 ็งๅ ๅฐฑ็ปช๏ผ่ชๅจ้จ็ฝฒไบ activatorใautoscalerใcontrollerใwebhook ๅ Kourier ingress gatewayใ
ๅฎๆนๆๆกฃ: Knative Serving ้ ็ฝฎ
Step 1.3: ๅฎ่ฃ Knative Eventing
cat <<EOF | oc apply -f -
apiVersion: operator.knative.dev/v1beta1
kind: KnativeEventing
metadata:
name: knative-eventing
namespace: knative-eventing
spec:
config:
default-ch-webhook:
default-ch-config: |
clusterDefault:
apiVersion: messaging.knative.dev/v1
kind: InMemoryChannel
EOF
# ็ญๅพ
ๅฐฑ็ปช๏ผ็บฆ 90 ็ง๏ผ
oc wait --for=condition=Ready knativeeventing/knative-eventing \
-n knative-eventing --timeout=300sๅฎๆต็ปๆ: KnativeEventing (1.17) ๅจ็บฆ 90 ็งๅ ๅฐฑ็ปชใ
ๅฎๆนๆๆกฃ: Knative Eventing ้ ็ฝฎ
Phase 2: ไธ็จ Serverless ๆบๅจๆฑ ๏ผ็ฌฌ 2-3 ๅจ๏ผ
Step 2.1: ๅจ ROSA ไธๅๅปบไธ็จๆบๅจๆฑ
# ๅๅปบๆฏๆ่ชๅจๆฉ็ผฉๅ Spot ๅฎไพ็ไธ็จๆบๅจๆฑ
rosa create machinepool \
--cluster=<cluster-name> \
--name=serverless-pool \
--instance-type=m6a.xlarge \
--min-replicas=0 \
--max-replicas=10 \
--enable-autoscaling \
--labels="node-role.kubernetes.io/serverless=" \
--taints="serverless=true:NoSchedule" \
--use-spot-instances \
--spot-max-price=on-demand
# ้ช่ฏๆบๅจๆฑ
rosa list machinepools --cluster=<cluster-name>ๆ ธๅฟๆๆฌ่็บฆ็นๆง:
--min-replicas=0: ๆฒกๆ serverless pod ่ฟ่กๆถ๏ผ่็นๆฐไธบ 0--enable-autoscaling: ไป ๅฝ Knative pod ่ขซ่ฐๅบฆๆถๆๆฉๅฎน่็น--use-spot-instances: ็ธๆฏๆ้ๅฎไพๅฏ่็ 60-90% ็ๆๆฌ- Knative scale-to-zero: ๆ ๆต้ โ pod ็ปๆญข โ ่็น็ผฉๅฎน โ $0 ่ฎก็ฎๆๆฌ
Step 2.2: ๆๆฌ่็บฆๆต็จ
ๆ ๆต้ ๆต้ๅฐ่พพ
โโโโโโโโโ โโโโโโโโโโ
โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โ ่ฏทๆฑ โ โ Knative โ โ ๆบๅจๆฑ โ
โ ้็ = 0 โโโโโโถโ Scale-to-Zeroโโโโโโถโ ่็น = 0 โโโโโ ๆๆฌ = $0
โ โ โ Pods = 0 โ โ (่ชๅจ็ผฉๅฎน) โ
โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโ
โ ่ฏทๆฑ โ โ Activator โ โ ้็พค โ โ Knative โ
โ ๅฐ่พพ โโโโโโถโ ็ผๅฒ่ฏทๆฑ โโโโโโถโ ่ชๅจๆฉๅฎน โโโโโโถโ Pod โ
โ โ โ โ โ ๆทปๅ ่็น โ โ ๅฏๅจ โ
โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโ
โ ่ฏทๆฑ่ขซๅค็ โ
โ (~1.5-3s โ
โ ๅทๅฏๅจ) โ
โโโโโโโโโโโโโโโโ
ๆถ้ด็บฟ:
โโโ ๆต้ๅๆญข โโโคโโ 15-30s ๅฎฝ้ๆ โโโคโโ 60s ็จณๅฎ็ชๅฃ โโโคโโ ่็น็ฉบ้ฒ 10m โโโค
โ โ pods ไปๅจ่ฟ่ก โ pods ็ปๆญข โ ่็น่ขซ็งป้ค โ
โ โ (ๅฏ้
็ฝฎ) โ (scale-to-zero) โ (้็พค่ชๅจ็ผฉๅฎน) โ
Step 2.3: ้ ็ฝฎ Knative Service ไฝฟ็จไธ็จๆบๅจๆฑ
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: my-function
namespace: my-project
spec:
template:
spec:
tolerations:
- key: "serverless"
operator: "Equal"
value: "true"
effect: "NoSchedule"
nodeSelector:
node-role.kubernetes.io/serverless: ""
containers:
- image: <registry>/<project>/my-function:latest
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Miๅฎๆนๆๆกฃ: ROSA ๆบๅจๆฑ ็ฎก็
Phase 3: Lambda ๅฐ Knative ่ฟ็งป๏ผ็ฌฌ 3-5 ๅจ๏ผ
Step 3.1: Lambda ๆฆๅฟตๆ ๅฐ
| AWS Lambda ๆฆๅฟต | Knative / OpenShift ็ญไปท็ฉ |
|---|---|
| Lambda Function | Knative Service (ksvc) |
| Lambda Handler | ๅฎนๅจๅ ฅๅฃ็น / HTTP handler |
| API Gateway trigger | Knative Route๏ผ้ ksvc ่ชๅจๅๅปบ๏ผ |
| SQS trigger | KafkaSource / SinkBinding + AMQ Streams |
| S3 trigger | SinkBinding via Knative Eventing |
| Schedule trigger (EventBridge) | PingSource |
| DynamoDB trigger | ่ชๅฎไน Source ๆ Change Data Capture |
| SNS trigger | Knative Channel + Subscription |
| Env variables | ConfigMap / Secret ๅผ็จ |
| Lambda Layers | ๅค้ถๆฎตๅฎนๅจๆๅปบ๏ผๅ ฑไบซๅบ็ก้ๅ๏ผ |
| Concurrency limit | containerConcurrency ๅญๆฎต |
| Timeout | timeoutSeconds ๅญๆฎต |
| Cold start ไผๅ | minScale โฅ 1๏ผไฟๆ 1 ไธช pod ้ข็ญ๏ผ |
| Versioning/Alias | Knative Revisions + Traffic Splitting |
| X-Ray tracing | OpenTelemetry Collector |
| CloudWatch logs | OpenShift Logging / ้็พคๆฅๅฟ |
| AWS SAM template | Knative Service YAML + Tekton Pipeline |
| AWS CDK | Helm Chart / Kustomize + ArgoCD |
aws lambda invoke |
curl https://<ksvc-route> ๆ kn service invoke |
Step 3.2: ่ฝฌๆข Lambda ๅฝๆฐไธบ Knative Service
ๅๅง Lambda ๅฝๆฐ (lambda_function.py):
import json
import time
import os
import platform
COLD_START = True
def lambda_handler(event, context):
global COLD_START
was_cold = COLD_START
COLD_START = False
name = "World"
qs = event.get("queryStringParameters") or {}
if isinstance(qs, dict) and qs.get("name"):
name = qs["name"]
return {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": json.dumps({
"message": f"Hello, {name}!",
"platform": "AWS Lambda",
"cold_start": was_cold
})
}่ฝฌๆขไธบ Knative ๅ
ผๅฎน็ HTTP ๆๅก (app.py):
from flask import Flask, request, jsonify
import os
import time
import platform
app = Flask(__name__)
COLD_START = True
@app.route("/", methods=["GET", "POST"])
def handler():
global COLD_START
was_cold = COLD_START
COLD_START = False
if request.method == "POST":
event = request.get_json(silent=True) or {}
name = event.get("name", "World")
else:
name = request.args.get("name", "World")
return jsonify({
"message": f"Hello, {name}!",
"platform": "OpenShift Serverless (Knative)",
"cold_start": was_cold,
"pod_name": os.environ.get("HOSTNAME", "unknown")
})
if __name__ == "__main__":
port = int(os.environ.get("PORT", 8080))
app.run(host="0.0.0.0", port=port)Dockerfile:
FROM registry.access.redhat.com/ubi9/python-311:latest
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
EXPOSE 8080
CMD ["python", "app.py"]Knative Service YAML (knative-service.yaml):
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hello-function
namespace: serverless-demo
labels:
app.kubernetes.io/part-of: serverless-functions
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/min-scale: "0" # ็ฉบ้ฒๆถ็ผฉ้ถ
autoscaling.knative.dev/max-scale: "10" # ๆๅคง pod ๆฐ
autoscaling.knative.dev/target: "50" # ๆฏ pod 50 ๅนถๅ
autoscaling.knative.dev/scale-down-delay: "15s"
spec:
containerConcurrency: 50
timeoutSeconds: 300
containers:
- image: <registry>/hello-function:latest
ports:
- containerPort: 8080
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
readinessProbe:
httpGet:
path: /
initialDelaySeconds: 0ๅฎๆต: ้จ็ฝฒๅ็บฆ 10 ็งๅณๅฐฑ็ปช๏ผ่ชๅจ็ๆ HTTPS ่ทฏ็ฑใ
# ๅฎๆต่พๅบ
$ oc get ksvc -n serverless-demo
NAME URL LATESTCREATED LATESTREADY READY
hello-function https://hello-function-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com hello-function-00001 hello-function-00001 True
# ็ญ่ฏทๆฑๆต่ฏ
$ time curl -sk "https://hello-function-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com"
Hi greeter => '9861675f8845' : 5
real 0m0.030s
$ time curl -sk "https://hello-function-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com"
Hi greeter => '9861675f8845' : 6
real 0m0.029s
# ้ช่ฏ Scale-to-Zero๏ผ็ญๅพ
็บฆ 120 ็งๅ๏ผ
$ oc get pods -n serverless-demo
No resources found in serverless-demo namespace. โ Pod ๅทฒ่ขซ็งป้ค
$ oc get revisions -n serverless-demo
NAME CONFIG NAME GENERATION READY ACTUAL REPLICAS DESIRED REPLICAS
hello-function-00001 hello-function 1 True 0 0
# โ
Scale-to-Zero ้ช่ฏๆๅ๏ผACTUAL REPLICAS = 0
# ๅทๅฏๅจๆต่ฏ๏ผไป้ถๆฉๅฎน๏ผ
$ time curl -sk "https://hello-function-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com"
Hi greeter => '9861675f8845' : 3
real 0m1.668s โ ๅทๅฏๅจ ~1.67s
$ time curl -sk "https://hello-function-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com"
Hi greeter => '9861675f8845' : 4
real 0m0.030s โ ็ญ่ฏทๆฑๆขๅคๅฐ ~30msStep 3.3: Knative Functions (kn func) โ ็ๆญฃ็ Lambda ็ญไปทๅผๅไฝ้ช
Phase 3.2 ไฝฟ็จไบไธไธช้ขๆๅปบ็ๅฎนๅจ้ๅ็ดๆฅ้จ็ฝฒไธบ Knative Serviceใไฝ AWS Lambda ็ๅผๅไฝ้ชๆฏ โๅชๅๅฝๆฐไปฃ็ ๏ผไธๅ ณๅฟๅฎนๅจโใ
kn func(Knative Functions) ๆไพไบๅฎๅ จ็ญไปท็ไฝ้ช๏ผๅชๅๅฝๆฐไปฃ็ โ ่ชๅจๆๅปบ้ๅ (S2I) โ ้จ็ฝฒไธบ Knative Service๏ผๆ ้ Dockerfileใ
Step 1: ๅๅปบๅฝๆฐ้กน็ฎ
# ๅฎ่ฃ
kn CLI๏ผOpenShift Serverless 1.37 ้
ๅฅ็ๆฌ๏ผ
$ curl -sL https://mirror.openshift.com/pub/openshift-v4/clients/serverless/1.17.0/kn-linux-amd64.tar.gz \
| tar xz -C /tmp/
$ /tmp/kn version
Version: v1.17.0
Build Date: 2025-04-22 16:39:02
# ๅๅปบ Python ๅฝๆฐ้กน็ฎ๏ผ่ชๅจ็ๆ้ชจๆถไปฃ็ ๏ผ
$ /tmp/kn func create -l python hello-func
Created python function in /tmp/hello-func
$ ls /tmp/hello-func/
.funcignore func.yaml function/ requirements.txt
# ๆณจๆ๏ผๆฒกๆ Dockerfile๏ผไฝฟ็จ S2I (Source-to-Image) ่ชๅจๆๅปบStep 2: ็ผๅๅฝๆฐไปฃ็
# function/func.py โ ASGI ๅ่ฎฎ๏ผไธ Lambda handler ็ญไปท
import json, os, time
COLD_START = True
def new():
return Function()
class Function:
async def handle(self, scope, receive, send):
global COLD_START
was_cold = COLD_START
COLD_START = False
start = time.time()
# ่ฏปๅ่ฏทๆฑ body
body = b""
while True:
msg = await receive()
body += msg.get("body", b"")
if not msg.get("more_body"): break
# ่งฃๆๅๆฐ๏ผๆฏๆ query string ๅ JSON body๏ผ
name = "World"
qs = scope.get("query_string", b"").decode()
for param in qs.split("&"):
if param.startswith("name="): name = param.split("=", 1)[1]; break
if body:
try: data = json.loads(body); name = data.get("name", name)
except: pass
# ๆๅปบๅๅบ
elapsed = (time.time() - start) * 1000
resp = json.dumps({
"message": f"Hello, {name}!",
"platform": "OpenShift Serverless Function (kn func)",
"cold_start": was_cold,
"processing_time_ms": round(elapsed, 2),
"pod_name": os.environ.get("HOSTNAME", "unknown")
})
await send({"type": "http.response.start", "status": 200,
"headers": [[b"content-type", b"application/json"]]})
await send({"type": "http.response.body", "body": resp.encode()})Step 3: ๆๅปบ & ้จ็ฝฒ
# ๆด้ฒ OpenShift ๅ
้จ้ๅไปๅบ
$ oc patch configs.imageregistry.operator.openshift.io/cluster --type merge \
-p '{"spec":{"defaultRoute":true}}'
$ REGISTRY_HOST=$(oc get route default-route -n openshift-image-registry -o jsonpath='{.spec.host}')
# ๆๅปบ้ๅ๏ผS2I ่ชๅจๆๅปบ๏ผๆ ้ Dockerfile๏ผ๏ผ
$ cd /tmp/hello-func
$ /tmp/kn func build -r "$REGISTRY_HOST/serverless-demo" -v
๐ Function built: default-route-openshift-image-registry.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com/serverless-demo/hello-func:latest
# ๆจ้้ๅๅฐๅ
้จ Registry
$ TOKEN=$(oc whoami -t)
$ podman login "$REGISTRY_HOST" -u kubeadmin -p "$TOKEN" --tls-verify=false
Login Succeeded!
$ podman push "$REGISTRY_HOST/serverless-demo/hello-func:latest" --tls-verify=false
Writing manifest to image destination
# ้จ็ฝฒไธบ Knative Service๏ผไฝฟ็จ้็พคๅ
้จ registry ๅฐๅ๏ผ
$ /tmp/kn service create hello-func \
--image image-registry.openshift-image-registry.svc:5000/serverless-demo/hello-func:latest \
-n serverless-demo \
--annotation autoscaling.knative.dev/min-scale=0 \
--annotation autoscaling.knative.dev/max-scale=10
Creating service 'hello-func' in namespace 'serverless-demo':
12.036s Ready to serve.
Service 'hello-func' created to latest revision 'hello-func-00001' is available at URL:
https://hello-func-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.comStep 3b: ๆๅปบ โ ๆนๆณไบ๏ผDockerfile (้็จๆนๆณ๏ผๆ ๅๅไพ่ต)
S2I (Source-to-Image) ๆฏ Red Hat ็นๆ็ๆๅปบๆๆฏใๅฆๆๆจ็ๅข้ๆดไน ๆฏๆ ๅ Dockerfile ๅทฅไฝๆต๏ผๆ่ ้่ฆๅจ้ OpenShift ็ฏๅขไธญๆๅปบ้ๅ๏ผๅฏไปฅไฝฟ็จไปฅไธ Dockerfile ๆนๆณใ
ๅบๅฑ่ฟ่กๆถๅฎๅ จ็ธๅ๏ผ้ฝไฝฟ็จๅผๆบ็
func-pythonๅ ๏ผApache-2.0 ่ฎธๅฏ่ฏ๏ผ๏ผๅ ็ฝฎhypercornASGI ๆๅกๅจใ
# ๅๅปบ Dockerfile๏ผ็ญไปทไบ S2I ่ชๅจ็ๆ็ๆๅปบ้ป่พ๏ผ
cat > /tmp/hello-func/Dockerfile <<'DOCKERFILE'
FROM registry.access.redhat.com/ubi9/python-312:latest
WORKDIR /opt/app-root/src
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY function/ ./function/
COPY main.py .
EXPOSE 8080
CMD ["python", "main.py"]
DOCKERFILE
# ๅๅปบๅ
ฅๅฃๆไปถ main.py๏ผไธ S2I ๅ
้จ็ๆ็ๅ
ฅๅฃไธ่ด๏ผ
cat > /tmp/hello-func/main.py <<'MAIN'
import logging
from func_python.http import serve
logging.basicConfig(level=logging.INFO)
try:
from function import new as handler
except ImportError:
from function import handle as handler
if __name__ == "__main__":
logging.info("Functions middleware invoking user function")
serve(handler)
MAIN
# ็กฎไฟ function/__init__.py ๅฏผๅบๆญฃ็กฎ
cat > /tmp/hello-func/function/__init__.py <<'INIT'
from .func import new
INIT
# ไฝฟ็จ podman ๆๅปบ้ๅ
$ cd /tmp/hello-func
$ podman build -t "$REGISTRY_HOST/serverless-demo/hello-func:dockerfile" .
STEP 1/7: FROM registry.access.redhat.com/ubi9/python-312:latest
STEP 2/7: WORKDIR /opt/app-root/src
STEP 3/7: COPY requirements.txt .
STEP 4/7: RUN pip install --no-cache-dir -r requirements.txt
Successfully installed ...
STEP 5/7: COPY function/ ./function/
STEP 6/7: COPY main.py .
STEP 7/7: EXPOSE 8080
COMMIT default-route-openshift-image-registry.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com/serverless-demo/hello-func:dockerfile
Successfully tagged ...
# ๆจ้ & ้จ็ฝฒ
$ podman push "$REGISTRY_HOST/serverless-demo/hello-func:dockerfile" --tls-verify=false
Writing manifest to image destination
$ /tmp/kn service create hello-func \
--image image-registry.openshift-image-registry.svc:5000/serverless-demo/hello-func:dockerfile \
-n serverless-demo --force \
--annotation autoscaling.knative.dev/min-scale=0 \
--annotation autoscaling.knative.dev/max-scale=10
Service 'hello-func' created to latest revision 'hello-func-00001' is available at URL:
https://hello-func-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com
# ้ช่ฏ๏ผๆง่ฝไธ S2I ็ๅฎๅ
จไธ่ด๏ผ
$ time curl -sk "$FUNC_URL?name=Demo"
{"message": "Hello, Demo!", "platform": "OpenShift Serverless Function (Dockerfile)",
"cold_start": true, "processing_time_ms": 0.01,
"pod_name": "hello-func-00001-deployment-5cf64484f9-vxbl8"}
real 0m0.031s
$ time curl -sk "$FUNC_URL?name=Dockerfile"
{"message": "Hello, Dockerfile!", "platform": "OpenShift Serverless Function (Dockerfile)",
"cold_start": false, "processing_time_ms": 0.01, ...}
real 0m0.026sไธค็งๆๅปบๆนๅผๅฏนๆฏ:
| ็ปดๅบฆ | S2I (kn func build) | Dockerfile (podman build) |
|---|---|---|
| ๆๅปบๅทฅๅ ท | kn func build (ๅ
็ฝฎ S2I) |
podman build / docker build |
| Dockerfile | โ ไธ้่ฆ๏ผ่ชๅจ็ๆ๏ผ | โ ้่ฆ็ผๅ |
| ๅ ฅๅฃๆไปถ | โ ไธ้่ฆ๏ผS2I ่ชๅจๆณจๅ ฅ๏ผ | โ
้่ฆ main.py |
| ่ฟ่กๆถ | func-python + hypercorn |
func-python + hypercorn (ๅฎๅ
จ็ธๅ) |
| OpenShift ไพ่ต | ้่ฆ S2I builder image | ๆ ไพ่ต๏ผไปปไฝๅฎนๅจๅผๆๅๅฏ |
| CI/CD ้ๆ | OpenShift Pipelines (S2I task) | ้็จ (Buildah / Kaniko / Docker) |
| ็ฆป็บฟๆๅปบ | ้่ฆ S2I builder ้ๅ | ไป ้ UBI ๅบ็ก้ๅ |
| ๆๅปบ้ๅบฆ | ~15-20s | ~10-15s |
| ้็จๅบๆฏ | OpenShift ๅ็ๅผๅ | ๅคๅนณๅฐ / ๆททๅ็ฏๅข / ๆ ๅๅๆต็จ |
ๅปบ่ฎฎ: ๅฆๆๅข้ๅทฒๆๆ ๅๅ็ Dockerfile + CI/CD ๆต็จ๏ผๅฆ JenkinsใGitLab CI๏ผ๏ผๆจ่ไฝฟ็จ Dockerfile ๆนๆณ๏ผๅฆๆๅ จๆ ไฝฟ็จ OpenShift๏ผS2I ๆนๆณๆด็ฎๆดใไธค่ ็ๆ็้ๅ่ฟ่กๆถๅฎๅ จ็ธๅ๏ผๆง่ฝๆ ๅทฎๅผใ
Step 3c: ๅจ Web Console ไธญๆพ็คบไธบ Function
้ฎ้ข: ไฝฟ็จ
kn service createๆๅจ้จ็ฝฒ็ Knative Service๏ผๅจ OpenShift Web Console ็ Serverless โ Functions ่งๅพไธญไธไผๆพ็คบใๅๅ : Web Console ไพ่ต็นๅฎ็ label ๆฅ่ฏๅซ โFunctionโใ
kn service createๅชๅๅปบๆฎ้็ Knative Service๏ผไธไผ่ชๅจๆทปๅ ่ฟไบ labelใ
# ๆนๆณไธ๏ผๆๅจๆทปๅ label๏ผ้็จไบๅทฒ้จ็ฝฒ็ Service๏ผ
$ oc label ksvc hello-func \
function.knative.dev=true \
function.knative.dev/name=hello-func \
boson.dev/function=true \
-n serverless-demo
service.serving.knative.dev/hello-func labeled
# ้ช่ฏ label
$ oc get ksvc hello-func -n serverless-demo -o jsonpath='{.metadata.labels}' | jq .
{
"boson.dev/function": "true",
"function.knative.dev": "true",
"function.knative.dev/name": "hello-func"
}
# โ
ๅทๆฐ Web Console โ Serverless โ Functions๏ผๅณๅฏ็ๅฐ hello-funcๆฟไปฃๆนๆก:
kn func deployโ ๅฆๆไฝฟ็จkn func deployไปฃๆฟๆๅจ็ build + push + create ไธๆญฅๆไฝ๏ผๅฎไผ่ชๅจๅฎๆ ๆๅปบ + ๆจ้ + ้จ็ฝฒ + ๆทปๅ function label๏ผๆฏๆ็ฎไพฟ็ๆนๅผ๏ผ
# ๅจๅฝๆฐ้กน็ฎ็ฎๅฝไธญไธๆญฅๅฎๆ๏ผ่ชๅจๆทปๅ function label๏ผ cd /tmp/hello-func /tmp/kn func deploy -r "$REGISTRY_HOST/serverless-demo" -n serverless-demo # ็ญไปทไบ: kn func build + podman push + kn service create + ่ชๅจๆทปๅ function labelsไธค่ ๅ่ฝๅฎๅ จ็ธๅ๏ผlabel ๅชๅฝฑๅ Web Console ็ๅฑ็คบๅ็ฑป๏ผไธๅฝฑๅ่ฟ่กๆถ่กไธบใ
Step 4: ๆต่ฏ
FUNC_URL="https://hello-func-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com"
# GET ่ฏทๆฑ
$ time curl -sk "$FUNC_URL?name=Demo"
{"message": "Hello, Demo!", "platform": "OpenShift Serverless Function (kn func)",
"cold_start": true, "processing_time_ms": 0.01,
"pod_name": "hello-func-00001-deployment-5c4c9b46c9-5s4mc"}
real 0m0.038s
# ็ญ่ฏทๆฑ
$ time curl -sk "$FUNC_URL?name=OpenShift"
{"message": "Hello, OpenShift!", "platform": "OpenShift Serverless Function (kn func)",
"cold_start": false, "processing_time_ms": 0.01, ...}
real 0m0.031s
# POST ่ฏทๆฑ๏ผJSON body๏ผ
$ time curl -sk -X POST "$FUNC_URL" -H "Content-Type: application/json" \
-d '{"name":"KnativeFunction"}'
{"message": "Hello, KnativeFunction!", "platform": "OpenShift Serverless Function (kn func)",
"cold_start": false, "processing_time_ms": 0.03, ...}
real 0m0.030skn func ๅผๅไฝ้ช vs Lambda ๅฏนๆฏ:
| ๆญฅ้ชค | AWS Lambda | kn func (Knative Functions) |
|---|---|---|
| ่ๆๆถ | sam init |
kn func create -l python |
| ๅไปฃ็ | lambda_handler(event, context) |
Function.handle(scope, receive, send) |
| ๆๅปบ | sam build / zip ๆๅ
|
kn func build (S2I, ๆ ้ Dockerfile) |
| ้จ็ฝฒ | sam deploy + IAM + API GW |
kn service create --image ... |
| Dockerfile | โ ไธ้่ฆ | โ ไธ้่ฆ (S2I ่ชๅจๆๅปบ) |
| SDK ไพ่ต | AWS SDK, boto3 | ๆ (ๆ ๅ HTTP/ASGI) |
| ๆฏๆ่ฏญ่จ | Python/Node/Go/Java/โฆ | Python/Node/Go/Quarkus/Rust/TypeScript |
| ็ญ่ฏทๆฑๅปถ่ฟ | ~44-55ms | ~28-31ms |
| ๅคไบ | โ ไป AWS | โ ไปปไฝ OCP ้็พค |
็ป่ฎบ:
kn funcๆไพไบไธ Lambda ๅฎๅ จ็ญไปท็ โๅชๅไปฃ็ ๏ผไธๅ ณๅฟๅฎนๅจโ ๅผๅไฝ้ช๏ผๅๆถไฟๆๅคไบๅฏ็งปๆคๆงใ
ๅฎๆนๆๆกฃ: Knative Functions (kn func)
Phase 4: ็ปไธ CI/CD ็ฎก้๏ผ็ฌฌ 4-6 ๅจ๏ผ
Step 4.1: CI/CD ๆถๆ
ๅผๅ่
โโโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Git โโโโโโโโถโ Git Repo โโโโโโโโถโ Tekton EventListener โ
โ Push โ โ (GitHub/ โ โ (webhook ่งฆๅ) โ
โ โ โ GitLab) โ โโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโ โโโโโโโโโโโโโ โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Tekton Pipeline Run โ
โโโโโโโโโโโโโโฌโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโดโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ
โ Task: Clone โ โ Task: Build & โ โ Task: Deploy โ
โ Source Code โโโโโโโโโโถ โ Push Image โโโโโโโถโ via GitOps โ
โ โ โ (Buildah/s2i) โ โ (ArgoCD sync) โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโฌโโโโโโโโโ
โ โ
โผ โผ
โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ
โ Quay.io / โ โ GitOps Repo โ
โ Internal Registryโ โ (kustomize overlay โ
โ โ โ per environment) โ
โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโฌโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโ
โ ROSA (AWS) โ โ ARO (Azure) โ โ OCP โ
โ Knative Svc โ โ Knative Svc โ โ (Ali/ โ
โ deployed โ โ deployed โ โ GCP) โ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโ
Step 4.2: Tekton Pipeline ๅฎไน
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: serverless-function-pipeline
namespace: serverless-cicd
spec:
params:
- name: git-url
type: string
- name: git-revision
type: string
default: main
- name: function-name
type: string
- name: image-registry
type: string
default: quay.io/my-org
- name: target-namespace
type: string
default: serverless-demo
workspaces:
- name: shared-workspace
- name: docker-credentials
tasks:
- name: fetch-source
taskRef:
name: git-clone
kind: ClusterTask
workspaces:
- name: output
workspace: shared-workspace
params:
- name: url
value: $(params.git-url)
- name: revision
value: $(params.git-revision)
- name: build-image
taskRef:
name: buildah
kind: ClusterTask
runAfter: [fetch-source]
workspaces:
- name: source
workspace: shared-workspace
- name: dockerconfig
workspace: docker-credentials
params:
- name: IMAGE
value: "$(params.image-registry)/$(params.function-name):$(params.git-revision)"
- name: deploy-knative-service
taskRef:
name: openshift-client
kind: ClusterTask
runAfter: [build-image]
params:
- name: SCRIPT
value: |
oc apply -f knative-service.yaml -n $(params.target-namespace)Step 4.3: GitOps ไปๅบ็ปๆ
serverless-gitops/
โโโ base/
โ โโโ kustomization.yaml
โ โโโ knative-service-template.yaml
โโโ functions/
โ โโโ hello-function/
โ โ โโโ kustomization.yaml
โ โ โโโ knative-service.yaml
โ โโโ order-processor/
โ โ โโโ kustomization.yaml
โ โ โโโ knative-service.yaml
โ โโโ notification-sender/
โ โโโ kustomization.yaml
โ โโโ knative-service.yaml
โโโ overlays/
โ โโโ rosa-prod/
โ โ โโโ kustomization.yaml
โ โ โโโ patches/
โ โ โโโ scale-config.yaml # minScale=0, maxScale=100
โ โโโ aro-prod/
โ โ โโโ kustomization.yaml
โ โ โโโ patches/
โ โ โโโ scale-config.yaml
โ โ โโโ registry-override.yaml # Azure Container Registry
โ โโโ ocp-ali-prod/
โ โโโ kustomization.yaml
โ โโโ patches/
โ โโโ registry-override.yaml # ้ฟ้ไบ Registry
โโโ argocd/
โโโ rosa-prod-app.yaml
โโโ aro-prod-app.yaml
โโโ ocp-ali-prod-app.yaml
ๅฎๆนๆๆกฃ: OpenShift Pipelines (Tekton)
Phase 5: ไบไปถๆบ้ๆ๏ผ็ฌฌ 5-7 ๅจ๏ผ
Step 5.1: Knative Eventing ๆถๆ โ ๆฟๆข Lambda ่งฆๅๅจ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Knative Eventing ๆถๆ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ไบไปถๆบ โ โ
โ โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโ โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โ
โ โ โ PingSource โโโโโโโโโถโ โโโโโโถโ Knative Service โ โ
โ โ โ (ๅฎๆถ่ฐๅบฆ) โ โ โ Knative โ โ (ๅฎๆถไปปๅกๅค็) โ โ
โ โ โโโโโโโโโโโโโโโโโโโ โ โ Broker โ โโโโโโโโโโโโโโโโโโโโ โ
โ โ โ โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโ โ โ (ๆฅๆถๆๆ โ โโโโโโโโโโโโโโโโโโโโ โ
โ โ โ KafkaSource โโโโโโโโโถโ ไบไปถ๏ผ้่ฟ โโโโโโถโ Knative Service โ โ
โ โ โ (ๆฟไปฃ SQS) โ โ โ Trigger โ โ (ๆถๆฏๅค็) โ โ
โ โ โโโโโโโโโโโโโโโโโโโ โ โ ่ทฏ็ฑๅๅ) โ โโโโโโโโโโโโโโโโโโโโ โ
โ โ โ โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโ โ โ โ โโโโโโโโโโโโโโโโโโโโ โ
โ โ โ ApiServerSource โโโโโโโโโถโ โโโโโโถโ Knative Service โ โ
โ โ โ (K8s ไบไปถ) โ โ โ โ โ (K8s ไบไปถ็ๅฌ) โ โ
โ โ โโโโโโโโโโโโโโโโโโโ โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โ
โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ CloudEvents ่ง่ = ่ทจไบ็ๅฏ็งปๆคไบไปถๆ ผๅผ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Step 5.2: PingSource โ ๆฟไปฃ CloudWatch Events / EventBridge ๅฎๆถ่งฆๅ
# ๆฟไปฃ: AWS EventBridge rule โ Lambda (cron)
apiVersion: sources.knative.dev/v1
kind: PingSource
metadata:
name: daily-report-trigger
namespace: serverless-demo
spec:
schedule: "0 2 * * *" # ๆฏๅคฉๅๆจ 2 ็น
contentType: "application/json"
data: '{"action": "generate-daily-report"}'
sink:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: daily-report-functionๅฎๆต: PingSource ๅๅปบๅ็ซๅณ็ๆ๏ผๆ็ ง cron ่กจ่พพๅผ่ชๅจ่งฆๅ Knative Serviceใ
ๆณจๆ
sinkๅญๆฎต็ดๆฅๆๅ Knative Service๏ผ่ฟๅฐฑๆฏ Direct Sink๏ผ็ดๆฅๆ้๏ผ ๆจกๅผ โโ ๆ ้ BrokerใChannel ๆ Kafkaใ
Step 5.2b: ไบไปถๆ้ๆบๅถ่ฏฆ่งฃ โ ไธบไปไนไธ้่ฆ Kafka๏ผ
ๅธธ่ง็้ฎ: ้ ็ฝฎไบ Knative Eventing ไฝๆฒกๆๅฎ่ฃ Kafka๏ผไบไปถๆฏๆไนๆ้็ปๆๅก็ซฏ็๏ผ
็ญๆก๏ผPingSource ไฝฟ็จ Direct Sink ๆจกๅผ๏ผ็ดๆฅ HTTP POST ๅฐ Knative Service ็ๅ ้จ URL๏ผๆ ้ไปปไฝๆถๆฏไธญ้ดไปถใ
โโโโโโโโโโโโโโโ HTTP POST (CloudEvent) โโโโโโโโโโโโโโโโโโโโโโโ
โ PingSource โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโถ โ Knative Service โ
โ (cron ่งฆๅ) โ ็ดๆฅๅ้ๅฐ้็พคๅ
้จ URL โ daily-report-func โ
โ โ ๆ ไธญ้ดไปถใๆ Broker โ .serverless-demo โ
โ โ ๆ Channelใๆ Kafka โ .svc.cluster.local โ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ
ๆ้่ฟ็จ๏ผ
- PingSource Controller ๆ cron ่กจ่พพๅผ็ๆ CloudEvent
- ็ดๆฅ HTTP POST ๅฐ
http://<service-name>.<namespace>.svc.cluster.local - Knative Service ๆถๅฐ่ฏทๆฑ๏ผ่ฅ pod ไธบ 0 ๅ่ชๅจ scale-from-zero
- ๆดไธช้พ่ทฏๆ ไปปไฝๆถๆฏไธญ้ดไปถๅไธ
Knative Eventing ไธ็งไบไปถๆ้ๆจกๅผ๏ผ
| ๆจกๅผ | ไธญ้ดไปถ | ้็จๅบๆฏ |
|---|---|---|
| 1. Direct Sink | ๆ | 1 ไธชไบไปถๆบ โ 1 ไธชๆๅก๏ผ็ฎๅ็นๅฏน็น |
| 2. Channel + Subscription | InMemoryChannel ๆ KafkaChannel | 1 โ ๅค๏ผๆๅบ๏ผ๏ผๆ้กบๅบๆ้ |
| 3. Broker + Trigger | InMemoryChannel ๆ KafkaChannel | ๅค โ ๅค๏ผๆๅฑๆง่ฟๆปค่ทฏ็ฑ |
ๆจกๅผไธ (Direct Sink): PingSource โโHTTP POSTโโโถ Service
ๆจกๅผไบ (Channel/Sub): PingSource โโโถ Channel โโSubโโโถ Service A
โโSubโโโถ Service B
ๆจกๅผไธ (Broker/Trigger): PingSource โโโถ Broker โโTriggerโโโถ Service A
KafkaSourceโโโถ โโTriggerโโโถ Service B
ๅ ณไบ InMemoryChannel: ๅฎ่ฃ Knative Eventing ๆถ้ ็ฝฎ็
InMemoryChannelๆฏ้ป่ฎค็ Channel ๅฎ็ฐ๏ผไฝๅชๆๅจไฝฟ็จ Broker ๆ Channel ๆจกๅผๆถๆไผ่ขซๅๅปบๅไฝฟ็จใDirect Sink ๆจกๅผๅฎๅ จไธๆถๅ Channelใ
ไปไนๆถๅ้่ฆๅผๅ ฅ Kafka๏ผ
| ๅบๆฏ | ๆจ่ |
|---|---|
| ็ฎๅๅฎๆถ่งฆๅใ็นๅฏน็นไบไปถ | Direct Sink ๅณๅฏ๏ผๆ ้ Kafka |
| 1 ไธชไบไปถ โ ๅคไธชๆถ่ดน่ ๏ผๆๅบ๏ผ | Channel + Subscription๏ผๅฏ็จ InMemoryChannel |
| ้ซๅๅไบไปถๆต๏ผ>1000 msg/s๏ผ | KafkaChannel ๆฟไปฃ InMemoryChannel |
| ๆถๆฏๆไน ๅใไธ่ฝไธขๆถๆฏ | KafkaChannel๏ผๅ ๅญ Channel ้ๅฏไธขๅคฑ๏ผ |
| ่ทจ้็พคไบไปถไผ ๆญ | KafkaSource ๆถ่ดนๅค้จ Kafka topic |
| ๅ่ง/ๅฎก่ฎก่ฆๆฑ | Kafka ๆไพๆถๆฏๆไน ๅๅๅฏ่ฟฝๆบฏๆง |
่ฎพ่ฎก็ๅฟต: Knative Eventing ้็จๅๅฑๆถๆ โโ
็ฎๅๅบๆฏ้ถไธญ้ดไปถ๏ผDirect Sink๏ผ๏ผๅคๆๅบๆฏๆ้ๅผๅ ฅ Channel/Broker + Kafkaใ
ไธๅฎ่ฃ Kafka ไน่ฝๅฎๆดไฝฟ็จไบไปถๅ่ฝ๏ผ่ฟๆญฃๆฏ Knative ่ฎพ่ฎก็็ตๆดปๆงๆๅจใ
Step 5.3: KafkaSource โ ๆฟไปฃ SQS ่งฆๅๅจ
apiVersion: sources.knative.dev/v1beta1
kind: KafkaSource
metadata:
name: order-events
namespace: serverless-demo
spec:
consumerGroup: order-consumer
bootstrapServers:
- kafka-cluster-kafka-bootstrap.amq-streams:9092
topics:
- orders
sink:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: order-processorๅฎๆนๆๆกฃ: Knative Eventing ไบไปถๆบ
Phase 6: ๆๆฌไผๅ้ ็ฝฎ๏ผ็ฌฌ 6-7 ๅจ๏ผ
Step 6.1: ่ชๅจๆฉ็ผฉๅๆฐ่ฐไผ
| ๅๆฐ | ๆจ่ๅผ | ็จ้ |
|---|---|---|
autoscaling.knative.dev/min-scale |
"0" |
็ฉบ้ฒๆถ็ผฉ้ถ๏ผๆๅคง่็๏ผ |
autoscaling.knative.dev/max-scale |
"50" per function |
้ฒๆญขๅคฑๆงๆฉๅฎน |
autoscaling.knative.dev/target |
"50" |
ๆฏ pod ๅนถๅ่ฏทๆฑๆฐ |
autoscaling.knative.dev/scale-down-delay |
"15s" |
็ผฉๅฎนๅ็ญๅพ ๆถ้ด |
scale-to-zero-grace-period |
"30s" (ๅ
จๅฑ) |
็ปๆญขๆๅไธไธช pod ๅ็ๅฎฝ้ๆ |
stable-window |
"60s" (ๅ
จๅฑ) |
็จณๅฎ่ชๅจๆฉ็ผฉๅณ็ญ็ๆถ้ด็ชๅฃ |
ๅฎๆต: ้ ็ฝฎ
scale-to-zero-grace-period: 30s+stable-window: 60s๏ผๅฎ้ ไปๆๅไธๆฌก่ฏทๆฑๅฐ pod ๅฎๅ จ็ผฉ้ถ็บฆ้ 90-120 ็งใ
Step 6.2: ๆๆฌๅฏนๆฏๆจกๅ
| ๅ ็ด | AWS Lambda | Knative on ROSA (Spot) |
|---|---|---|
| ่ฐ็จๆๆฌ | $0.20/็พไธ่ฏทๆฑ | $0๏ผๅ ๅซๅจ่ฎก็ฎไธญ๏ผ |
| ่ฎก็ฎ (128MB, 1s) | $0.0000021/่ฏทๆฑ | Scale-to-zero = ็ฉบ้ฒๆถ $0 |
| ้ข็ญๆๆฌ | Provisioned Concurrency |minScaleโ=โ0,โ็ฉบ้ฒๆ ๆๆฌ||ๆฐๆฎไผ ่พ|่ทจๆๅก |
้็พคๅ = ๅ ่ดน |
| ๅคไบๅผ้ | N/A๏ผๅไบ๏ผ | ๅไธ้ๅ๏ผๅไธ YAML |
| CI/CD ็ฎก้ๆๆฌ | ๆฏไบ $$ | ไธๆก็ฎก้้้ ๆๆ |
| ่็นๆๆฌ (Spot) | N/A | m6a.xlarge spot ~$0.05/hr |
| ่็น็ฉบ้ฒๆๆฌ | N/A | $0๏ผ่ชๅจ็ผฉๅฎน็งป้ค่็น๏ผ |
ๅ ธๅๆๅบฆๆๆฌไผฐ็ฎ๏ผ50 ไธชๅฝๆฐ๏ผ:
| ๆต้ๅบๆฏ | AWS Lambda | Knative on ROSA (Spot) |
|---|---|---|
| ไฝๆต้๏ผ้ดๆญๆง๏ผ | $200-500 | ~$0๏ผๅ จ้จ็ผฉ้ถ๏ผ |
| ไธญ็ญๆต้ | $500-2000+ | $200-600 |
| ่ทจ 3 ไธชไบ | 3x ๆๆฌ | 1x CI/CD + 3x OCP ่ฎก็ฎ |
ๆณจๆ: ๅฏนไบๆ็ปญ้ซๆต้ๅฝๆฐ๏ผLambda ๅฏ่ฝๆดๅ ทๆๆฌไผๅฟใKnative ๅจ็ชๅ/้ดๆญๆงๅทฅไฝ่ด่ฝฝๅๅคไบๅบๆฏไธญ่กจ็ฐๆดไผใ
Step 6.3: Spot ๅฎไพไธญๆญๅค็
# ไธบๅ
ณ้ฎๅฝๆฐ่ฎพ็ฝฎ PodDisruptionBudget
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: critical-function-pdb
namespace: serverless-demo
spec:
minAvailable: 1
selector:
matchLabels:
serving.knative.dev/service: order-processorๅฏนไบไธ่ฝๅฎนๅฟๅทๅฏๅจ็ๅ
ณ้ฎๅฝๆฐ๏ผ่ฎพ็ฝฎ minScale: "1" ๅนถไฝฟ็จๅ็ฌ็ๆ้ๅฎไพๆบๅจๆฑ ใ
ๅฎๆนๆๆกฃ: Knative Serving ่ชๅจๆฉ็ผฉ
Phase 7: ๅคไบๅฏ็งปๆคๆง้ช่ฏ๏ผ็ฌฌ 7-8 ๅจ๏ผ
Step 7.1: ๅคไบ้จ็ฝฒๆต็จ
ๅไธๅฎนๅจ้ๅ + ๅไธ Knative YAML
โ
โโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โ ROSA (AWS) โ โ ARO (Azure) โ โ OCP ่ช็ฎก็ โ
โโโโโโโโโโโโโโโค โโโโโโโโโโโโโโโค โโโโโโโโโโโโโโโโค
โ Registry: โ โ Registry: โ โ Registry: โ
โ Quay.io/ECR โ โ ACR/Quay.io โ โ Harbor/Quay โ
โโโโโโโโโโโโโโโค โโโโโโโโโโโโโโโค โโโโโโโโโโโโโโโโค
โ Ingress: โ โ Ingress: โ โ Ingress: โ
โ Kourier+NLB โ โ Kourier+ALB โ โ Kourier+LB โ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
ๅฏไธๅทฎๅผ: registry URL, DNS, ่ด่ฝฝๅ่กก็ฑปๅ
(้่ฟ Kustomize overlays ๅค็)
Step 7.2: ๆฏไธชไบ็ๅทฎๅผ๏ผKustomize Overlay๏ผ
# overlays/aro-prod/patches/registry-override.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: FUNCTION_NAME
spec:
template:
spec:
containers:
- name: user-container
image: myregistry.azurecr.io/serverless/FUNCTION_NAME:TAG
# ๅ
ถไปๆๆ้
็ฝฎ๏ผtolerations, nodeSelector, autoscaling,
# env vars, resource limits๏ผไฟๆๅฎๅ
จ็ธๅใPhase 8: Serverless Logic โ ๅทฅไฝๆต็ผๆ๏ผ็ฌฌ 7-9 ๅจ๏ผ
ๅฎขๆทๅ ณๆณจ้็น: ๅฎขๆทๅจ 2024 ๅนดๅทฒ็่ฟๅบ็ก Knative demo๏ผๅ ถๆ ธๅฟ่ฏๆฑๆฏ Serverless Logic (SonataFlow) โ ็จไบๆๅปบๅคๆญฅ้ชคๅทฅไฝๆต๏ผไธไป ไป ๆฏๅไธชๅฝๆฐ่ฐ็จ๏ผ๏ผๆฟไปฃ AWS Step Functionsใ
Step 8.1: SonataFlow ไธ AWS Step Functions ๆฆๅฟตๆ ๅฐ
| AWS Step Functions ๆฆๅฟต | SonataFlow / Serverless Logic ็ญไปท็ฉ |
|---|---|
| State Machine (็ถๆๆบ) | SonataFlow CR (ๅทฅไฝๆตๅฎไน) |
| Amazon States Language (ASL) | CNCF Serverless Workflow Spec (ๅผๆพๆ ๅ) |
| Pass State | Operation State + expression function |
| Choice State | Switch State + dataConditions |
| Task State (Lambda ่ฐ็จ) | Operation State + REST/OpenAPI function |
| Wait State | Sleep State |
| Parallel State | Parallel State (ๅ็ๆฏๆ) |
| Map State | ForEach State |
| Fail State | End State + error handling |
| Activity Task (ไบบๅทฅๅฎกๆน) | Callback State (ๅ ๅปบ) |
| CloudWatch Logs | OpenShift Logging |
| X-Ray Tracing | OpenTelemetry |
| Workflow Studio (ๅฏ่งๅ) | DevUI + SwaggerUI๏ผๅ ๅปบ็ๆง/ๆต่ฏ๏ผ+ VS Code ๆฉๅฑ๏ผๅฏ่งๅ็ผ่พ๏ผ่ง Step 8.7๏ผ |
Step 8.2: ๅฎ่ฃ Serverless Logic Operator
# ๅฎ่ฃ
OpenShift Serverless Logic Operator (GA ็ๆฌ)
# ๆณจๆ: ้ๆฉ logic-operator (GA, stable channel) ่้ logic-operator-rhel8 (Alpha)
cat <<EOF | oc apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: openshift-serverless-logic
---
apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
name: logic-operators
namespace: openshift-serverless-logic
spec: {}
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: logic-operator
namespace: openshift-serverless-logic
spec:
channel: stable
installPlanApproval: Automatic
name: logic-operator
source: redhat-operators
sourceNamespace: openshift-marketplace
EOF
# ้ช่ฏๅฎ่ฃ
๏ผ็บฆ 60 ็ง๏ผ
oc get csv -n openshift-serverless-logic
# ้ขๆ: logic-operator.v1.37.2 ... Succeededๅฎๆต็ปๆ: Logic Operator v1.37.2 (GA) ๅจ็บฆ 60 ็งๅ ๅฎ่ฃ ๆๅ๏ผ่ชๅจๅๅปบ SonataFlow CRDใ
Step 8.3: ๅๅปบ SonataFlowPlatform
cat <<EOF | oc apply -f -
apiVersion: sonataflow.org/v1alpha08
kind: SonataFlowPlatform
metadata:
name: sonataflow-platform
namespace: serverless-demo
spec:
build:
config:
strategyOptions:
KanikoBuildCacheEnabled: "true"
devMode: {}
EOFStep 8.4: ้จ็ฝฒๅทฅไฝๆต โ ่ฎขๅๅค็็คบไพ
ๅทฅไฝๆตๆจกๆๅฎๆด็่ฎขๅๅค็ๆต็จ๏ผๆฅๆถ่ฎขๅ โ ้ช่ฏ โ ๆฏไป โ ๅบๅญๆฃๆฅ โ ๅ่ดง โ ้็ฅๅฎขๆท
ไฝฟ็จ CNCF Serverless Workflow ่ง่ๅฎไน๏ผjq ่กจ่พพๅผๅๆฐๆฎ่ฝฌๆขใ
# ไฝฟ็จ CNCF Serverless Workflow ่ง่ๅฎไนๅคๆญฅ้ชคๅทฅไฝๆต
apiVersion: sonataflow.org/v1alpha08
kind: SonataFlow
metadata:
name: order-processing
namespace: serverless-demo
annotations:
sonataflow.org/description: "Order Processing Workflow - multi-step demo"
sonataflow.org/version: "1.0.0"
sonataflow.org/profile: "dev"
spec:
flow:
start: ReceiveOrder
functions:
- name: validateOrderFunction
type: expression
operation: >-
.order | if .items != null and (.items | length) > 0 and .totalAmount > 0
then {valid: true, message: "Order validated"}
else {valid: false, message: "Invalid order"} end
- name: processPaymentFunction
type: expression
operation: >-
.order | {paymentId: "PAY-" + (.orderId // "unknown"),
status: "approved", method: .paymentMethod, amount: .totalAmount}
- name: checkInventoryFunction
type: expression
operation: >-
.order.items | map({itemId: .id, name: .name, inStock: true,
warehouse: "WH-EAST-1"}) | {inventoryCheck: ., allInStock: true}
- name: shipOrderFunction
type: expression
operation: >-
{shipmentId: "SHIP-" + (.order.orderId // "unknown"),
carrier: "Express", estimatedDays: 3,
trackingUrl: "https://tracking.example.com/SHIP-" + (.order.orderId // "unknown")}
- name: notifyCustomerFunction
type: expression
operation: >-
{notificationId: "NOTIFY-" + (.order.orderId // "unknown"),
channel: "email", recipient: .order.customerEmail,
status: "sent", message: "Your order has been shipped!"}
states:
- name: ReceiveOrder
type: operation
actions:
- functionRef:
refName: validateOrderFunction
actionDataFilter:
results: ".validation"
transition: CheckValidation
- name: CheckValidation
type: switch
dataConditions:
- condition: ".validation.valid == true"
transition: ProcessPayment
- condition: ".validation.valid == false"
end:
terminate: true
defaultCondition:
end:
terminate: true
- name: ProcessPayment
type: operation
actions:
- functionRef:
refName: processPaymentFunction
actionDataFilter:
results: ".payment"
transition: CheckInventory
- name: CheckInventory
type: operation
actions:
- functionRef:
refName: checkInventoryFunction
actionDataFilter:
results: ".inventory"
transition: ShipOrder
- name: ShipOrder
type: operation
actions:
- functionRef:
refName: shipOrderFunction
actionDataFilter:
results: ".shipment"
transition: NotifyCustomer
- name: NotifyCustomer
type: operation
actions:
- functionRef:
refName: notifyCustomerFunction
actionDataFilter:
results: ".notification"
end:
terminate: trueๅฎๆต็ปๆ: ๅทฅไฝๆตๅจ็บฆ 2 ๅ้ๅ ๅฐฑ็ปช๏ผๅซๆๅ devmode ้ๅ๏ผ๏ผ่ชๅจ็ๆ HTTPS ่ทฏ็ฑๅ SwaggerUIใ
# ๅฎๆต่พๅบ
$ oc get sonataflow -n serverless-demo
NAME PROFILE VERSION URL READY REASON
order-processing dev 1.0.0 https://order-processing-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com/order-processing True
$ oc get pods -n serverless-demo -l app=order-processing
NAME READY STATUS RESTARTS AGE
order-processing-fbf46f984-8wsfm 1/1 Running 0 115s
# ๆต่ฏๅทฅไฝๆต โ ๆไบค่ฎขๅ
SONATA_URL="https://order-processing-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com/order-processing"
$ time curl -sk -X POST "$SONATA_URL" \
-H "Content-Type: application/json" \
-d '{"workflowdata":{"order":{"orderId":"ORD-001","customerEmail":"user@example.com",
"paymentMethod":"credit_card","totalAmount":199.99,
"items":[{"id":"ITEM-1","name":"Laptop Stand","qty":1},
{"id":"ITEM-2","name":"USB-C Hub","qty":2}]}}}'
{"id":"3d2f9ddc-60b2-433c-95a6-c2ce1afc750c","workflowdata":{...}}
real 0m0.288s โ ้ฆๆฌก่ฏทๆฑ
# ็ญ่ฏทๆฑ
$ time curl -sk -X POST "$SONATA_URL" \
-H "Content-Type: application/json" \
-d '{"workflowdata":{"order":{"orderId":"ORD-002","customerEmail":"test@example.com",
"paymentMethod":"debit","totalAmount":50.00,
"items":[{"id":"ITEM-3","name":"Mouse","qty":1}]}}}'
{"id":"cbb5a9f1-b307-4fb6-8851-1194c30f460f","workflowdata":{...}}
real 0m0.110s โ ็ญ่ฏทๆฑ ~110ms
# Dev ๅทฅๅ
ท URL๏ผ่ชๅจ็ๆ๏ผ
# SwaggerUI: https://order-processing-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com/q/swagger-ui
# DevUI: https://order-processing-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com/q/dev-uiStep 8.5: ๅฎๆตๅฏนๆฏ โ SonataFlow vs AWS Step Functions
| ๆๆ | AWS Step Functions | SonataFlow on ROSA |
|---|---|---|
| ๅทฅไฝๆตๆง่กๅปถ่ฟ | ~2ms (Express) | ~46ms (็ญ่ฏทๆฑ) |
| ้ฆๆฌก่ฏทๆฑ | ~962ms (ๅซ CLI) | ~220ms |
| ้จ็ฝฒๆนๅผ | aws stepfunctions create-state-machine + IAM |
oc apply ไธไธช YAML |
| ๅทฅไฝๆต่ง่ | ASL (AWS ไธๆ) | CNCF Serverless Workflow (ๅผๆพๆ ๅ) |
| ่กจ่พพๅผ่ฝๅ | JSONPath + ๆ้ intrinsic functions | jq (ๅฎๆดๅ่ฝ๏ผTuring-complete) |
| ๅฏ่งๅๅทฅๅ ท | โ AWS Console Workflow Studio๏ผๆๆฝๅผ๏ผๅ ๅปบ๏ผ | โ ๏ธ DevUI ็ๆง + SwaggerUI ๆต่ฏ๏ผๅ ๅปบ๏ผ๏ผๅฏ่งๅ็ผ่พ้ VS Code ๆฉๅฑ๏ผ่ง Step 8.7๏ผ |
| ๅคไบๅฏ็งปๆค | โ ไป AWS | โ ไปปไฝ OCP ้็พค |
| K8s ๅ็ | โ | โ CRD + operator ๆจกๅผ |
| ไบบๅทฅๅฎกๆน | Activity Task + SQS | ๅ ๅปบ Callback State |
| ๆๆฌๆจกๅ | ๆ็ถๆ่ฝฌๆขๆฌกๆฐ่ฎก่ดน | ๅ ๅซๅจ OCP ่ฎก็ฎไธญ |
| ๅๅ้ๅฎ | ้ซ | ไฝ (CNCF ๆ ๅ) |
Step 8.6: SonataFlow ๅ ณ้ฎไผๅฟ
- ๅผๆพๆ ๅ: ๅบไบ CNCF Serverless Workflow ่ง่๏ผๅทฅไฝๆตๅฎไนๅฏๅจไปปไฝๆฏๆ่ฏฅ่ง่็่ฟ่กๆถๆง่ก
- K8s ๅ็: ๅทฅไฝๆตๅฎไนๅฐฑๆฏ Kubernetes CR๏ผไธ GitOpsใCI/CD ๅฎ็พ้ๆ
- ๅคไบไธ่ด: ๅไธ SonataFlow YAML ๅฏ้จ็ฝฒๅฐ ROSAใAROใOCP on GCP/Ali๏ผๆ ้ไฟฎๆน
- Dev Mode: ๅผๅ้ถๆฎต่ชๅจๆไพ SwaggerUIใDevUI๏ผๆ ้้ขๅค้ ็ฝฎ
- ็ปไธ็ฎก้: ไฝฟ็จไธ Knative Service ็ธๅ็ Tekton + ArgoCD ็ฎก้้จ็ฝฒๅทฅไฝๆต
- jq ่กจ่พพๅผ: ๆฏ ASL ็ JSONPath ๆดๅผบๅคง็ๆฐๆฎ่ฝฌๆข่ฝๅ
ๅฎๆนๆๆกฃ: OpenShift Serverless Logic
Step 8.7: ๅฏ่งๅๅทฅๅ ทๅฏนๆฏ โ SonataFlow vs AWS Step Functions
ๅฎขๆทๅธธ่ง้ฎ้ข: โSonataFlow ไธบไปไนๆฒกๆๅ AWS Step Functions ้ฃๆ ท็ๅฏ่งๅ็ผ่พ็้ข๏ผโ
็ป่ฎบ๏ผ็กฎ่ฎค SonataFlow ๅจ OpenShift Web Console ไธญๆฒกๆๅ ๅปบ็ๅฏ่งๅๅทฅไฝๆต็ผ่พๅจ/ๆฅ็ๅจใ AWS Step Functions ๆฅๆ Workflow Studio๏ผๆๆฝๅผๅฏ่งๅ็ผ่พๅจ๏ผ๏ผ็ดๆฅ้ๆๅจ AWS Console ไธญ๏ผSonataFlow ็ๅฏ่งๅๅทฅๅ ทๆฏๅค็ฝฎ็๏ผVS Code ๆฉๅฑใWeb Tools๏ผ๏ผไธๅจ OCP Console ๅ ใ่ฟๆฏ SonataFlow ๅจ UX ๆน้ข็ไธไธชๅผฑ็นใ
SonataFlow ๅฏ่งๅๅทฅๅ ทๆป่ง๏ผ3 ไธชๅฑ็บง๏ผ๏ผ
| ๅฑ็บง | ๅทฅๅ ทๅ็งฐ | ้ๆไฝ็ฝฎ | ่ฝๅ |
|---|---|---|---|
| 1. DevUI | Quarkus DevUI (/q/dev-ui) |
SonataFlow Pod ๅ ๅปบ | ๅทฅไฝๆตๅฎไพ็ๆงใ่งฆๅใ็ถๆ่ฟฝ่ธช |
| 2. VS Code ๆฉๅฑ | KIE Serverless Workflow Editor | VS Code / OpenShift Dev Spaces | ไปฃ็ ็ผ่พ + ๅทฅไฝๆตๅพ่กจ้ข่ง๏ผๅนถๆๆพ็คบ๏ผ |
| 3. Web Tools | Serverless Logic Web Tools | ็ฌ็ซๆต่งๅจๅบ็จ | ๅจ็บฟๅฏ่งๅ็ผ่พๅจ๏ผๅฏ่ฟๆฅ OpenShift |
ๆณจๆ: ไปฅไธ 3 ไธชๅทฅๅ ท้ฝไธๆฏ OCP Web Console ็ไธ้จๅใ
่ฏฆ็ปๅฏนๆฏ๏ผ
| ็ปดๅบฆ | AWS Step Functions | SonataFlow |
|---|---|---|
| Console ๅ ๅปบๅฏ่งๅ | โ Workflow Studio๏ผๆๆฝๅผ็ผ่พๅจ๏ผ | โ OCP Web Console ๆ ๅทฅไฝๆตๅฏ่งๅ |
| ๅทฅไฝๆตๅพ่กจๅฎๆถๆธฒๆ | โ Console ๅฎๆถๆพ็คบๆง่กๆต็จ | โ ๏ธ ไป VS Code ๆฉๅฑ / Web Tools ๆไพ |
| ๆง่กๅฎไพ็ๆง | โ Console ๆฅ็ๆญฅ้ชคๅ่พๅ ฅ/่พๅบ | โ
DevUI (/q/dev-ui) ๆไพ |
| ๆๆฝๅผ็ผ่พๅจ | โ Workflow Studio | โ ไปฃ็ ็ผ่พ + ๅพ่กจ้ข่ง |
| SwaggerUI | โ ๆ | โ
ๅ
ๅปบ (/q/swagger-ui) |
| ็ฆป็บฟ่ฎพ่ฎก | โ ้ AWS Console ๅจ็บฟ | โ VS Code ๆฉๅฑๅฎๅ จ็ฆป็บฟๅฏ็จ |
| GitOps ๅๅฅฝ | โ ๏ธ Console ็ผ่พไธ่ตฐ Git | โ YAML CRD + Git ็ๆฌๆงๅถ |
ๅฎๆต้ช่ฏ โ DevUI/SwaggerUI URL๏ผๅฏ็ดๆฅ่ฎฟ้ฎ๏ผ๏ผ
DevUI: https://order-processing-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com/q/dev-ui/
SwaggerUI: https://order-processing-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com/q/swagger-ui/
ๅปบ่ฎฎ๏ผ
- ๅผๅ้ถๆฎต โ ๅฎ่ฃ
VS Code ๆฉๅฑ
KIE Serverless Workflow Editor๏ผไปฃ็ + ๅพ่กจๅนถๆ๏ผๆฏๆ่ชๅจ่กฅๅ จใ้ช่ฏใSVG ๅฏผๅบ๏ผ - ่ฐ่ฏ/็ๆง โ ไฝฟ็จ DevUI (
/q/dev-ui)๏ผๆฅ็ๅทฅไฝๆตๅฎไพๅๆง่ก็ถๆ๏ผ - API ๆต่ฏ โ ไฝฟ็จ SwaggerUI (
/q/swagger-ui)๏ผๆต่งๅจ็ดๆฅๆต่ฏ REST API๏ผ - ๅข้ๅไฝ โ ไฝฟ็จ Serverless Logic Web Tools๏ผๆต่งๅจๅจ็บฟ็ผ่พ๏ผๅฏ่ฟๆฅ OCP ้็พค้จ็ฝฒ๏ผ
่ฎพ่ฎก็ๅฟตๅทฎๅผ: AWS ไพง้ Console-first๏ผๅพๅฝข็้ขไผๅ ๏ผ๏ผSonataFlow ไพง้ Code-first๏ผไปฃ็ ไผๅ + GitOps๏ผใ
ๅฏนไบๅคงๅ้่ไผไธ็ GitOps ๅทฅไฝๆต๏ผCode-first ๆจกๅผๅ่ๆด็ฌฆๅ็ไบง็ฏๅขๆไฝณๅฎ่ทต โโ ๆๆๅทฅไฝๆตๅๆด้่ฟ Git PR ๅฎกๆน๏ผ
่้ๅจ Console ไธญๆๅจๆๆฝไฟฎๆนใ
Phase 9: ่ฟ็ปดๆๅ๏ผ็ฌฌ 9-10 ๅจ๏ผ
Step 9.1: ็ๆงไธๅฏ่งๆตๆง
# ๅ
ณ้ฎ็ๆงๆๆ ๏ผ้่ฟ OpenShift Monitoring / Prometheus ่ทๅ๏ผ
# 1. ๆฏไธชๅฝๆฐ็่ฏทๆฑๅปถ่ฟ (P95)
histogram_quantile(0.95,
sum(rate(revision_request_latencies_bucket[5m])) by (le, service_name))
# 2. ๆฏไธชๅฝๆฐ็่ฏทๆฑๆฐ
sum(rate(revision_request_count[5m])) by (service_name)
# 3. ๆดป่ท pod ๆฐ้๏ผ้ช่ฏ scale-to-zero ๆฏๅฆๅทฅไฝ๏ผ
sum(autoscaler_actual_pods) by (service_name)
# 4. ๅทๅฏๅจๅปถ่ฟ (P95)
histogram_quantile(0.95,
sum(rate(activator_request_latencies_bucket{cold_start="true"}[5m])) by (le))Step 9.2: ๅธธ็จ่ฟ็ปดๆไฝ
# ๅๅบๆๆ Knative Services
$ oc get ksvc -n serverless-demo
NAME URL LATESTCREATED LATESTREADY READY
hello-function https://hello-function-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com hello-function-00001 hello-function-00001 True
hello-func https://hello-func-serverless-demo.apps.rosa.rosa-fhmhp.r63a.p3.openshiftapps.com hello-func-00001 hello-func-00001 True
# ๆฅ็ Revisions๏ผ็ๆฌๅๅฒ๏ผ
$ oc get revisions -n serverless-demo
NAME CONFIG NAME GENERATION READY ACTUAL REPLICAS DESIRED REPLICAS
hello-function-00001 hello-function 1 True 0 0
hello-func-00001 hello-func 1 True 1 1
# ๆฅ็ๆๆ Serverless ่ตๆบๆฆ่ง
$ oc get ksvc,revisions,pingsource,sonataflow -n serverless-demo
NAME URL LATESTCREATED READY
service.serving.knative.dev/hello-function https://hello-func... hello-function-00001 True
service.serving.knative.dev/hello-func https://hello-func... hello-func-00001 True
NAME CONFIG NAME READY ACTUAL REPLICAS
revision.serving.knative.dev/hello-function-00001 hello-function True 0
revision.serving.knative.dev/hello-func-00001 hello-func True 1
NAME SINK SCHEDULE READY
pingsource.sources.knative.dev/demo-ping http://hello-function... */1 * * * * True
NAME PROFILE VERSION READY
sonataflow.sonataflow.org/order-processing dev 1.0.0 True
# ๆดๆฐๅฝๆฐ๏ผๅๅปบๆฐ revision๏ผ
oc set image ksvc/hello-function \
user-container=<registry>/hello-function:v2 \
-n serverless-demo
# ้ไธ้ๅๅธ๏ผ90/10 ๆต้ๅๅฒ๏ผ
oc patch ksvc hello-function -n serverless-demo --type merge -p '
spec:
traffic:
- revisionName: hello-function-00001
percent: 90
- revisionName: hello-function-00002
percent: 10
'
# ๅๆปๅฐไนๅ็ revision
oc patch ksvc hello-function -n serverless-demo --type merge -p '
spec:
traffic:
- revisionName: hello-function-00001
percent: 100
'
# ๅผบๅถ้ข็ญ๏ผ้ฟๅ
ๅทๅฏๅจ๏ผ
oc annotate ksvc hello-function \
autoscaling.knative.dev/min-scale=1 \
-n serverless-demo --overwriteStep 9.3: ๆ ้ๆๆฅ
# ๆฃๆฅ Knative Serving ็ปไปถ็ถๆ
$ oc get knativeserving -n knative-serving
NAME VERSION READY REASON
knative-serving 1.17 True
# ๆฃๆฅ Serverless ๅบ็ก็ปไปถ pod ็ถๆ
$ oc get pods -n knative-serving
NAME READY STATUS AGE
activator-76c876897-74jlb 2/2 Running 4h
autoscaler-5cf6d5d889-nrf8w 2/2 Running 4h
controller-656bffbb85-kqbnk 2/2 Running 4h
webhook-5fd78f67b4-qs5fk 2/2 Running 4h
...
# ๆฃๆฅ Ingress Gateway
$ oc get pods -n knative-serving-ingress
NAME READY STATUS AGE
3scale-kourier-gateway-7cf56975cd-qg6zp 1/1 Running 4h
net-kourier-controller-7bfd97bb65-7bkpl 1/1 Running 4h
# ๆฅ็ๅฝๆฐ็ไบไปถ๏ผๆๆฅๅฏๅจ้ฎ้ข๏ผ
$ oc get events -n serverless-demo --sort-by='.lastTimestamp' | tail -10
# ๆฅ็ Knative Service ็ conditions
$ oc get ksvc hello-func -n serverless-demo -o jsonpath='{range .status.conditions[*]}{.type}={.status} {.message}{"\n"}{end}'
ConfigurationsReady=True
Ready=True
RoutesReady=True3. ๅฎๆนๆๆกฃๅ่
| ไธป้ข | ้พๆฅ |
|---|---|
| OpenShift Serverless ๆฆ่ง | https://docs.redhat.com/en/documentation/red_hat_openshift_serverless/1.37 |
| ๅฎ่ฃ OpenShift Serverless | https://docs.redhat.com/en/documentation/red_hat_openshift_serverless/1.37/html/installing_openshift_serverless/install-serverless-operator |
| Knative Serving | https://docs.redhat.com/en/documentation/red_hat_openshift_serverless/1.37/html/serving/index |
| Knative Serving ่ชๅจๆฉ็ผฉ | https://docs.redhat.com/en/documentation/red_hat_openshift_serverless/1.37/html/serving/autoscaling |
| Knative Eventing | https://docs.redhat.com/en/documentation/red_hat_openshift_serverless/1.37/html/eventing/index |
| Knative Functions (kn func) | https://docs.redhat.com/en/documentation/red_hat_openshift_serverless/1.37/html/functions/serverless-functions-setup |
| OpenShift Pipelines (Tekton) | https://docs.redhat.com/en/documentation/red_hat_openshift_pipelines/1.17 |
| OpenShift GitOps (ArgoCD) | https://docs.redhat.com/en/documentation/red_hat_openshift_gitops/1.15 |
| ROSA ๆบๅจๆฑ | https://docs.redhat.com/en/documentation/red_hat_openshift_service_on_aws/4/html/cluster_administration/managing-compute-nodes |
| ROSA Spot ๅฎไพ | https://docs.redhat.com/en/documentation/red_hat_openshift_service_on_aws/4/html/cluster_administration/managing-compute-nodes#rosa-creating-a-machine-pool-with-spot-instances |
| ้็พค่ชๅจ็ผฉๅฎน | https://docs.redhat.com/en/documentation/red_hat_openshift_service_on_aws/4/html/cluster_administration/cluster-autoscaling |
| Knative ไธๆธธๆๆกฃ | https://knative.dev/docs/ |
4. ๆถ้ด็บฟๆป็ป
Week 1-2 โโโโโโโโโโโโโโโโโโโโโโ Phase 1: ๅฎ่ฃ
Serverless Operator
Week 2-3 โโโโโโโโโโโโโโโโโโโโโโ Phase 2: ไธ็จๆบๅจๆฑ ้
็ฝฎ
Week 3-5 โโโโโโโโโโโโโโโโโโโโโโ Phase 3: Lambda ่ฟ็งป (2-3 ไธช่ฏ็น)
Week 4-6 โโโโโโโโโโโโโโโโโโโโโโ Phase 4: ็ปไธ CI/CD ็ฎก้
Week 5-7 โโโโโโโโโโโโโโโโโโโโโโ Phase 5: ไบไปถๆบ้ๆ
Week 6-7 โโโโโโโโโโโโโโโโโโโโโโ Phase 6: ๆๆฌไผๅ่ฐไผ
Week 7-8 โโโโโโโโโโโโโโโโโโโโโโ Phase 7: ๅคไบ้ช่ฏ
Week 8 โโโโโโโโโโโโโโโโโโโโโโ Phase 8: ่ฟ็ปดๆๅไบคไป
้ข่ฎกๆปๅทฅๆ: 6-8 ๅจ
5. ๆๅๆ ๅ
| ๆ ๅ | ่กก้ๆนๅผ |
|---|---|
| ็ปไธ CI/CD | ไธๆก Tekton Pipeline ๅฏ้จ็ฝฒๅฐๆๆ็ฎๆ ไบ |
| Scale-to-Zero ๅทฅไฝ | Pod ๆฐ้่ณ 0๏ผ่็น่ขซ็งป้ค๏ผๅทฒ้ช่ฏ โ ๏ผ |
| ๆๆฌ้ไฝ | ็ธๆฏ็ญไปท Lambda ๆๆฌ้ไฝ โฅ30%๏ผๆๆๅบฆๆต้๏ผ |
| ๅทๅฏๅจ < 10s | P95 ๅทๅฏๅจๅปถ่ฟๅจ 10 ็งไปฅๅ ๏ผๅฎๆต ~1.67s โ ๏ผ |
| ๅคไบๅฏ็งปๆค | ๅไธๅฝๆฐ้ๅ + YAML ๅฏ้จ็ฝฒๅฐ ROSA ๅ ARO |
| ่ฟ็งป่ฆ็ | โฅ3 ไธช Lambda ๅฝๆฐๅฎๆๆฆๅฟต้ช่ฏ่ฟ็งป |
| ่ฟ็ปดๅฐฑ็ปช | ็ๆงไปช่กจๆฟใๅ่ญฆ่งๅใ่ฟ็ปดๆๅไบคไป |