
Knative
- 95 installs
- 6 repo stars
- Updated July 22, 2026
- julianobarbosa/claude-code-skills
Manage Kubernetes clusters, deployments, and cloud-native orchestration.
About
Knative serverless platform for Kubernetes. Use when deploying serverless workloads, configuring autoscaling with scale-to-zero, event-driven architectures.
- Wants to deploy serverless workloads on Kubernetes
- Needs scale-to-zero autoscaling capabilities
Knative by the numbers
- 95 all-time installs (skills.sh)
- +1 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #569 of 1,039 Cloud & Infrastructure skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/julianobarbosa/claude-code-skills --skill knativeAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 95 |
|---|---|
| repo stars | ★ 6 |
| Last updated | July 22, 2026 |
| Repository | julianobarbosa/claude-code-skills ↗ |
What it does
Manage Kubernetes clusters, deployments, and cloud-native orchestration.
Files
Knative Skill
Overview
Knative is an open-source Kubernetes-based platform for deploying and managing serverless workloads. It provides three main components:
| Component | Purpose | Key Features |
|---|---|---|
| Serving | HTTP-triggered autoscaling runtime | Scale-to-zero, traffic splitting, revisions |
| Eventing | Event-driven architectures | Brokers, Triggers, Sources, CloudEvents |
| Functions | Simplified function deployment | func CLI, multi-language support |
Current Version: v1.20.0 (as of late 2024)
When to Use This Skill
Use this skill when the user:
- Wants to deploy serverless workloads on Kubernetes
- Needs scale-to-zero autoscaling capabilities
- Is implementing event-driven architectures
- Needs traffic management (blue-green, canary, gradual rollout)
- Works with CloudEvents or event routing
- Mentions Knative Serving, Eventing, or Functions
- Asks about Brokers, Triggers, Sources, or Sinks
- Needs to configure networking layers (Kourier, Istio, Contour)
Quick Reference
Knative Service (Serving)
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: my-service
namespace: default
spec:
template:
metadata:
annotations:
# Autoscaling configuration
autoscaling.knative.dev/class: kpa.autoscaling.knative.dev
autoscaling.knative.dev/min-scale: "0"
autoscaling.knative.dev/max-scale: "10"
autoscaling.knative.dev/target: "100" # concurrent requests
spec:
containers:
- image: gcr.io/my-project/my-app:latest
ports:
- containerPort: 8080
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 128Mi # Memory limit = request (required)
# NO CPU limits (causes throttling)Traffic Splitting
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: my-service
spec:
template:
# ... container spec
traffic:
# Blue-green: 100% to new or old
- revisionName: my-service-00001
percent: 90
- revisionName: my-service-00002
percent: 10
# Or use latestRevision
- latestRevision: true
percent: 100Tagged Revisions (Preview URLs)
traffic:
- revisionName: my-service-00002
percent: 0
tag: staging # Accessible at staging-my-service.example.com
- latestRevision: true
percent: 100
tag: productionBroker and Trigger (Eventing)
# Create a Broker
apiVersion: eventing.knative.dev/v1
kind: Broker
metadata:
name: default
namespace: default
---
# Create a Trigger to route events
apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
name: my-trigger
namespace: default
spec:
broker: default
filter:
attributes:
type: dev.knative.example
source: /my/source
subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: my-serviceEvent Source Example (PingSource)
apiVersion: sources.knative.dev/v1
kind: PingSource
metadata:
name: cron-job
spec:
schedule: "*/1 * * * *" # Every minute
contentType: application/json
data: '{"message": "Hello from cron"}'
sink:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: event-displayInstallation
Prerequisites
- Kubernetes cluster v1.28+
kubectlconfigured- Cluster admin permissions
Method 1: YAML Install (Recommended for GitOps)
# Install Knative Serving CRDs and Core
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.20.0/serving-crds.yaml
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.20.0/serving-core.yaml
# Install Networking Layer (choose one)
# Option A: Kourier (lightweight, recommended for most cases)
kubectl apply -f https://github.com/knative/net-kourier/releases/download/knative-v1.20.0/kourier.yaml
kubectl patch configmap/config-network \
--namespace knative-serving \
--type merge \
--patch '{"data":{"ingress-class":"kourier.ingress.networking.knative.dev"}}'
# Option B: Istio (for service mesh requirements)
kubectl apply -f https://github.com/knative/net-istio/releases/download/knative-v1.20.0/net-istio.yaml
# Install Knative Eventing
kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.20.0/eventing-crds.yaml
kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.20.0/eventing-core.yaml
# Install In-Memory Channel (dev only) or Kafka Channel (production)
kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.20.0/in-memory-channel.yaml
# Install MT-Channel-Based Broker
kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.20.0/mt-channel-broker.yamlMethod 2: Knative Operator
# Install the Operator
kubectl apply -f https://github.com/knative/operator/releases/download/knative-v1.20.0/operator.yaml
# Deploy Knative Serving
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
---
# Deploy Knative Eventing
apiVersion: operator.knative.dev/v1beta1
kind: KnativeEventing
metadata:
name: knative-eventing
namespace: knative-eventingConfigure DNS
# Get the External IP of the ingress
kubectl get svc kourier -n kourier-system
# Option A: Real DNS (production)
# Create A record: *.knative.example.com -> EXTERNAL-IP
# Option B: Magic DNS with sslip.io (development)
kubectl patch configmap/config-domain \
--namespace knative-serving \
--type merge \
--patch '{"data":{"<EXTERNAL-IP>.sslip.io":""}}'
# Option C: Default domain (internal only)
kubectl patch configmap/config-domain \
--namespace knative-serving \
--type merge \
--patch '{"data":{"example.com":""}}'Autoscaling
Autoscaler Classes
| Class | Key | Scale to Zero | Metrics |
|---|---|---|---|
| KPA (default) | kpa.autoscaling.knative.dev | Yes | Concurrency, RPS |
| HPA | hpa.autoscaling.knative.dev | No | CPU, Memory |
Autoscaling Annotations
metadata:
annotations:
# Autoscaler class
autoscaling.knative.dev/class: kpa.autoscaling.knative.dev
# Scale bounds
autoscaling.knative.dev/min-scale: "1" # Prevent scale-to-zero
autoscaling.knative.dev/max-scale: "100"
autoscaling.knative.dev/initial-scale: "3"
# Scaling metric (KPA)
autoscaling.knative.dev/metric: concurrency # or rps
autoscaling.knative.dev/target: "100" # target per pod
# Scale-down behavior
autoscaling.knative.dev/scale-down-delay: "5m"
autoscaling.knative.dev/scale-to-zero-pod-retention-period: "1m"
# Window for averaging metrics
autoscaling.knative.dev/window: "60s"Concurrency Limits
spec:
template:
spec:
containerConcurrency: 100 # Hard limit per pod (0 = unlimited)Networking
Networking Layer Comparison
| Layer | Pros | Cons | Use Case |
|---|---|---|---|
| Kourier | Lightweight, fast, simple | Limited features | Most deployments |
| Istio | Full service mesh, mTLS | Heavy, complex | Enterprise, security-critical |
| Contour | Envoy-based, good performance | Medium complexity | High-traffic apps |
TLS Configuration
# Using cert-manager (recommended)
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: my-service
annotations:
# Auto-TLS with cert-manager
networking.knative.dev/certificate-class: cert-manager
spec:
# ... template specCustom Domain Mapping
apiVersion: serving.knative.dev/v1beta1
kind: DomainMapping
metadata:
name: api.example.com
namespace: default
spec:
ref:
kind: Service
name: my-service
apiVersion: serving.knative.dev/v1Eventing Patterns
Event Source Types
| Source | Description | Use Case |
|---|---|---|
| PingSource | Cron-based events | Scheduled tasks |
| ApiServerSource | K8s API events | Cluster monitoring |
| KafkaSource | Kafka messages | Stream processing |
| GitHubSource | GitHub webhooks | CI/CD triggers |
| ContainerSource | Custom container | Any external system |
Channel Types
| Channel | Persistence | Use Case |
|---|---|---|
| InMemoryChannel | No | Development only |
| KafkaChannel | Yes | Production |
| NATSChannel | Configurable | High throughput |
Sequence (Chained Processing)
apiVersion: flows.knative.dev/v1
kind: Sequence
metadata:
name: my-sequence
spec:
channelTemplate:
apiVersion: messaging.knative.dev/v1
kind: InMemoryChannel
steps:
- ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: step-1
- ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: step-2
reply:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: final-handlerParallel (Fan-out)
apiVersion: flows.knative.dev/v1
kind: Parallel
metadata:
name: my-parallel
spec:
channelTemplate:
apiVersion: messaging.knative.dev/v1
kind: InMemoryChannel
branches:
- subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: handler-a
- subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: handler-bKnative Functions
CLI Installation
# macOS
brew install knative/client/func
# Linux
curl -sL https://github.com/knative/func/releases/latest/download/func_linux_amd64 -o func
chmod +x func && sudo mv func /usr/local/bin/Function Lifecycle
# Create a new function
func create -l python my-function
cd my-function
# Build the function
func build
# Deploy to cluster
func deploy
# Invoke locally
func invoke
# Invoke remote
func invoke --target=remoteSupported Languages
| Language | Template | Runtime |
|---|---|---|
| Go | go | Native binary |
| Node.js | node | Node.js 18+ |
| Python | python | Python 3.9+ |
| Quarkus | quarkus | GraalVM/JVM |
| Rust | rust | Native binary |
| TypeScript | typescript | Node.js |
Function Configuration (func.yaml)
specVersion: 0.36.0
name: my-function
runtime: python
registry: docker.io/myuser
image: docker.io/myuser/my-function:latest
build:
builder: pack
buildpacks:
- paketo-buildpacks/python
deploy:
namespace: default
annotations:
autoscaling.knative.dev/min-scale: "1"
env:
- name: MY_VAR
value: my-value
volumes:
- secret: my-secret
path: /secretsBest Practices
Resource Configuration
| Resource | Requirement | Notes |
|---|---|---|
| CPU requests | Required | Set based on actual usage |
| CPU limits | FORBIDDEN | Causes throttling |
| Memory requests | Required | Match your app needs |
| Memory limits | Required | Must equal requests |
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 128Mi # Same as request
# NO cpu limit!Probes Configuration
spec:
containers:
- image: my-app
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
# Liveness probe optional for serverless
# (Knative handles pod lifecycle)Cold Start Optimization
1. Keep minimum replicas: Set min-scale: "1" for latency-critical services 2. Optimize container image: Use distroless/alpine base images 3. Lazy initialization: Defer heavy initialization until first request 4. Connection pooling: Pre-warm database connections
Production Checklist
- [ ] Use KafkaChannel instead of InMemoryChannel
- [ ] Configure proper resource requests/limits
- [ ] Set up TLS with cert-manager
- [ ] Configure custom domain
- [ ] Set appropriate min/max scale values
- [ ] Enable dead letter sink for Triggers
- [ ] Configure monitoring (Prometheus metrics)
- [ ] Set up proper RBAC
Troubleshooting
Common Issues
| Symptom | Cause | Solution |
|---|---|---|
| Service not accessible | DNS not configured | Configure domain mapping or use sslip.io |
| Pods not scaling up | Activator overloaded | Increase activator replicas |
| Slow cold starts | Large image or slow init | Optimize image, use min-scale: "1" |
| Events not delivered | Broker misconfigured | Check Broker/Trigger status |
| 503 errors | Service scaling | Check activator logs, increase scale |
| Certificate errors | cert-manager issue | Check ClusterIssuer and Certificate status |
Diagnostic Commands
# Check Knative Serving status
kubectl get ksvc -A
kubectl describe ksvc <service-name>
# Check revisions
kubectl get revisions -A
kubectl describe revision <revision-name>
# Check routes
kubectl get routes -A
# Check Knative Eventing status
kubectl get brokers -A
kubectl get triggers -A
kubectl get sources -A
# Check event delivery
kubectl get subscriptions -A
# View activator logs
kubectl logs -n knative-serving -l app=activator -c activator
# View controller logs
kubectl logs -n knative-serving -l app=controller
# Check networking layer (Kourier)
kubectl logs -n kourier-system -l app=3scale-kourier-gatewayDebug Event Flow
# Deploy event-display service for debugging
kubectl apply -f - <<EOF
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: event-display
spec:
template:
spec:
containers:
- image: gcr.io/knative-releases/knative.dev/eventing/cmd/event_display
EOF
# Create a trigger to route all events
kubectl apply -f - <<EOF
apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
name: debug-trigger
spec:
broker: default
subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: event-display
EOF
# Watch events
kubectl logs -l serving.knative.dev/service=event-display -c user-container -fIntegration with ArgoCD
ApplicationSet for Knative Services
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: knative-services
spec:
generators:
- git:
repoURL: https://github.com/org/repo.git
revision: HEAD
directories:
- path: knative-services/*
template:
metadata:
name: '{{path.basename}}'
annotations:
# Disable SSA if using Jobs
argocd.argoproj.io/compare-options: ServerSideDiff=false
spec:
project: default
source:
repoURL: https://github.com/org/repo.git
targetRevision: HEAD
path: '{{path}}'
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: trueHealth Checks for Knative Resources
ArgoCD automatically recognizes Knative resources. Custom health checks:
# In argocd-cm ConfigMap
data:
resource.customizations.health.serving.knative.dev_Service: |
hs = {}
if obj.status ~= nil then
if obj.status.conditions ~= nil then
for _, condition in ipairs(obj.status.conditions) do
if condition.type == "Ready" and condition.status == "True" then
hs.status = "Healthy"
hs.message = "Service is ready"
return hs
end
end
end
end
hs.status = "Progressing"
hs.message = "Waiting for service to be ready"
return hsReferences
- Official Documentation
- Knative Serving API
- Knative Eventing API
- Knative Functions
- GitHub Repository
- Detailed Reference
---
Gotchas
- `min-scale: "0"` saves money but cold-start hits the first request — sometimes 3-10s for JVM/Python apps. Health probes hitting the public URL accidentally keep the pod warm; removing them surfaces the cold-start the user always had.
- `containerConcurrency: 0` (unlimited) breaks KPA autoscaling because the autoscaler has no concurrency target to scale against. Always set an explicit value; the default 0 silently disables proper scaling.
- Knative Service `spec.template.metadata.name` is immutable once set — changing it doesn't create a new revision, it fails the apply. Omit the name and let Knative generate
-00001,-00002, etc. - `ServerSideDiff=false` annotation is required on ArgoCD apps deploying Knative Services because ArgoCD's schema doesn't recognize Knative status fields. Without it, syncs fail with
field not declared in schemaeven when manifests are valid. - InMemoryChannel loses events on broker pod restart — fine for dev, catastrophic for prod. Symptom: triggers report
Ready=Truebut events sporadically vanish. Always use KafkaChannel or NATSChannel in production. - CPU limits cause request latency spikes during scale-from-zero because the activator throttles. Match the cluster policy: requests only, no CPU limits.
- Tagged revisions with `percent: 0` still receive traffic on the
<tag>-<service>subdomain, even if the main route shows 0%. Don't assume tag=0 means "no traffic".
Knative Detailed Reference
API Reference
Serving API (serving.knative.dev/v1)
Service
The primary resource for deploying serverless workloads.
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: string # Required: Unique name
namespace: string # Optional: defaults to 'default'
labels: {} # Optional: Key-value labels
annotations: # Optional: Key-value annotations
# Common annotations
serving.knative.dev/creator: string
serving.knative.dev/lastModifier: string
spec:
template: # Required: PodTemplateSpec
metadata:
name: string # Optional: Revision name (auto-generated if omitted)
annotations: # Autoscaling and other annotations
autoscaling.knative.dev/class: string
autoscaling.knative.dev/metric: string
autoscaling.knative.dev/target: string
autoscaling.knative.dev/min-scale: string
autoscaling.knative.dev/max-scale: string
spec:
serviceAccountName: string # Optional: Service account
containerConcurrency: int # Optional: Hard concurrency limit (0=unlimited)
timeoutSeconds: int # Optional: Request timeout (default: 300)
containers: # Required: Container specs
- name: string
image: string # Required: Container image
imagePullPolicy: string # Optional: Always/IfNotPresent/Never
command: [] # Optional: Entrypoint
args: [] # Optional: Arguments
env: [] # Optional: Environment variables
envFrom: [] # Optional: Environment from ConfigMap/Secret
ports: # Optional: Container ports
- name: string # Optional: h2c or http1
containerPort: int # Required: Port number
protocol: string # Optional: TCP (default)
resources: # Recommended: Resource requirements
requests:
cpu: string
memory: string
limits:
memory: string # CPU limits NOT recommended
readinessProbe: {} # Optional: Readiness probe
livenessProbe: {} # Optional: Liveness probe
volumeMounts: [] # Optional: Volume mounts
volumes: [] # Optional: Volumes
traffic: # Optional: Traffic routing
- revisionName: string # Route to specific revision
latestRevision: bool # Or route to latest
percent: int # Traffic percentage (0-100)
tag: string # Optional: Named tag for URLConfiguration
Manages revision history (typically managed through Service).
apiVersion: serving.knative.dev/v1
kind: Configuration
metadata:
name: string
spec:
template: # Same as Service.spec.template
# ...Revision
Immutable snapshot of code and configuration (auto-created).
apiVersion: serving.knative.dev/v1
kind: Revision
metadata:
name: string # Auto-generated: {service}-{random}
labels:
serving.knative.dev/service: string
serving.knative.dev/configuration: string
spec:
# Inherited from Configuration/Service templateRoute
Manages traffic routing to Revisions.
apiVersion: serving.knative.dev/v1
kind: Route
metadata:
name: string
spec:
traffic:
- revisionName: string
percent: int
tag: stringEventing API (eventing.knative.dev/v1)
Broker
Event routing hub.
apiVersion: eventing.knative.dev/v1
kind: Broker
metadata:
name: string
namespace: string
annotations:
eventing.knative.dev/broker.class: string # MTChannelBasedBroker, Kafka, etc.
spec:
config: # Optional: Broker configuration
apiVersion: string
kind: string
name: string
namespace: string
delivery: # Optional: Delivery options
deadLetterSink: # Dead letter queue
ref:
apiVersion: string
kind: string
name: string
retry: int # Retry count
backoffPolicy: string # linear or exponential
backoffDelay: string # Duration (e.g., PT1S)Trigger
Event subscription with filtering.
apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
name: string
namespace: string
spec:
broker: string # Required: Broker name
filter: # Optional: Event filtering
attributes: # CloudEvent attributes
type: string # Event type filter
source: string # Event source filter
subject: string # Event subject filter
# Any CloudEvent extension attribute
subscriber: # Required: Event destination
ref: # Reference to Kubernetes resource
apiVersion: string
kind: string
name: string
namespace: string # Optional: defaults to Trigger namespace
uri: string # Alternative: Direct URI
delivery: # Optional: Per-trigger delivery options
deadLetterSink: {}
retry: int
backoffPolicy: string
backoffDelay: stringSources API (sources.knative.dev/v1)
PingSource
Cron-scheduled event producer.
apiVersion: sources.knative.dev/v1
kind: PingSource
metadata:
name: string
spec:
schedule: string # Required: Cron expression
timezone: string # Optional: Timezone (default: UTC)
contentType: string # Optional: application/json, text/plain
data: string # Optional: Event payload
dataBase64: string # Optional: Base64-encoded payload
sink: # Required: Event destination
ref:
apiVersion: string
kind: string
name: string
uri: string # Alternative: Direct URIApiServerSource
Kubernetes API event producer.
apiVersion: sources.knative.dev/v1
kind: ApiServerSource
metadata:
name: string
spec:
mode: string # Reference or Resource
resources: # Required: Resources to watch
- apiVersion: string
kind: string
serviceAccountName: string # Required: SA with RBAC permissions
sink:
ref:
apiVersion: string
kind: string
name: stringContainerSource
Custom container event producer.
apiVersion: sources.knative.dev/v1
kind: ContainerSource
metadata:
name: string
spec:
template: # Required: Pod template
spec:
containers:
- image: string
name: string
env:
- name: K_SINK # Injected by Knative
value: string
sink:
ref:
apiVersion: string
kind: string
name: stringFlows API (flows.knative.dev/v1)
Sequence
Serial event processing pipeline.
apiVersion: flows.knative.dev/v1
kind: Sequence
metadata:
name: string
spec:
channelTemplate: # Required: Channel type
apiVersion: messaging.knative.dev/v1
kind: InMemoryChannel # Or KafkaChannel
steps: # Required: Processing steps
- ref:
apiVersion: string
kind: string
name: string
uri: string # Alternative to ref
delivery: {} # Optional: Per-step delivery
reply: # Optional: Final destination
ref:
apiVersion: string
kind: string
name: stringParallel
Fan-out event processing.
apiVersion: flows.knative.dev/v1
kind: Parallel
metadata:
name: string
spec:
channelTemplate:
apiVersion: messaging.knative.dev/v1
kind: InMemoryChannel
branches: # Required: Parallel branches
- filter: # Optional: Branch filter
ref:
apiVersion: string
kind: string
name: string
subscriber: # Required: Branch processor
ref:
apiVersion: string
kind: string
name: string
reply: # Optional: Branch reply destination
ref:
apiVersion: string
kind: string
name: string
reply: # Optional: Aggregated reply destination
ref:
apiVersion: string
kind: string
name: stringConfigMaps Reference
config-autoscaler (knative-serving)
apiVersion: v1
kind: ConfigMap
metadata:
name: config-autoscaler
namespace: knative-serving
data:
# Container concurrency target default
container-concurrency-target-default: "100"
# Target utilization (0.0-1.0)
target-utilization-percentage: "70"
# Scale bounds
enable-scale-to-zero: "true"
scale-to-zero-grace-period: "30s"
scale-to-zero-pod-retention-period: "0s"
# Scaling rates
max-scale-up-rate: "1000"
max-scale-down-rate: "2"
# Stable window for metrics
stable-window: "60s"
# Panic mode settings
panic-window-percentage: "10"
panic-threshold-percentage: "200"config-defaults (knative-serving)
apiVersion: v1
kind: ConfigMap
metadata:
name: config-defaults
namespace: knative-serving
data:
# Default revision timeout
revision-timeout-seconds: "300"
# Default container concurrency
container-concurrency: "0"
# Default resource requests
revision-cpu-request: "400m"
revision-memory-request: "100M"
revision-ephemeral-storage-request: "500M"
# Default resource limits
revision-cpu-limit: "1000m"
revision-memory-limit: "200M"
revision-ephemeral-storage-limit: "750M"config-domain (knative-serving)
apiVersion: v1
kind: ConfigMap
metadata:
name: config-domain
namespace: knative-serving
data:
# Default domain for all services
example.com: ""
# Selector-based domain mapping
custom.example.com: |
selector:
app: special-appconfig-network (knative-serving)
apiVersion: v1
kind: ConfigMap
metadata:
name: config-network
namespace: knative-serving
data:
# Ingress class (networking layer)
ingress-class: kourier.ingress.networking.knative.dev
# Or: istio.ingress.networking.knative.dev
# Or: contour.ingress.networking.knative.dev
# Certificate class for auto-TLS
certificate-class: cert-manager.certificate.networking.knative.dev
# Auto-TLS configuration
auto-tls: "Enabled"
http-protocol: "Redirected" # or "Enabled"
# External/Internal service visibility
default-external-scheme: https
# Domain template
domain-template: "{{.Name}}.{{.Namespace}}.{{.Domain}}"config-br-defaults (knative-eventing)
apiVersion: v1
kind: ConfigMap
metadata:
name: config-br-defaults
namespace: knative-eventing
data:
default-br-config: |
clusterDefault:
brokerClass: MTChannelBasedBroker
apiVersion: v1
kind: ConfigMap
name: config-br-default-channel
namespace: knative-eventing
delivery:
retry: 10
backoffPolicy: exponential
backoffDelay: PT0.2SMetrics Reference
Serving Metrics
Exposed at :9090/metrics on knative-serving pods.
| Metric | Type | Description |
|---|---|---|
revision_request_count | Counter | Total requests per revision |
revision_request_latencies | Histogram | Request latency distribution |
revision_app_request_count | Counter | App-level request count |
revision_app_request_latencies | Histogram | App-level latency |
activator_request_count | Counter | Requests through activator |
autoscaler_actual_pods | Gauge | Current pod count |
autoscaler_desired_pods | Gauge | Desired pod count |
autoscaler_stable_request_concurrency | Gauge | Average concurrency (stable) |
autoscaler_panic_request_concurrency | Gauge | Average concurrency (panic) |
Eventing Metrics
| Metric | Type | Description |
|---|---|---|
broker_dispatch_count | Counter | Events dispatched by broker |
broker_dispatch_latency | Histogram | Event dispatch latency |
trigger_dispatch_count | Counter | Events dispatched by trigger |
trigger_filter_count | Counter | Events filtered by trigger |
event_count | Counter | Total events processed |
CloudEvents Specification
Knative Eventing uses CloudEvents format (CNCF specification).
Required Attributes
| Attribute | Type | Description |
|---|---|---|
specversion | String | CloudEvents spec version (1.0) |
id | String | Unique event ID |
source | URI-reference | Event source identifier |
type | String | Event type (e.g., dev.knative.example) |
Optional Attributes
| Attribute | Type | Description |
|---|---|---|
datacontenttype | String | Content type (e.g., application/json) |
dataschema | URI | Schema for data attribute |
subject | String | Event subject |
time | Timestamp | Event timestamp (RFC 3339) |
HTTP Binding
POST /events HTTP/1.1
Host: broker-ingress.knative-eventing.svc.cluster.local
Content-Type: application/json
ce-specversion: 1.0
ce-type: dev.knative.example
ce-source: /my/source
ce-id: A234-1234-1234
ce-time: 2024-01-01T00:00:00Z
{
"message": "Hello, World!"
}Annotations Reference
Serving Annotations
| Annotation | Values | Description |
|---|---|---|
autoscaling.knative.dev/class | kpa.autoscaling.knative.dev, hpa.autoscaling.knative.dev | Autoscaler implementation |
autoscaling.knative.dev/metric | concurrency, rps, cpu, memory | Scaling metric |
autoscaling.knative.dev/target | Number | Target value for metric |
autoscaling.knative.dev/min-scale | Number | Minimum replicas |
autoscaling.knative.dev/max-scale | Number | Maximum replicas |
autoscaling.knative.dev/initial-scale | Number | Initial replicas on creation |
autoscaling.knative.dev/scale-down-delay | Duration | Delay before scale down |
autoscaling.knative.dev/window | Duration | Metrics averaging window |
autoscaling.knative.dev/panic-window-percentage | Percentage | Panic mode window |
autoscaling.knative.dev/panic-threshold-percentage | Percentage | Panic mode threshold |
serving.knative.dev/visibility | cluster-local | Internal-only service |
Eventing Annotations
| Annotation | Values | Description |
|---|---|---|
eventing.knative.dev/broker.class | MTChannelBasedBroker, Kafka | Broker implementation |
eventing.knative.dev/injection | enabled, disabled | Auto-inject default broker |
Status Conditions
Service Status
| Condition | Description |
|---|---|
Ready | Service is fully operational |
ConfigurationsReady | Configuration is ready |
RoutesReady | Routes are configured |
Revision Status
| Condition | Description |
|---|---|
Ready | Revision is ready to serve |
Active | Revision is receiving traffic |
ContainerHealthy | Container passed health checks |
ResourcesAvailable | Resources are provisioned |
Broker Status
| Condition | Description |
|---|---|
Ready | Broker is operational |
Addressable | Broker has an address |
FilterReady | Filter service is ready |
IngressReady | Ingress is ready |
TriggerChannelReady | Channel is ready |
Trigger Status
| Condition | Description |
|---|---|
Ready | Trigger is operational |
BrokerReady | Referenced broker is ready |
SubscriberResolved | Subscriber URI resolved |
DependencyReady | Dependencies are ready |
#!/bin/bash
# Deploy a Knative Service
# Usage: ./deploy-service.sh <name> <image> [namespace] [cluster]
set -euo pipefail
NAME="${1:-}"
IMAGE="${2:-}"
NAMESPACE="${3:-default}"
CLUSTER="${4:-}"
if [[ -z "$NAME" || -z "$IMAGE" ]]; then
echo "Usage: $0 <name> <image> [namespace] [cluster]"
echo ""
echo "Examples:"
echo " $0 hello-world gcr.io/knative-samples/helloworld-go"
echo " $0 my-app myregistry/myapp:v1 production cafehyna-dev"
exit 1
fi
# Set kubeconfig if cluster specified
if [[ -n "$CLUSTER" ]]; then
KUBECONFIG_PATH="$HOME/.kube/aks-rg-hypera-${CLUSTER}-config"
if [[ -f "$KUBECONFIG_PATH" ]]; then
export KUBECONFIG="$KUBECONFIG_PATH"
echo "Using kubeconfig: $KUBECONFIG_PATH"
else
echo "Error: Kubeconfig not found: $KUBECONFIG_PATH"
exit 1
fi
fi
# Check if cluster uses spot instances (dev clusters)
SPOT_TOLERATIONS=""
if [[ "$CLUSTER" == *"-dev"* ]]; then
echo "Dev cluster detected - adding spot tolerations"
SPOT_TOLERATIONS='
tolerations:
- key: kubernetes.azure.com/scalesetpriority
operator: Equal
value: "spot"
effect: NoSchedule
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: agentpool
operator: In
values:
- cafedevspot'
fi
# Generate Knative Service YAML
cat <<EOF
---
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: ${NAME}
namespace: ${NAMESPACE}
spec:
template:
metadata:
annotations:
# Autoscaling configuration
autoscaling.knative.dev/class: kpa.autoscaling.knative.dev
autoscaling.knative.dev/min-scale: "0"
autoscaling.knative.dev/max-scale: "10"
autoscaling.knative.dev/target: "100"
spec:${SPOT_TOLERATIONS}
containers:
- image: ${IMAGE}
ports:
- containerPort: 8080
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 128Mi
# readinessProbe:
# httpGet:
# path: /health
# port: 8080
EOF
echo ""
echo "---"
echo ""
echo "To deploy this service, pipe the output to kubectl:"
echo " $0 $NAME $IMAGE $NAMESPACE $CLUSTER | kubectl apply -f -"
echo ""
echo "Or save to file and apply:"
echo " $0 $NAME $IMAGE $NAMESPACE $CLUSTER > ksvc-${NAME}.yaml"
echo " kubectl apply -f ksvc-${NAME}.yaml"
#!/bin/bash
# Knative Diagnostics Script
# Usage: ./diagnose.sh [cluster-name] [component]
# Components: serving, eventing, all (default)
set -euo pipefail
CLUSTER="${1:-}"
COMPONENT="${2:-all}"
# Color output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
print_header() {
echo -e "\n${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${BLUE} $1${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}
print_section() {
echo -e "\n${YELLOW}▶ $1${NC}"
}
print_ok() {
echo -e "${GREEN}✓${NC} $1"
}
print_warn() {
echo -e "${YELLOW}⚠${NC} $1"
}
print_error() {
echo -e "${RED}✗${NC} $1"
}
# Set kubeconfig if cluster specified
if [[ -n "$CLUSTER" ]]; then
KUBECONFIG_PATH="$HOME/.kube/aks-rg-hypera-${CLUSTER}-config"
if [[ -f "$KUBECONFIG_PATH" ]]; then
export KUBECONFIG="$KUBECONFIG_PATH"
print_ok "Using kubeconfig: $KUBECONFIG_PATH"
else
print_error "Kubeconfig not found: $KUBECONFIG_PATH"
exit 1
fi
fi
print_header "Knative Diagnostics"
echo "Cluster: ${CLUSTER:-current-context}"
echo "Component: $COMPONENT"
echo "Time: $(date)"
# Check Knative installation
check_installation() {
print_section "Checking Knative Installation"
# Check namespaces
if kubectl get namespace knative-serving &>/dev/null; then
print_ok "knative-serving namespace exists"
else
print_error "knative-serving namespace not found"
fi
if kubectl get namespace knative-eventing &>/dev/null; then
print_ok "knative-eventing namespace exists"
else
print_warn "knative-eventing namespace not found (optional)"
fi
# Check CRDs
print_section "Checking CRDs"
SERVING_CRDS=("services.serving.knative.dev" "routes.serving.knative.dev" "configurations.serving.knative.dev" "revisions.serving.knative.dev")
EVENTING_CRDS=("brokers.eventing.knative.dev" "triggers.eventing.knative.dev" "channels.messaging.knative.dev")
for crd in "${SERVING_CRDS[@]}"; do
if kubectl get crd "$crd" &>/dev/null; then
print_ok "$crd"
else
print_error "$crd not found"
fi
done
for crd in "${EVENTING_CRDS[@]}"; do
if kubectl get crd "$crd" &>/dev/null; then
print_ok "$crd"
else
print_warn "$crd not found (eventing)"
fi
done
}
# Check Serving components
check_serving() {
print_section "Checking Knative Serving Components"
# Controller
echo -e "\n${YELLOW}Controller:${NC}"
kubectl get pods -n knative-serving -l app=controller --no-headers 2>/dev/null | while read -r line; do
pod_name=$(echo "$line" | awk '{print $1}')
status=$(echo "$line" | awk '{print $3}')
restarts=$(echo "$line" | awk '{print $4}')
if [[ "$status" == "Running" && "$restarts" -lt 5 ]]; then
print_ok "$pod_name ($status, restarts: $restarts)"
else
print_error "$pod_name ($status, restarts: $restarts)"
fi
done
# Activator
echo -e "\n${YELLOW}Activator:${NC}"
kubectl get pods -n knative-serving -l app=activator --no-headers 2>/dev/null | while read -r line; do
pod_name=$(echo "$line" | awk '{print $1}')
status=$(echo "$line" | awk '{print $3}')
print_ok "$pod_name ($status)"
done
# Autoscaler
echo -e "\n${YELLOW}Autoscaler:${NC}"
kubectl get pods -n knative-serving -l app=autoscaler --no-headers 2>/dev/null | while read -r line; do
pod_name=$(echo "$line" | awk '{print $1}')
status=$(echo "$line" | awk '{print $3}')
print_ok "$pod_name ($status)"
done
# Webhook
echo -e "\n${YELLOW}Webhook:${NC}"
kubectl get pods -n knative-serving -l app=webhook --no-headers 2>/dev/null | while read -r line; do
pod_name=$(echo "$line" | awk '{print $1}')
status=$(echo "$line" | awk '{print $3}')
print_ok "$pod_name ($status)"
done
}
# Check networking layer
check_networking() {
print_section "Checking Networking Layer"
# Detect networking layer
if kubectl get namespace kourier-system &>/dev/null; then
print_ok "Kourier detected"
echo -e "\n${YELLOW}Kourier Pods:${NC}"
kubectl get pods -n kourier-system --no-headers 2>/dev/null
echo -e "\n${YELLOW}Kourier Service:${NC}"
kubectl get svc -n kourier-system kourier --no-headers 2>/dev/null || print_warn "Kourier service not found"
elif kubectl get namespace istio-system &>/dev/null; then
print_ok "Istio detected"
echo -e "\n${YELLOW}Istio Ingress:${NC}"
kubectl get pods -n istio-system -l app=istio-ingressgateway --no-headers 2>/dev/null
else
print_warn "No networking layer detected (Kourier/Istio)"
fi
# Check config-network
echo -e "\n${YELLOW}Network Configuration:${NC}"
kubectl get configmap config-network -n knative-serving -o jsonpath='{.data.ingress-class}' 2>/dev/null && echo ""
}
# Check Eventing components
check_eventing() {
print_section "Checking Knative Eventing Components"
if ! kubectl get namespace knative-eventing &>/dev/null; then
print_warn "Knative Eventing not installed"
return
fi
# Controller
echo -e "\n${YELLOW}Eventing Controller:${NC}"
kubectl get pods -n knative-eventing -l app=eventing-controller --no-headers 2>/dev/null | while read -r line; do
pod_name=$(echo "$line" | awk '{print $1}')
status=$(echo "$line" | awk '{print $3}')
print_ok "$pod_name ($status)"
done
# Webhook
echo -e "\n${YELLOW}Eventing Webhook:${NC}"
kubectl get pods -n knative-eventing -l app=eventing-webhook --no-headers 2>/dev/null | while read -r line; do
pod_name=$(echo "$line" | awk '{print $1}')
status=$(echo "$line" | awk '{print $3}')
print_ok "$pod_name ($status)"
done
# Brokers
echo -e "\n${YELLOW}Brokers:${NC}"
kubectl get brokers -A --no-headers 2>/dev/null || print_warn "No brokers found"
# Triggers
echo -e "\n${YELLOW}Triggers:${NC}"
kubectl get triggers -A --no-headers 2>/dev/null || print_warn "No triggers found"
}
# Check Services
check_services() {
print_section "Knative Services Status"
echo -e "\n${YELLOW}All Knative Services:${NC}"
kubectl get ksvc -A 2>/dev/null || print_warn "No Knative services found"
echo -e "\n${YELLOW}Service Details:${NC}"
kubectl get ksvc -A -o custom-columns="NAMESPACE:.metadata.namespace,NAME:.metadata.name,URL:.status.url,READY:.status.conditions[?(@.type=='Ready')].status,REASON:.status.conditions[?(@.type=='Ready')].reason" 2>/dev/null
}
# Check Revisions
check_revisions() {
print_section "Revisions Status"
echo -e "\n${YELLOW}All Revisions:${NC}"
kubectl get revisions -A -o custom-columns="NAMESPACE:.metadata.namespace,NAME:.metadata.name,SERVICE:.metadata.labels['serving\.knative\.dev/service'],READY:.status.conditions[?(@.type=='Ready')].status,REASON:.status.conditions[?(@.type=='Ready')].reason" 2>/dev/null
}
# Check domain configuration
check_domain() {
print_section "Domain Configuration"
echo -e "\n${YELLOW}config-domain:${NC}"
kubectl get configmap config-domain -n knative-serving -o yaml 2>/dev/null | grep -A 20 "^data:" || print_warn "config-domain not found"
}
# Check recent events
check_events() {
print_section "Recent Events (last 10)"
echo -e "\n${YELLOW}Knative Serving Events:${NC}"
kubectl get events -n knative-serving --sort-by='.lastTimestamp' 2>/dev/null | tail -10
if kubectl get namespace knative-eventing &>/dev/null; then
echo -e "\n${YELLOW}Knative Eventing Events:${NC}"
kubectl get events -n knative-eventing --sort-by='.lastTimestamp' 2>/dev/null | tail -10
fi
}
# Main execution
case "$COMPONENT" in
serving)
check_installation
check_serving
check_networking
check_services
check_revisions
check_domain
check_events
;;
eventing)
check_installation
check_eventing
check_events
;;
all)
check_installation
check_serving
check_networking
check_eventing
check_services
check_revisions
check_domain
check_events
;;
*)
echo "Usage: $0 [cluster-name] [serving|eventing|all]"
exit 1
;;
esac
print_header "Diagnostics Complete"
#!/bin/bash
# Knative Installation Script
# Usage: ./install.sh [cluster-name] [version] [networking-layer]
# Networking layers: kourier (default), istio, contour
set -euo pipefail
CLUSTER="${1:-}"
VERSION="${2:-v1.20.0}"
NETWORKING="${3:-kourier}"
# Color output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_header() {
echo -e "\n${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${BLUE} $1${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}
print_step() {
echo -e "\n${YELLOW}▶ $1${NC}"
}
print_ok() {
echo -e "${GREEN}✓${NC} $1"
}
print_error() {
echo -e "${RED}✗${NC} $1"
exit 1
}
# Set kubeconfig if cluster specified
if [[ -n "$CLUSTER" ]]; then
KUBECONFIG_PATH="$HOME/.kube/aks-rg-hypera-${CLUSTER}-config"
if [[ -f "$KUBECONFIG_PATH" ]]; then
export KUBECONFIG="$KUBECONFIG_PATH"
print_ok "Using kubeconfig: $KUBECONFIG_PATH"
else
print_error "Kubeconfig not found: $KUBECONFIG_PATH"
fi
fi
print_header "Knative Installation"
echo "Cluster: ${CLUSTER:-current-context}"
echo "Version: $VERSION"
echo "Networking: $NETWORKING"
echo ""
# Confirm installation
read -p "Proceed with installation? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Installation cancelled."
exit 0
fi
# Install Knative Serving
print_step "Installing Knative Serving CRDs"
kubectl apply -f "https://github.com/knative/serving/releases/download/knative-${VERSION}/serving-crds.yaml"
print_ok "Serving CRDs installed"
print_step "Installing Knative Serving Core"
kubectl apply -f "https://github.com/knative/serving/releases/download/knative-${VERSION}/serving-core.yaml"
print_ok "Serving core installed"
# Wait for serving pods
print_step "Waiting for Serving pods to be ready"
kubectl wait --for=condition=ready pod -l app=controller -n knative-serving --timeout=120s
kubectl wait --for=condition=ready pod -l app=activator -n knative-serving --timeout=120s
kubectl wait --for=condition=ready pod -l app=autoscaler -n knative-serving --timeout=120s
kubectl wait --for=condition=ready pod -l app=webhook -n knative-serving --timeout=120s
print_ok "Serving pods ready"
# Install Networking Layer
print_step "Installing Networking Layer: $NETWORKING"
case "$NETWORKING" in
kourier)
kubectl apply -f "https://github.com/knative/net-kourier/releases/download/knative-${VERSION}/kourier.yaml"
kubectl patch configmap/config-network \
--namespace knative-serving \
--type merge \
--patch '{"data":{"ingress-class":"kourier.ingress.networking.knative.dev"}}'
print_ok "Kourier installed"
# Wait for Kourier
kubectl wait --for=condition=ready pod -l app=3scale-kourier-gateway -n kourier-system --timeout=120s
print_ok "Kourier gateway ready"
;;
istio)
kubectl apply -f "https://github.com/knative/net-istio/releases/download/knative-${VERSION}/net-istio.yaml"
kubectl patch configmap/config-network \
--namespace knative-serving \
--type merge \
--patch '{"data":{"ingress-class":"istio.ingress.networking.knative.dev"}}'
print_ok "Istio networking installed"
;;
contour)
kubectl apply -f "https://github.com/knative/net-contour/releases/download/knative-${VERSION}/contour.yaml"
kubectl apply -f "https://github.com/knative/net-contour/releases/download/knative-${VERSION}/net-contour.yaml"
kubectl patch configmap/config-network \
--namespace knative-serving \
--type merge \
--patch '{"data":{"ingress-class":"contour.ingress.networking.knative.dev"}}'
print_ok "Contour networking installed"
;;
*)
print_error "Unknown networking layer: $NETWORKING. Use: kourier, istio, or contour"
;;
esac
# Install Knative Eventing
print_step "Installing Knative Eventing CRDs"
kubectl apply -f "https://github.com/knative/eventing/releases/download/knative-${VERSION}/eventing-crds.yaml"
print_ok "Eventing CRDs installed"
print_step "Installing Knative Eventing Core"
kubectl apply -f "https://github.com/knative/eventing/releases/download/knative-${VERSION}/eventing-core.yaml"
print_ok "Eventing core installed"
# Install In-Memory Channel (dev) or wait for Kafka setup
print_step "Installing In-Memory Channel (for development)"
kubectl apply -f "https://github.com/knative/eventing/releases/download/knative-${VERSION}/in-memory-channel.yaml"
print_ok "In-Memory Channel installed"
print_step "Installing MT-Channel-Based Broker"
kubectl apply -f "https://github.com/knative/eventing/releases/download/knative-${VERSION}/mt-channel-broker.yaml"
print_ok "MT-Channel-Based Broker installed"
# Wait for eventing pods
print_step "Waiting for Eventing pods to be ready"
kubectl wait --for=condition=ready pod -l app=eventing-controller -n knative-eventing --timeout=120s
kubectl wait --for=condition=ready pod -l app=eventing-webhook -n knative-eventing --timeout=120s
print_ok "Eventing pods ready"
# Get External IP for DNS configuration
print_header "Installation Complete"
echo -e "\n${YELLOW}External IP for DNS configuration:${NC}"
case "$NETWORKING" in
kourier)
kubectl get svc kourier -n kourier-system
;;
istio)
kubectl get svc istio-ingressgateway -n istio-system
;;
contour)
kubectl get svc envoy -n contour-external
;;
esac
echo -e "\n${YELLOW}Next steps:${NC}"
echo "1. Configure DNS:"
echo " - Production: Create A record *.knative.yourdomain.com -> EXTERNAL-IP"
echo " - Development: Use sslip.io magic DNS"
echo ""
echo "2. Configure domain:"
echo " kubectl patch configmap/config-domain \\"
echo " --namespace knative-serving \\"
echo " --type merge \\"
echo " --patch '{\"data\":{\"<EXTERNAL-IP>.sslip.io\":\"\"}}'"
echo ""
echo "3. (Optional) Enable auto-TLS with cert-manager"
echo ""
echo "Run './diagnose.sh ${CLUSTER:-}' to verify installation"
#!/bin/bash
# Configure traffic splitting for a Knative Service
# Usage: ./traffic-split.sh <service> <revision1:percent> [revision2:percent] ... [cluster]
set -euo pipefail
SERVICE="${1:-}"
shift || true
if [[ -z "$SERVICE" ]]; then
echo "Usage: $0 <service> <revision:percent> [revision:percent] ... [--cluster=name]"
echo ""
echo "Examples:"
echo " # Blue-green deployment (100% to new revision)"
echo " $0 my-service my-service-00002:100"
echo ""
echo " # Canary deployment (90/10 split)"
echo " $0 my-service my-service-00001:90 my-service-00002:10"
echo ""
echo " # Gradual rollout"
echo " $0 my-service my-service-00001:70 my-service-00002:30"
echo ""
echo " # With specific cluster"
echo " $0 my-service my-service-00002:100 --cluster=cafehyna-dev"
echo ""
echo "Special revision names:"
echo " @latest - Route to latest ready revision"
exit 1
fi
NAMESPACE="${NAMESPACE:-default}"
CLUSTER=""
TRAFFIC_ENTRIES=()
# Parse arguments
for arg in "$@"; do
if [[ "$arg" == --cluster=* ]]; then
CLUSTER="${arg#--cluster=}"
elif [[ "$arg" == --namespace=* ]]; then
NAMESPACE="${arg#--namespace=}"
elif [[ "$arg" == *:* ]]; then
TRAFFIC_ENTRIES+=("$arg")
fi
done
if [[ ${#TRAFFIC_ENTRIES[@]} -eq 0 ]]; then
echo "Error: At least one revision:percent pair is required"
exit 1
fi
# Set kubeconfig if cluster specified
if [[ -n "$CLUSTER" ]]; then
KUBECONFIG_PATH="$HOME/.kube/aks-rg-hypera-${CLUSTER}-config"
if [[ -f "$KUBECONFIG_PATH" ]]; then
export KUBECONFIG="$KUBECONFIG_PATH"
echo "Using kubeconfig: $KUBECONFIG_PATH"
else
echo "Error: Kubeconfig not found: $KUBECONFIG_PATH"
exit 1
fi
fi
# Validate percentages sum to 100
TOTAL=0
for entry in "${TRAFFIC_ENTRIES[@]}"; do
percent="${entry#*:}"
TOTAL=$((TOTAL + percent))
done
if [[ $TOTAL -ne 100 ]]; then
echo "Error: Traffic percentages must sum to 100 (got $TOTAL)"
exit 1
fi
# Build traffic patch
TRAFFIC_JSON="["
FIRST=true
for entry in "${TRAFFIC_ENTRIES[@]}"; do
revision="${entry%:*}"
percent="${entry#*:}"
if [[ "$FIRST" == "true" ]]; then
FIRST=false
else
TRAFFIC_JSON+=","
fi
if [[ "$revision" == "@latest" ]]; then
TRAFFIC_JSON+="{\"latestRevision\":true,\"percent\":${percent}}"
else
TRAFFIC_JSON+="{\"revisionName\":\"${revision}\",\"percent\":${percent}}"
fi
done
TRAFFIC_JSON+="]"
echo "Service: $SERVICE"
echo "Namespace: $NAMESPACE"
echo "Traffic configuration:"
for entry in "${TRAFFIC_ENTRIES[@]}"; do
revision="${entry%:*}"
percent="${entry#*:}"
echo " - $revision: ${percent}%"
done
echo ""
# Show the patch that would be applied
echo "Patch to apply:"
echo "{\"spec\":{\"traffic\":$TRAFFIC_JSON}}"
echo ""
read -p "Apply this traffic split? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Cancelled."
exit 0
fi
# Apply the patch
kubectl patch ksvc "$SERVICE" -n "$NAMESPACE" --type=merge -p "{\"spec\":{\"traffic\":$TRAFFIC_JSON}}"
echo ""
echo "Traffic split applied. Current status:"
kubectl get ksvc "$SERVICE" -n "$NAMESPACE" -o jsonpath='{range .status.traffic[*]} {.revisionName}: {.percent}%{"\n"}{end}'