What's Actually Happening

Knative Service fails to deploy. The service is created but revisions don't become ready or routes aren't configured.

The Error You'll See

```bash $ kubectl get ksvc -n default

NAME URL LATESTCREATED LATESTREADY READY REASON my-service my-service-01 False RevisionFailed

$ kubectl describe ksvc my-service -n default

Status: Conditions: Type: Ready Status: False Reason: RevisionFailed Message: Revision "my-service-01" failed ```

Revision error:

```bash $ kubectl get revision -n default

NAME SERVICE NAME CONFIG NAME READY REASON my-service-01 my-service-01 my-service False ContainerMissing ```

Route error:

bash
Error: RevisionTargetMissing: no healthy revision target

Why This Happens

  1. 1.Container image not found - Image doesn't exist or cannot be pulled
  2. 2.Revision failed - Revision startup or health check failed
  3. 3.Route not ready - Knative route configuration error
  4. 4.Configuration error - Invalid service spec
  5. 5.Domain not configured - Magic DNS or custom domain issue
  6. 6.Activator issues - Knative activator not functioning

Step 1: Check Service and Revision Status

```bash # List Knative Services: kubectl get ksvc -A

# Check service details: kubectl get ksvc my-service -n default -o yaml

# Describe service: kubectl describe ksvc my-service -n default

# List revisions: kubectl get revision -n default

# Check specific revision: kubectl get revision my-service-01 -n default -o yaml

# Describe revision: kubectl describe revision my-service-01 -n default

# Check revision conditions: kubectl get revision my-service-01 -n default -o jsonpath='{.status.conditions}'

# View revision logs: kubectl logs -n default revision-pod-name

# Check configuration: kubectl get configuration -n default

# Check routes: kubectl get route -n default ```

Step 2: Verify Container Image

```bash # Check image in revision: kubectl get revision my-service-01 -n default -o jsonpath='{.spec.containers[0].image}'

# Test image pull: docker pull myimage:latest

# Check image exists: kubectl run test-image --image=myimage:latest --rm -it --restart=Never -- echo "image exists"

# For private registry, check imagePullSecrets: kubectl get revision my-service-01 -n default -o yaml | grep -A5 imagePullSecrets

# Create image pull secret: kubectl create secret docker-registry regcred \ --docker-server=myregistry.com \ --docker-username=user \ --docker-password=pass \ -n default

# Add to service: apiVersion: serving.knative.dev/v1 kind: Service metadata: name: my-service spec: template: spec: imagePullSecrets: - name: regcred containers: - image: myregistry.com/myimage:latest

# Check image registry connectivity: kubectl run test-reg --image=curlimages/curl --rm -it --restart=Never \ -- curl -I https://myregistry.com/v2/ ```

Step 3: Check Revision Pods

```bash # List pods for revision: kubectl get pods -n default -l serving.knative.dev/revision=my-service-01

# Describe revision pod: kubectl describe pod -n default -l serving.knative.dev/revision=my-service-01

# Check pod events: kubectl get events -n default --field-selector involvedObject.kind=Pod

# Check pod logs: kubectl logs -n default -l serving.knative.dev/revision=my-service-01 -c user-container

# Check queue-proxy logs: kubectl logs -n default -l serving.knative.dev/revision=my-service-01 -c queue-proxy

# Check pod status: kubectl get pod -n default -l serving.knative.dev/revision=my-service-01 -o jsonpath='{.status.phase}'

# Check init containers: kubectl logs -n default -l serving.knative.dev/revision=my-service-01 -c queue-proxy-init

# If pod pending, check events: kubectl describe pod -n default -l serving.knative.dev/revision=my-service-01 | grep -A10 Events ```

Step 4: Verify Health Checks

