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.