Sign In

Curriculum 30: Kubectl Internals

Request Flow

20 min · 50 XP

Request Flow in Kubernetes

Every kubectl command triggers a request that passes through multiple stages in the API server before a resource is persisted. Understanding this flow is essential for debugging and building extensions.

The Full Request Lifecycle

When you run kubectl apply -f deployment.yaml, the request flows through these stages:

kubectl --> API Server --> Authentication --> Authorization
    --> Admission Controllers --> Validation --> etcd

1. Authentication

The API server verifies the identity of the caller:

# Check your current identity
kubectl auth whoami

# View the authentication configuration
kubectl config view --minify

# Test with verbose output to see auth headers
kubectl get pods -v=8 2>&1 | grep -i "authorization"

Supported methods include client certificates, bearer tokens, OIDC, and service account tokens.

2. Authorization

After authentication, the API server checks if the user is allowed to perform the requested action:

# Check if you can perform an action
kubectl auth can-i create deployments -n production

# Check all permissions
kubectl auth can-i --list -n production

# Test as a different user
kubectl auth can-i get secrets --as=system:serviceaccount:default:myapp

Kubernetes supports RBAC, ABAC, Node, and Webhook authorization modes.

3. Admission Controllers

Admitted requests pass through mutating and validating admission controllers:

# List enabled admission controllers
kubectl get --raw /apis/admissionregistration.k8s.io/v1/mutatingwebhookconfigurations
kubectl get --raw /apis/admissionregistration.k8s.io/v1/validatingwebhookconfigurations

# Check if admission webhooks are blocking requests
kubectl get events --field-selector reason=FailedCreate

Mutating admission controllers modify the request (e.g., injecting sidecar containers). Validating controllers reject requests that violate policies.

4. Persistence

After all checks pass, the resource is serialized and stored in etcd:

# Confirm the resource was created
kubectl get deployment myapp -o jsonpath='{.metadata.resourceVersion}'

# The resourceVersion changes with each update
kubectl get deployment myapp -o jsonpath='{.metadata.uid}'

If a request fails at any stage, kubectl returns an error indicating which stage rejected it. Use -v=8 to see the full HTTP response for detailed error diagnosis.