```bash # Check readiness probe configuration: kubectl get revision my-service-01 -n default -o yaml | grep -A10 readinessProbe

# Default Knative checks: # - Port 8080 or PORT env var # - Path / (or specified path)

# Check container port: kubectl get revision my-service-01 -n default -o jsonpath='{.spec.containers[0].ports[0].containerPort}'

# Test health endpoint: kubectl port-forward -n default svc/my-service 8080:80 & curl http://localhost:8080/health

# Add custom readiness probe: apiVersion: serving.knative.dev/v1 kind: Service metadata: name: my-service spec: template: spec: containers: - image: myimage:latest readinessProbe: httpGet: path: /health port: 8080 periodSeconds: 5

# Check startup probe: # Knative uses startupProbe by default # May need to increase timeout for slow-starting containers

# Increase timeout: spec: template: spec: containers: - image: myimage:latest readinessProbe: periodSeconds: 10 failureThreshold: 30 # 5 minutes ```

Step 5: Check Route Status

```bash # List routes: kubectl get route -n default

# Check route details: kubectl get route my-service -n default -o yaml

# Describe route: kubectl describe route my-service -n default

# Check route conditions: kubectl get route my-service -n default -o jsonpath='{.status.conditions}'

# Check route URL: kubectl get route my-service -n default -o jsonpath='{.status.url}'

# Check traffic targets: kubectl get route my-service -n default -o jsonpath='{.status.traffic}'

# Verify ingress: kubectl get ingress -n default

# Check Knative ingress: kubectl get kingress -n default

# Describe ingress: kubectl describe kingress my-service -n default

# Check virtual service (Istio): kubectl get virtualservice -n default

# Check network policies: kubectl get networkpolicy -n default ```

Step 6: Check Knative Serving

```bash # Check Knative namespace: kubectl get all -n knative-serving

# Check Knative pods: kubectl get pods -n knative-serving

# View controller logs: kubectl logs -n knative-serving deploy/controller

# Check activator: kubectl get pods -n knative-serving -l app=activator kubectl logs -n knative-serving deploy/activator

# Check autoscaler: kubectl get pods -n knative-serving -l app=autoscaler kubectl logs -n knative-serving deploy/autoscaler

# Check webhook: kubectl get pods -n knative-serving -l app=webhook kubectl logs -n knative-serving deploy/webhook

# Check domain config: kubectl get configmap -n knative-serving config-domain -o yaml

# Check network config: kubectl get configmap -n knative-serving config-network -o yaml

# Check features config: kubectl get configmap -n knative-serving config-features -o yaml ```

Step 7: Configure Custom Domain

```bash # Check current domain: kubectl get configmap -n knative-serving config-domain -o yaml

# Default uses sslip.io or nip.io magic DNS

# Configure custom domain: apiVersion: v1 kind: ConfigMap metadata: name: config-domain namespace: knative-serving data: example.com: "" mydomain.com: | selector: app: myapp

# Verify domain config: kubectl get configmap -n knative-serving config-domain -o yaml

# After config, services get URL: # http://my-service.default.example.com

# For HTTPS, configure cert-manager: apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: my-service-cert namespace: default spec: dnsNames: - my-service.default.example.com issuerRef: name: letsencrypt kind: ClusterIssuer secretName: my-service-tls ```

Step 8: Check Resource Limits

```bash # Check revision resources: kubectl get revision my-service-01 -n default -o yaml | grep -A10 resources

# Default resources may be too low: # requests: # cpu: "100m" # memory: "128Mi"

# Increase resources: apiVersion: serving.knative.dev/v1 kind: Service metadata: name: my-service spec: template: spec: containers: - image: myimage:latest resources: requests: cpu: "500m" memory: "512Mi" limits: cpu: "1000m" memory: "1Gi"

# Check container concurrency: kubectl get revision my-service-01 -n default -o jsonpath='{.spec.containerConcurrency}'

# Adjust concurrency: spec: template: spec: containerConcurrency: 10 # Max 10 concurrent requests per pod ```

Step 9: Check Autoscaling

```bash # Check autoscaling config: kubectl get revision my-service-01 -n default -o yaml | grep -A10 autoscaling

# Check KPA (Knative Pod Autoscaler): kubectl get kpa -n default

# Describe KPA: kubectl describe kpa my-service-01 -n default

# Check KPA conditions: kubectl get kpa my-service-01 -n default -o jsonpath='{.status.conditions}'

# Adjust scale bounds: apiVersion: serving.knative.dev/v1 kind: Service metadata: name: my-service annotations: autoscaling.knative.dev/minScale: "1" autoscaling.knative.dev/maxScale: "10" autoscaling.knative.dev/target: "10" # Target concurrency spec: template: spec: containers: - image: myimage:latest

# Check scale-to-zero config: kubectl get configmap -n knative-serving config-autoscaler -o yaml | grep scale-to-zero

# Disable scale-to-zero: kubectl patch configmap -n knative-serving config-autoscaler \ --type='json' -p='[{"op": "add", "path": "/data/enable-scale-to-zero", "value": "false"}]' ```

Step 10: Knative Verification Script

```bash # Create verification script: cat << 'EOF' > /usr/local/bin/check-knative-service.sh #!/bin/bash

SVC=${1:-"my-service"} NS=${2:-"default"}

echo "=== Knative Service ===" kubectl get ksvc $SVC -n $NS

echo "" echo "=== Service Status ===" kubectl get ksvc $SVC -n $NS -o yaml | grep -A30 "status:"

echo "" echo "=== Revisions ===" kubectl get revision -n $NS -l serving.knative.dev/service=$SVC

echo "" echo "=== Latest Revision ===" LATEST=$(kubectl get ksvc $SVC -n $NS -o jsonpath='{.status.latestCreatedRevisionName}') kubectl get revision $LATEST -n $NS -o yaml | grep -A20 "status:"

echo "" echo "=== Route ===" kubectl get route $SVC -n $NS

echo "" echo "=== Route URL ===" kubectl get route $SVC -n $NS -o jsonpath='{.status.url}'

echo "" echo "=== Revision Pods ===" kubectl get pods -n $NS -l serving.knative.dev/service=$SVC

echo "" echo "=== Knative Serving ===" kubectl get pods -n knative-serving

echo "" echo "=== Pod Logs ===" kubectl logs -n $NS -l serving.knative.dev/service=$SVC -c user-container --tail=10 2>/dev/null || echo "No logs"

echo "" echo "=== Recommendations ===" echo "1. Verify container image exists and is accessible" echo "2. Check health/readiness endpoint is working" echo "3. Review revision logs for errors" echo "4. Ensure Knative Serving pods are running" echo "5. Verify domain configuration" echo "6. Check resource limits are adequate" echo "7. Review autoscaling configuration" EOF

chmod +x /usr/local/bin/check-knative-service.sh

# Usage: /usr/local/bin/check-knative-service.sh my-service default ```

Knative Service Checklist

CheckExpected
Container imageExists and pullable
Health check/health or / returns 200
Revision readyREADY condition true
Route configuredURL assigned
Domain configCustom or magic DNS
Serving podsRunning in knative-serving
Resource limitsAdequate CPU/memory

Verify the Fix

```bash # After fixing Knative Service issues

# 1. Check service ready kubectl get ksvc my-service -n default // READY: True

# 2. Get service URL kubectl get ksvc my-service -n default -o jsonpath='{.status.url}' // http://my-service.default.example.com

# 3. Test service curl http://my-service.default.example.com // Returns response

# 4. Check revision kubectl get revision -n default // Latest revision READY: true

# 5. Verify route kubectl get route my-service -n default // URL assigned

# 6. Check pods kubectl get pods -n default -l serving.knative.dev/service=my-service // Pods running ```

  • [Fix Kubernetes Deployment Not Working](/articles/fix-kubernetes-deployment-not-working)
  • [Fix Kubernetes Ingress Not Routing Traffic](/articles/fix-kubernetes-ingress-not-routing-traffic)
  • [Fix Istio Traffic Not Routing](/articles/fix-istio-traffic-not-routing)