API Server Request Lifecycle in Kubernetes

API Server Request Lifecycle in Kubernetes

Every kubectl command, every controller and every kubelet talks to one component: the API server. This guide follows a single request from the moment it leaves the client to the moment it is safely stored and answered, one checkpoint at a time.

Imagine a very busy city hall with exactly one front door. Everyone who wants something, from a family asking for a birth certificate to a builder asking for a permit, must walk through that door. A guard checks who you are. A clerk checks whether you are allowed to ask for that thing. An inspector checks that your form is filled in properly and may even fix small mistakes for you. Only then is your paper filed in the big archive room, and you get a receipt. Kubernetes works in almost the same way, and the front door of its city hall is called the API server.

1What the API Server Is and Why It Matters

Before following a request, we need to know who is receiving it and why it is the center of the cluster.

Kubernetes is a system that runs and manages containers across many computers. Behind the scenes it keeps a long list of things that should exist: which applications should run, how many copies of each, which network rules apply, which secrets are stored, and so on. The component that guards and serves this list is the kube-apiserver, usually called the API server.

The API server is a web server. It speaks HTTP, mostly using a style called REST, which simply means that things are named by addresses and you use standard actions such as read, create, change and delete. A Deployment, a Pod, a Service or a Secret is each called a resource. When you ask Kubernetes to run an application, you are really asking the API server to create a resource that describes what you want.

Simple Analogy

Think of the API server as the single reception desk of a huge office building. Visitors never walk into the archive room themselves, and nobody is allowed to write directly on the master record. Everything goes through reception, which means the rules are applied the same way to everyone.

Why a single door is a good idea

No other Kubernetes component is allowed to talk to the cluster database directly. The scheduler, the controller manager, the kubelet on each machine, kubectl, your CI pipeline and your monitoring tools all talk to the API server instead. Because of this, there is exactly one place where identity, permissions, rules and recording happen. If you want to know how Kubernetes stays safe and consistent, you start by understanding this door.

The API server is also stateless. It does not keep the master record in its own memory or disk. The record lives in a separate database called etcd. This means you can run several API servers side by side behind a load balancer, and any of them can answer any request.

Term 1

Resource

A kind of object Kubernetes manages, such as Pods, Services or Deployments. Each one has its own address on the API server.

Term 2

Verb

The action being asked for, such as get, list, watch, create, update, patch or delete. Permissions are written using verbs.

Term 3

etcd

The distributed key-value database where the cluster keeps its desired state. Only the API server is supposed to talk to it.

Term 4

Controller

A program that watches resources and works to make reality match what the resources say. Controllers are clients of the API server too.

i
Remember

The API server does not start containers. It records what you want and tells other components about it. Starting containers is the job of the kubelet and the container runtime.

2The Big Picture: A Request’s Journey

A request passes through a fixed series of gates, and failing any gate stops it right there.

When a request reaches the API server it does not go straight to the database. It travels through a pipeline. Each stage asks one question, and the request continues only if the answer is acceptable. At a high level the questions are: who are you, are you allowed to do this, is this request healthy enough to be processed right now, do the cluster rules allow this change, is the object itself well formed, and can it be safely stored?

flowchart LR
  A["Client: kubectl, controller, kubelet"] --> B["TLS and HTTP parsing"]
  B --> C["Authentication"]
  C --> D["Audit and impersonation"]
  D --> E["Priority and fairness"]
  E --> F["Authorization"]
  F --> G["Mutating admission"]
  G --> H["Schema validation"]
  H --> I["Validating admission"]
  I --> J["Write to etcd"]
  J --> K["Response to client"]
        
FIG 1 — The main stages a write request passes through

Notice the shape of the diagram. Early stages are about the caller: identity and permission. Middle stages are about the change: rules and correctness. The last stage is about durability: making sure the change is saved. Read requests, such as listing Pods, skip the admission and write stages, but they still go through identity, permission and flow control.

3
Big questions: who, allowed, valid
1
Database behind the door: etcd
6443
Common secure port for the API
1

Connect and parse

The client opens a secure connection and sends an HTTP request. The server decodes the address, the verb and the body.

2

Prove identity and permission

Authentication decides who is calling. Authorization decides whether that caller may perform this verb on this resource.

3

Apply cluster rules

Admission control may change the object and may reject it. Validation checks that the final object makes sense.

4

Save and answer

The object is stored in etcd, watchers are told, and the client receives a response with the saved object or an error.

Simple Analogy

This is like boarding a flight. You show your passport at the desk (who are you), a gate agent checks your ticket for this exact flight (are you allowed), security scans your bag (do the rules allow what you carry), and only then do you walk onto the plane (the change is made).

3Stage One: Connection, TLS and Request Parsing

Before anyone checks your name, a secure channel must exist and the request must be understood.

Every conversation with the API server begins with a network connection. In a normal cluster the API server listens on a secure port, commonly 6443, and speaks HTTPS. Older clusters once offered an insecure local port, but that was removed many versions ago, so today you should assume everything is encrypted.

What TLS gives you

TLS, short for Transport Layer Security, does two jobs. First, it encrypts the traffic so that nobody on the network can read or change it. Second, it lets the client confirm that it is really talking to the genuine API server and not an imposter. The API server shows a certificate, and the client checks that this certificate was signed by an authority it trusts. That trusted authority information is usually stored in the client’s kubeconfig file.

TLS can also work in the other direction. The server can ask the client to show its own certificate. This is called mutual TLS, and it is one of the ways a client proves who it is. We will return to this in the next chapter.

Simple Analogy

Picture a phone call where you first confirm that the number really belongs to your bank, and then whisper your details so nobody can listen in. TLS is that confirmation and that whisper together.

HTTP and the shape of the address

Once the secure channel is ready, the client sends an HTTP request. Modern clients use HTTP/2, which allows many requests to share one connection. This matters because controllers and kubelets keep connections open for a long time and send many requests through them.

The address in the request tells the API server which resource is wanted. Core resources such as Pods live under one kind of path, while resources that belong to named groups, such as Deployments in the apps group, live under another. The path also includes the version of the API, for example v1, and optionally the namespace and the name of the object. The HTTP method then maps to a Kubernetes verb: reading one object is get, reading a collection is list, a long-running read is watch, a POST creates, a PUT replaces, a PATCH changes part of an object, and a DELETE removes.

What the client wantsHTTP methodKubernetes verb
Read one objectGET on the object pathget
Read a whole collectionGET on the collection pathlist
Keep listening for changesGET with a watch optionwatch
Make a new objectPOSTcreate
Replace an objectPUTupdate
Change part of an objectPATCHpatch
Remove an objectDELETEdelete

The request information step

Early in the pipeline the API server works out a tidy summary of the request: the verb, the API group, the version, the namespace, the resource, the subresource and the name. Every later stage reuses this summary. That is why authorization rules can talk about “list Pods in the team-a namespace” so naturally, because the server has already split the raw address into those parts.

!
Common Mistake

People often think “list” and “get” are the same permission. They are not. A caller who may list Secrets can read every Secret in the namespace, even if it cannot get one by name. Always treat list and watch on sensitive resources as powerful permissions.

4Stage Two: Authentication, Who Are You?

Authentication answers one question only: who is making this request?

Kubernetes does not have a built-in list of human users. There is no “create user” command. Instead, the API server trusts proof that comes from outside and turns that proof into an identity. The result of successful authentication is a small package: a username, a set of groups, and sometimes extra information. Everything after this stage uses that package.

The authenticators

The API server can be configured with several authentication methods at once. It tries them one after another. The first method that recognizes the credentials wins. If none of them recognize the request, the server answers with 401 Unauthorized, unless anonymous access is enabled.

Method 1

Client Certificates

The caller shows a certificate signed by the cluster’s certificate authority. The common name becomes the username and the organization fields become groups.

Method 2

Service Account Tokens

Programs running inside Pods present a signed token that proves which service account they belong to. This is how most in-cluster software logs in.

Method 3

OpenID Connect Tokens

Humans sign in through a company identity provider, and the API server trusts the signed identity token that provider issues.

Method 4

Webhook Token Authentication

The API server asks an outside service whether a presented token is valid and who it belongs to.

Method 5

Authenticating Proxy

A trusted front proxy authenticates the user and passes the name along in special headers. The API server trusts those headers only from that proxy.

Method 6

Bootstrap and Static Tokens

Simple tokens used while joining new machines to a cluster, or in small test setups. Static tokens are discouraged for real use.

Simple Analogy

A club may accept a membership card, a staff badge, or a letter from a trusted partner company. Each is a different kind of proof, but the doorman only needs one of them to be real to let you into the lobby.

Service account tokens in more detail

Applications inside the cluster need an identity too. Kubernetes gives each Pod a service account, and the kubelet places a token for it inside the Pod. In current versions this token is short-lived, tied to the specific Pod and to an intended audience, and is refreshed automatically before it expires. This is much safer than the old style of long-lived tokens stored in Secrets, which are no longer created automatically.

Anonymous requests

If a request carries no credentials and anonymous access is turned on, the API server treats the caller as the user system:anonymous in the group system:unauthenticated. Authorization rules then decide what, if anything, such a caller may do. Many clusters keep a tiny number of public paths for health checks, and nothing else.

i
Good Practice

Prefer short-lived credentials and an external identity provider for people. Certificates that last for a year and sit on laptops are hard to take back if someone loses a device.

Authentication also decides one more thing that is easy to miss: it removes the credentials from the request. After this stage, later stages see the identity but no longer see the raw token. This stops secrets from leaking deeper into the system by accident.

5The Handler Chain, Impersonation and Audit Recording

The API server wraps its real work in layers of filters, a bit like layers of an onion.

Inside the API server code, a request does not move through the stages by magic. Each stage is a small piece of code called a filter or handler, and the filters are wrapped around each other. The request enters the outermost layer, passes inward through each one, and finally reaches the code that actually reads or writes the resource. The collection of layers is known as the handler chain.

The outer layers handle general safety. One recovers from crashes so that a bug in one request does not bring down the whole server. One attaches a time limit so that ordinary requests cannot hang forever; the default is about a minute for normal requests, while long-running ones such as watch are treated differently. One records the time the request arrived. Others add headers and measure latency. The exact order can shift a little between Kubernetes versions, but the idea stays the same.

Simple Analogy

An onion has many thin layers, and you must peel each one before you reach the middle. A request has to pass each filter before it reaches the real resource code, and every filter can say “stop here” and send an error back.

Audit recording starts

Once the caller is known, the audit filter begins writing a record of what is happening. The audit system can capture the identity, the time, the verb, the address, and, depending on how it is set up, the request body and the response body. We look at audit in more detail in a later chapter, but it is important to know that it begins early so that even rejected requests leave a trace.

Impersonation

Kubernetes allows one identity to act as another. This is called impersonation. A request can carry special headers saying “I am user A, but please treat me as user B”. The API server first checks that user A is allowed to impersonate user B. If so, the identity is swapped, and every later stage sees user B.

Impersonation is useful for administrators who want to test what a limited user can do without asking for that user’s password. It is also used by some platforms that sit in front of the cluster and act on behalf of their own users. Because it is so powerful, the permission to impersonate should be handed out very carefully.

!
Common Mistake

Granting permission to impersonate “all users” or “all groups” is almost the same as giving away full admin rights, because the caller can pretend to be any powerful identity.

6Flow Control: API Priority and Fairness

Even permitted requests must wait their turn when the server is busy, and some turns are more important than others.

An API server can be overwhelmed. A broken script that lists every Pod in a huge cluster in a tight loop can eat up so much capacity that the scheduler and the controllers cannot get their own requests through. When that happens the whole cluster stops reacting, even though nothing is technically broken. To prevent this, the API server includes a feature called API Priority and Fairness, often shortened to APF.

How APF thinks

APF sorts every incoming request into a group using rules called flow schemas. Each flow schema points at a priority level, which is a pool of capacity. Important traffic, such as leader election by control plane components and requests from nodes, is placed in high-priority pools. Ordinary workloads from users and applications go into general pools. Within a pool, requests are separated into flows, for example by user, so that one noisy caller cannot crowd out everyone else.

If there is room, the request runs immediately. If not, it waits in a queue. APF uses a careful method of picking queues so that a noisy caller is likely to fill only its own queues, leaving other callers unaffected. If the queue is full or the wait is too long, the API server rejects the request with status 429 Too Many Requests and a hint about how long to wait before trying again.

flowchart TD
  R["Incoming request"] --> F["Match a flow schema"]
  F --> P["Choose a priority level"]
  P --> Q{"Spare capacity?"}
  Q -->|Yes| X["Run now"]
  Q -->|No| W["Wait in a fair queue"]
  W --> T{"Queue full or too slow?"}
  T -->|No| X
  T -->|Yes| E["Reject with 429 and retry hint"]
        
FIG 2 — How API Priority and Fairness decides what to do with a request
Simple Analogy

At a hospital emergency room, a person with chest pain is seen before someone with a sprained wrist, but among people with similar needs the queue is fair and no single family can take every chair. APF gives the cluster the same kind of sensible triage.

Advantages

  • Protects critical control plane traffic during overload
  • Stops one noisy client from starving others
  • Gives clear signals with 429 and retry hints
  • Can be tuned for your own workloads

Disadvantages / Trade-offs

  • Adds a new set of settings to understand
  • Wrong classification can slow down useful traffic
  • Clients that ignore 429 and retry instantly make things worse

Older clusters used a simpler approach with two global limits on how many requests may be in flight at the same time, one for reads and one for writes. Those limits still exist as an outer safety net, but APF is the modern and fairer mechanism. Long-running requests such as watches do not hold a slot for their entire life. They are counted mainly while the initial data is being sent.

i
Good Practice

Write your own clients so that they respect the retry hint in a 429 response and back off with some random delay. A thousand clients retrying at exactly the same instant only create a bigger traffic spike.

7Stage Three: Authorization, Are You Allowed?

Knowing who you are is not enough. The server must also decide whether you may do this exact thing.

Authorization takes the identity from authentication and the request summary from earlier, and checks them against a set of rules. It looks at the user, the groups, the verb, the API group, the resource, the subresource, the name and the namespace. If the rules allow the action, the request moves on. If not, the answer is 403 Forbidden.

Authorization modes

A cluster administrator picks one or more authorization modes, and the API server asks them in order. Each mode can say allow, deny, or “no opinion”. The first mode that gives a clear allow or deny decides the outcome. If every mode has no opinion, the request is denied. The most common set is Node plus RBAC.

Mode 1

Node

A special mode that gives each kubelet access only to the objects related to the Pods running on its own machine.

Mode 2

RBAC

Role-based access control. Permissions are grouped into roles, and roles are attached to users, groups or service accounts.

Mode 3

Webhook

The API server asks an outside service to decide. Useful when a company already has a central policy system.

Mode 4

ABAC

An older attribute-based method using a static policy file. It is rarely chosen today because changing it needs a restart.

How RBAC works

RBAC has four main objects. A Role lists permissions inside one namespace. A ClusterRole lists permissions that can apply cluster-wide or to resources that are not in any namespace, such as Nodes. A RoleBinding attaches a role to people or programs inside a namespace. A ClusterRoleBinding attaches a cluster role everywhere.

RBAC is purely additive. There are no deny rules. A caller gets the combined permissions of everything bound to them, and nothing more. This keeps the model simple but means you must be careful about what you add.

Simple Analogy

A role is like a key ring that opens certain doors, such as “kitchen keys” or “storeroom keys”. A binding is the act of handing that key ring to a particular person. Nobody ever hands out a key that locks a door against someone, they only add keys that open doors.

ObjectScopeWhat it does
RoleOne namespaceLists allowed verbs on resources in that namespace
ClusterRoleWhole clusterLists allowed verbs on any resource, including non-namespaced ones
RoleBindingOne namespaceGives a role or cluster role to subjects inside that namespace
ClusterRoleBindingWhole clusterGives a cluster role to subjects everywhere

Paths that are not resources

Some addresses on the API server are not Kubernetes resources, for example health checks, version information and metrics. These are called non-resource URLs, and RBAC can allow or deny them with separate rules.

!
Common Mistake

Binding the all-powerful cluster-admin role to a CI pipeline “just to make it work” is one of the most common security problems in real clusters. Give automation only the verbs and resources it needs.

One subtle point is that the permission to create Pods is more powerful than it looks. A person who can create Pods may be able to mount Secrets or run privileged containers, which gives indirect access to far more than Pods. When designing roles, think about what a permission allows in practice, not only what it is named.

8Stage Four: Admission Control

The request is from a known caller who is allowed to ask, but the cluster still gets to inspect and adjust what is being requested.

Authentication and authorization look at the caller. Admission control looks at the content. It runs only for requests that would change something: create, update, delete, and a few special connect actions such as opening a shell into a Pod. Plain reads never go through admission.

Admission control is made of many small pieces called admission controllers. Some are built into the API server. Others are added by you using webhooks or policy objects. They run in two phases, and the order is important: first the mutating phase, then validation of the object’s shape, then the validating phase.

flowchart LR
  A["Authorized write request"] --> B["Mutating admission: may change the object"]
  B --> C["Object schema validation"]
  C --> D["Validating admission: may only accept or reject"]
  D --> E["Persist to etcd"]
        
FIG 3 — The three steps of admission and validation

The mutating phase

Mutating controllers are allowed to edit the object. They fill in missing values, add labels, inject extra containers, or attach default settings. For example, if you create a PersistentVolumeClaim without naming a storage class, a default-storage-class controller can add the cluster’s default one. The mutating controllers run one after another, so each one sees the changes made by the one before it.

The validating phase

After the object has its final shape and has passed schema checks, validating controllers get their turn. They are not allowed to change anything. They only say yes or no. Because they cannot change the object, they can safely run at the same time, which makes this phase faster. If any one of them says no, the whole request is rejected.

Simple Analogy

Imagine submitting a school form. First a helpful teacher fills in anything you left blank and fixes your spelling, this is mutation. Then a principal reads the final version and either stamps it or sends it back, this is validation. The principal never edits, only decides.

Some built-in admission controllers

Built-in 1

NamespaceLifecycle

Refuses to create objects in a namespace that is being deleted or does not exist.

Built-in 2

LimitRanger

Applies default resource requests and limits, and rejects objects that break the allowed range.

Built-in 3

ResourceQuota

Stops a namespace from using more than its fair share of CPU, memory or object counts.

Built-in 4

ServiceAccount

Attaches the right service account and token settings to new Pods.

Built-in 5

PodSecurity

Enforces standard safety levels on Pods per namespace, for example forbidding privileged containers.

Built-in 6

NodeRestriction

Limits what each kubelet may change, so a compromised node cannot rewrite other nodes or their Pods.

i
Did You Know

You can ask the API server to run a request through all the stages, including admission, without saving anything. This is called a dry run, and it is a safe way to find out whether a change would be accepted.

9Admission Webhooks and Policy Rules

Webhooks and policy objects let you add your own rules to the pipeline without changing Kubernetes itself.

Built-in controllers cannot know your company’s special rules. Maybe every Pod must have an owner label, or images may only come from an approved registry, or every container must define memory limits. Kubernetes gives you two main ways to add such rules.

Admission webhooks

A webhook is a small web service that you run. You register it with the API server and tell it which resources and verbs you care about. When a matching request arrives, the API server sends the object to your service inside a message called an AdmissionReview. Your service replies with allow or deny, and, if it is a mutating webhook, a description of the changes to apply.

Because the API server waits for the webhook, your service becomes part of the request path. This brings several settings that matter a great deal:

1

Failure policy

Decides what happens if the webhook is down or too slow. “Fail” rejects the request, which is safe but can block work. “Ignore” lets the request through, which keeps the cluster moving but skips your rule.

2

Timeout

How long the API server waits for an answer before giving up. It is a small number of seconds, and every slow webhook adds delay to every matching request.

3

Selectors

Namespace and object selectors narrow down which requests are sent to the webhook, so it does not see traffic it does not need.

4

Side effects

A declaration of whether the webhook does anything outside itself. This matters for dry runs, which must not cause real changes.

5

Reinvocation

Because later mutating webhooks may change the object after an earlier one ran, a webhook can ask to be called again so that its rule still holds.

Simple Analogy

A webhook is like a building that asks an outside security company to approve each visitor by phone. It is flexible, but if the phone line is busy, everyone waits at the door, so you must decide in advance whether to let people in or keep them out when the phone does not answer.

Built-in policy rules

Running a webhook server just to enforce a simple rule is a lot of effort. Newer Kubernetes versions offer validating admission policies, where the rule is written as an expression inside a Kubernetes object, using a small expression language called CEL. The API server evaluates the rule itself, with no extra network call. This is faster, simpler and more reliable. A similar approach for mutations is maturing in recent versions.

Advantages

  • Policy rules run inside the API server with no network hop
  • No extra service to deploy, patch or keep available
  • Rules are plain objects that can be reviewed like any other change
  • Webhooks remain available for complex logic

Disadvantages / Trade-offs

  • Expressions can express less than a full program can
  • Webhooks add latency and a point of failure
  • Policy objects need to be tested carefully before being enforced
!
Common Mistake

A webhook with a “Fail” policy that also applies to the namespace where the webhook itself runs can create a deadlock. If the webhook Pod is down, it cannot be restarted, because creating the new Pod needs the webhook’s approval. Always exclude the webhook’s own namespace and critical system namespaces.

10Versions, Defaults, Validation and Conversion

The same object can be written in several API versions, so the server must translate and double-check it.

Kubernetes APIs evolve. A resource may start as a beta version, become stable, and later have an older version retired. The API server can understand several versions of the same resource at once, so that old tools keep working while new tools use new features. To make this possible it uses a trick: it keeps one internal form of every object, and converts to and from the version that the client used.

Decoding and defaulting

When the body of a request arrives, the API server decodes it from JSON, YAML or a compact binary format called protobuf. It then converts it to the internal form and fills in default values for fields that the client did not set. For instance, a Pod without a restart policy gets the standard default. This is part of the reason that an object you read back often looks larger than what you submitted.

Validation

Next comes validation. The API server checks that required fields are present, that names follow the allowed format, that numbers are in range, that fields that cannot change are not being changed, and that fields that belong together make sense together. For custom resources, defined by CustomResourceDefinitions, the API server checks the object against the schema supplied by the definition. If a field is unknown or has the wrong type, the request can be rejected with status 422 Unprocessable Entity. Newer versions can also warn about or reject unknown fields, which catches spelling mistakes in field names that would otherwise be silently ignored.

Simple Analogy

A translator at an international meeting turns every speaker’s language into one shared language that the chairperson understands, and turns the replies back again. The internal version of an object is that shared language, and conversion is the translator.

Storage version and conversion

Although many versions can be served, each resource has one storage version, which is the version actually written into etcd. When the object is read through a different version, the server converts it on the way out. For custom resources that have several versions, the definition can say how conversion happens: either simply by changing the version label, or by calling a conversion webhook that you provide.

StepWhat happensWhat can go wrong
DecodeBytes are turned into an objectBad syntax gives a 400 error
ConvertObject moves to the internal formBroken conversion webhook gives a 500 error
DefaultMissing fields get standard valuesSurprising defaults confuse readers
ValidateRules and schemas are checkedInvalid fields give a 422 error
i
Good Practice

Use the newest stable API version of each resource in your files. Old versions are removed on a published schedule, and a manifest that works today can fail after a cluster upgrade if it uses a retired version.

11Stage Five: Persistence in etcd

After every check has passed, the object is finally written to the cluster’s memory.

The object is now complete and approved. The API server hands it to its storage layer, which turns it into bytes and stores it in etcd. Built-in resources are usually stored in the compact protobuf format, while custom resources are stored as JSON. Each object is saved under a key that looks like a file path, grouped by resource type and namespace, so that the server can find a whole collection quickly.

Why etcd is trusted with this job

etcd is a distributed database. It runs on several machines, commonly three or five, and uses an agreement method called Raft. A write is only considered done when a majority of the etcd members have recorded it. This means the cluster record survives the loss of a machine, and two members can never disagree about what the latest truth is.

Simple Analogy

Imagine five clerks each holding a copy of the town record book. A new entry only counts after at least three of them have written it down. If one clerk falls ill, the other four still agree, and the town never loses its history.

3 or 5
Usual number of etcd members
Majority
Needed to confirm every write
~1.5 MiB
Default etcd limit for one request

Encryption at rest

By default, data in etcd is stored without encryption. The API server can be told to encrypt chosen resources, such as Secrets, before they are written, using a key that is kept in its configuration or in an external key management service. Anyone who steals a backup of etcd then sees only scrambled data. Encryption at rest does not replace access control, but it adds a valuable second wall.

i
Good Practice

Treat etcd like the vault of the cluster. Allow only the API servers to connect, require mutual TLS, back it up on a schedule, and test restoring that backup before you ever need it.

12Concurrency, Resource Versions and Deletion

When many clients edit the same object, the server needs a fair way to avoid lost changes.

Every stored object carries a field called resourceVersion. It comes from the revision counter of etcd and changes every time the object changes. Clients should treat it as an opaque label and never do arithmetic on it. Its purpose is to enable optimistic concurrency.

Optimistic concurrency

Suppose two people read the same object, and both change it. When the first person saves, all is fine. When the second person saves, they are still holding the old resourceVersion. The API server notices that the stored version has moved on and refuses the update with status 409 Conflict. The second person must read the fresh object, re-apply their change, and try again. This stops one editor from silently overwriting the other.

Simple Analogy

Two friends edit the same shared recipe card. Each time someone saves, the card gets a new page number. If you try to save a change based on page 7 but the card is already on page 8, the librarian asks you to look at page 8 first so you do not erase your friend’s work.

Patching and server-side apply

Replacing a whole object is risky when several tools manage different fields. Kubernetes therefore supports patching, which changes only chosen fields. A newer approach, called server-side apply, lets the API server track which tool owns which field. When two tools try to control the same field with different values, the server reports a conflict instead of letting them fight silently.

Deleting is a process

Deleting an object is not always instant. If the object has finalizers, which are labels that mean “someone must clean up first”, the API server only sets a deletion timestamp. Controllers that own the finalizers do their cleanup and then remove their label. When no finalizers remain, the object is truly removed. Pods also have a graceful stop period, so applications can finish what they are doing. Objects can have owners, and when an owner is deleted, a garbage collector removes the objects that depended on it, according to the chosen deletion policy.

!
Common Mistake

Removing finalizers by hand to make a stuck object disappear can leave real resources, such as cloud disks or load balancers, behind and still costing money. First find out which controller is meant to clean up and why it is stuck.

13The Response and the Audit Record

The journey ends with a reply to the caller and a permanent note in the logbook.

Once etcd confirms the write, the API server builds a response. For a create, the answer is status 201 Created along with the saved object, now holding generated fields such as the unique identifier, the creation time and the resourceVersion. For a read or update, the answer is 200 OK. For a delete that still has cleanup to do, the answer may be 202 Accepted. If anything went wrong earlier, the response is an error with a small structured body that explains the reason.

Audit logging

In parallel with all of this, the audit system has been recording the request. Audit records are written at defined moments, called stages: when the request is received, when the response starts for long-running requests, when it completes, and if a panic occurs. An audit policy decides how much detail to keep for each kind of request, using four levels.

Audit levelWhat is recordedTypical use
NoneNothingNoisy, harmless requests such as health checks
MetadataWho, what, when and the result, but not the bodiesDefault for most requests, including Secrets
RequestMetadata plus the request bodyImportant changes where you want to see what was asked
RequestResponseMetadata, request body and response bodyRare, high-value investigation needs

Audit records can be written to a file on the control plane machine or sent to an external service. They answer the questions that matter after an incident: who deleted that namespace, from which address, and at what time.

i
Good Practice

Never record full request or response bodies for Secrets. Doing so copies sensitive values into your logs, where far more people may be able to read them.

14Reads, Lists and the Watch Mechanism

Most traffic to the API server is not writing. It is controllers and tools asking what changed.

A cluster contains many programs that need to react quickly to changes. The scheduler needs to know the moment a new unscheduled Pod appears. The kubelet needs to know when a Pod is assigned to its machine. Asking again and again, “anything new?”, would flood the API server. Kubernetes solves this with watch.

List, then watch

A client first lists the current objects and remembers the resourceVersion of that list. It then opens a watch starting from that point. The API server keeps the connection open and streams small messages, each saying that an object was added, modified or deleted. Occasional bookmark messages let the client keep track of its position. If the client falls too far behind and its position is no longer available, the server answers with 410 Gone, and the client must list again.

Simple Analogy

Instead of phoning the pizza shop every minute to ask if your order is ready, you ask them to call you the moment it is done. Watch is that phone call. If you miss too many calls, you ring the shop once to get the full status again, which is the list.

The watch cache

If every client’s read went all the way to etcd, the database would quickly become the bottleneck. The API server therefore keeps its own in-memory copy of each resource type, kept up to date by watching etcd. This is called the watch cache. Many reads and all watches are served from it. Clients can choose to accept slightly older data from the cache, which is fast, or ask for the very latest data, which may be sent to etcd for confirmation.

Pagination

Listing a huge collection in one answer can use a great deal of memory on both sides. Clients can ask for results in pages by setting a page size and following a continue token. Well-behaved tools do this by default for large lists.

sequenceDiagram
  participant C as Controller
  participant A as API Server
  participant W as Watch Cache
  participant E as etcd
  E->>W: Stream of changes
  C->>A: List Pods
  A->>W: Read current state
  W-->>A: Objects and resource version
  A-->>C: Full list
  C->>A: Watch from that version
  E->>W: New Pod written
  W-->>A: Event added
  A-->>C: Stream event
        
FIG 4 — List and watch served through the watch cache

Client libraries package this pattern in a helper often called an informer. An informer lists, watches, stores a local copy, and tells the controller about each change. Because the local copy answers most questions, the controller rarely has to ask the API server again.

15Special Requests: Subresources, Streams and Extensions

Not every request follows the plain read-and-write path. Some open tunnels, and some are handed to other servers.

Subresources

Some resources have extra addresses attached to them, called subresources. A Pod has a status subresource, a scale subresource exists for Deployments, and Pods have logs, exec and port-forward subresources. Each is authorized separately. This allows, for example, a monitoring tool to read logs without being able to open a shell into a container.

Logs, exec and port-forward

Logs and shells are not stored by the API server. When you ask for them, it acts as a middleman. It connects to the kubelet on the right machine and carries the traffic back to you. For interactive sessions the connection is upgraded into a long-lived streaming connection. For this reason the API server must be able to reach every node’s kubelet, and the kubelet must trust the API server.

Reading logs

The client asks the API server for the logs of a Pod. The server finds the node, calls the kubelet, and streams the text back. The API server stores none of it.

Opening a shell in a container

The API server checks permission for the exec subresource, runs admission for the connect action, and then links the user’s terminal to the kubelet, which links to the container runtime.

Custom resources and aggregation

Kubernetes can be extended with your own resource types. There are two ways. With CustomResourceDefinitions, you describe your new type and its schema, and the built-in extensions server begins to serve it with the same authentication, authorization, admission and storage behavior as built-in types. With the aggregation layer, you run your own API server and register it, and the main server forwards matching requests to it after checking identity and permission. The metrics API is a well-known example of this second style.

Inside the main process, three servers are chained like a relay. The aggregator gets the request first. If the address belongs to a registered extension server, it forwards it. If not, it passes the request to the core API server, which serves built-in resources. If that does not know the address either, the request passes to the extensions server for custom resources. If nobody knows it, the answer is 404 Not Found.

flowchart LR
  R["Request"] --> G["Aggregator"]
  G -->|Registered extension| X["Extension API server"]
  G -->|Otherwise| K["Core API server"]
  K -->|Not a built-in type| C["Custom resources server"]
  C -->|Unknown| N["404 Not Found"]
        
FIG 5 — How one front door hands requests to the right server
Simple Analogy

It is like a hotel concierge who first checks if the guest wants a partner service such as a tour company. If not, the concierge uses the hotel’s own services. If the hotel has no such service either, the guest is told politely that it does not exist.

16A Worked Example: Creating a Deployment

Let us follow one real action from your keyboard all the way to a running container.

You run a command to create a Deployment named web that asks for three copies of an application. Here is what happens, in order.

1

The client prepares the call

Your tool reads the kubeconfig, finds the server address and your credentials, and sends a secure POST request to the Deployments collection in your namespace.

2

Identity and permission are checked

The API server recognizes your certificate or token, then checks RBAC to confirm that you may create Deployments in that namespace.

3

Admission and validation run

Defaults are added, quotas are checked, any mutating webhooks run, the schema is validated, and then validating policies approve it.

4

The Deployment is stored

The object is written to etcd, you receive a 201 response, and watchers are told that a new Deployment exists.

5

Controllers react through the same door

The Deployment controller sees the new object and creates a ReplicaSet. The ReplicaSet controller creates three Pod objects. Each of these creations is another full trip through the API server.

6

Scheduling and starting

The scheduler sees Pods with no node, picks machines, and writes the choice back through the API server. Each kubelet sees Pods assigned to it, starts the containers, and reports status back through the API server.

sequenceDiagram
  participant U as You
  participant A as API Server
  participant E as etcd
  participant D as Deployment Controller
  participant S as Scheduler
  participant K as Kubelet
  U->>A: Create Deployment
  A->>A: Authenticate, authorize, admit, validate
  A->>E: Store Deployment
  A-->>U: 201 Created
  A-->>D: Watch event for new Deployment
  D->>A: Create ReplicaSet and Pods
  A->>E: Store Pods
  A-->>S: Watch event for unscheduled Pods
  S->>A: Bind Pods to nodes
  A-->>K: Watch event for assigned Pods
  K->>A: Report Pod status
        
FIG 6 — Every component talks to the API server, never to each other
“Kubernetes components never call each other. They all talk to the API server, and the server tells them what changed.”

Notice that you received your reply at step four, long before any container was running. The API server’s promise is only that your wish has been safely recorded. Making the wish come true is the work of controllers, and that work happens afterwards, step by step. This is why a command can succeed and yet the application may still be starting for a while.

17Security Hardening of the Request Path

Each stage of the lifecycle is also a security control, and each can be tightened.

Because the API server is the one door to the cluster, protecting it is the most valuable security work you can do. A useful way to think is to walk the same path a request takes and ask, at each stage, what could go wrong.

Network

Limit who can connect

Do not expose the API server to the whole internet if you can avoid it. Use private endpoints, firewalls, or allowed address ranges.

Identity

Use short-lived credentials

Prefer identity provider tokens for people and bound service account tokens for programs. Turn off anonymous access unless you need it.

Permission

Least privilege

Give each person and program only the verbs and resources they need. Review bindings often, and watch for wide wildcards.

Policy

Enforce rules at admission

Block privileged Pods, unknown image registries and missing limits using built-in policy features or trusted webhooks.

Data

Encrypt at rest

Turn on encryption for Secrets and protect the keys, preferably in an external key service.

Evidence

Keep good audit logs

Record metadata for everything and ship the logs somewhere that an attacker with cluster access cannot easily erase.

Simple Analogy

A bank vault does not rely on one lock. It has a guarded street, a front door, a teller check, a vault door, cameras and a logbook. If one layer fails, the next still protects the money. The API server pipeline gives you the same layered defense.

!
Common Mistake

Believing that a private network alone makes the API server safe. A stolen laptop, a leaked token or a compromised pod inside the network can still reach the door, so every later stage must stay strict.

18Monitoring, Logging and Metrics

If you cannot see how the front door is behaving, you will only learn about problems when users complain.

The API server exposes metrics that describe its own health, in a format that common monitoring systems understand. A few of them tell you most of what you need.

What to watchTypical metric familyWhat it tells you
Request volume and errorsapiserver_request_totalHow many requests arrive and how many fail, by verb, resource and code
Request speedapiserver_request_duration_secondsHow long requests take, so you can spot slow resources
Flow control pressureapiserver_flowcontrol_*Which priority levels are queueing or rejecting requests
Webhook delayapiserver_admission_webhook_admission_duration_secondsWhether a slow webhook is slowing down every write
Database speedetcd_request_duration_secondsHow long the API server waits on etcd
Object countsapiserver_storage_objectsWhich resource types are growing too large

Reading the signals

A sudden rise in 429 responses points to flow control being triggered, so look for a noisy client. Slow writes with healthy reads point to etcd or to a slow admission webhook. Many 401 or 403 responses from one source can mean a broken credential or an intruder trying doors. A rapid growth in the count of one object type, such as Events or Jobs, often means a controller is misbehaving.

Tracing and client-side clues

Recent versions can produce distributed traces of a request as it moves through the server, including calls to etcd and to webhooks. On the client side, turning up the verbosity of kubectl shows the exact addresses, headers and response codes that were used, which is often the quickest way to understand a failure from the user’s point of view.

i
Good Practice

Set alerts on error ratio and on slow request percentiles, not just on averages. Averages hide the small number of very slow requests that actually hurt your controllers.

19Anti-Patterns to Avoid

These mistakes appear again and again in real clusters, and each one harms the request lifecycle in a different way.

ANTI-PATTERN-01 Avoid
Problem

Polling the API server with repeated list calls every few seconds to see if anything changed.

Why It’s Harmful

Each list can be large, and hundreds of clients doing it at once can use up request capacity, push up memory use on the server, and trigger flow control that slows down important components.

Correct Approach

List once, then watch, using an informer from a client library so that the program keeps a local copy and reacts to events.

ANTI-PATTERN-02 Avoid
Problem

A critical admission webhook with a “Fail” policy that covers every namespace, including its own and the system namespaces.

Why It’s Harmful

If the webhook service goes down, new Pods cannot be created, even the Pod that would bring the webhook back. The cluster can become stuck and need manual repair.

Correct Approach

Exclude the webhook’s own namespace and system namespaces, keep timeouts short, run several replicas, and consider built-in policy rules for simple checks.

ANTI-PATTERN-03 Avoid
Problem

Giving automation tools the cluster-admin role for convenience.

Why It’s Harmful

A leaked pipeline token then equals full control of every resource and every Secret in the cluster, and an audit log cannot undo that damage.

Correct Approach

Create narrow roles listing exactly the resources and verbs needed, bind them per namespace, and rotate or expire the credentials.

ANTI-PATTERN-04 Avoid
Problem

Storing huge amounts of data, such as large files or big logs, inside Kubernetes objects such as ConfigMaps.

Why It’s Harmful

Large objects slow down writes, bloat etcd, enlarge every watch event, and may exceed request size limits.

Correct Approach

Keep objects small and store bulk data in object storage or a proper database, keeping only a reference in the object.

ANTI-PATTERN-05 Avoid
Problem

Retrying failed requests immediately and without limit.

Why It’s Harmful

When the server is already busy, a crowd of instant retries makes it busier and turns a short slowdown into a long outage.

Correct Approach

Honor retry hints, use growing waits with random variation, and set a maximum number of attempts.

20Scaling, Performance and Design Trade-offs

A single front door is simple and safe, but it must be built to handle a crowd.

Because the API server is stateless, the usual way to scale is to run several copies behind a load balancer. Reads and watches are served from each copy’s own memory, which spreads the load nicely. Writes still all end up in etcd, so etcd is often the real limit on how fast a very large cluster can change. Fast disks, low network delay between etcd members, and keeping object sizes small all help.

Cluster size also matters. The number of objects, the number of watchers, and the rate of change all affect memory use and latency. Many teams therefore split very large environments into several clusters instead of growing one without limit.

Advantages

  • One place to enforce identity, permission and policy
  • Every change is recorded and can be audited
  • Components stay independent and only know the API
  • Stateless servers are easy to replace and multiply
  • Watch makes the whole system event driven and responsive

Disadvantages / Trade-offs

  • The API server and etcd are critical, so their failure stops all changes
  • Every extra webhook adds delay to writes
  • Large clusters can generate heavy watch and list traffic
  • The pipeline has many settings, so mistakes are easy to make
i
Good Practice

Running workloads continue to run even if the API server is briefly unavailable, because kubelets keep managing the containers they already have. What you lose during an outage is the ability to change or observe the cluster, so plan your upgrades and backups with that in mind.

21Troubleshooting by Status Code

The response code tells you which stage of the journey rejected the request.

Because each stage has its own typical error, you can often locate a problem just by reading the number. This turns a confusing failure into a short list of places to look.

CodeMeaningStage that usually causes itFirst thing to check
400Bad RequestDecodingIs the body valid and in the expected format?
401UnauthorizedAuthenticationIs the token expired or the certificate untrusted?
403ForbiddenAuthorization or admissionDoes RBAC allow this verb, or did a policy deny it?
404Not FoundRoutingIs the resource type, version or name correct?
409ConflictPersistenceDid someone else change the object, or does it already exist?
410GoneWatchHas the client fallen behind and needs to list again?
422Unprocessable EntityValidationWhich field failed the rules?
429Too Many RequestsFlow controlWho is the noisy client, and are retries backing off?
500Internal ErrorServer or webhookIs a webhook or conversion service failing?
503 or 504Unavailable or TimeoutServer, etcd or extension serverIs etcd healthy and is an extension server reachable?

A calm way to investigate

Start with the code. Then look at the message body, because Kubernetes errors usually name the reason and often the exact field. Next, check the audit log to confirm which identity made the request. For 403 errors, an authorization check tool can show whether RBAC allowed the action, which helps you separate permission problems from admission denials. For slow or failing writes, look at webhook and etcd latency metrics before blaming the application.

!
Common Mistake

Treating every 403 as a missing role. A 403 can also come from an admission rule that rejects the object. Read the message text to tell the two apart.

22Real-World Examples

The same lifecycle powers very different kinds of teams and platforms.

Managed cloud clusters

Managed Kubernetes services from the major cloud providers run the API servers and etcd for you. You still send the same requests and face the same stages, but the provider handles scaling, patching and backups, and often adds integrations for identity and audit logs.

Policy-driven platform teams

Platform teams use admission policy rules to guarantee that every workload has owner labels, resource limits and approved images before it is ever stored, so that standards are enforced automatically instead of through review meetings.

GitOps and delivery tools

Tools that keep clusters in sync with a Git repository act as busy API clients. They rely on watch to notice drift and on server-side apply to share ownership of fields cleanly with other tools.

Operators for databases and queues

Operators add custom resources, such as a database cluster object, through CustomResourceDefinitions. Creating one travels the same path as a Pod, and a controller then does the real work of setting up the database.

Autoscaling and metrics

Autoscalers read usage numbers through the aggregated metrics API and then change replica counts through the scale subresource. Both steps are ordinary requests, authorized and audited like any others.

Security and compliance reviews

Auditors request evidence of who changed what and when. A well-configured audit policy, with logs stored outside the cluster, answers those questions directly from the lifecycle’s own records.

23Frequently Asked Questions

Short answers to questions that beginners often ask about the request lifecycle.

Q1Does a read request go through admission control?

No. Admission runs only for requests that create, change or delete objects, and for special connect actions such as opening a shell. Reads still pass authentication and authorization.

Q2What is the difference between authentication and authorization?

Authentication decides who you are. Authorization decides what that identity is allowed to do. A person can be authenticated perfectly and still be forbidden.

Q3Why does mutating admission run before validating admission?

Validators should judge the final form of the object. If mutation ran afterwards, a change could slip in that no validator had seen.

Q4Can I talk to etcd directly instead of using the API server?

Technically possible for administrators, but it bypasses authentication, authorization, admission, validation and audit, and can corrupt the cluster. It should not be part of normal operations.

Q5What happens to running Pods if the API server goes down?

They keep running, because the kubelet on each machine continues to manage the containers it already has. New changes, scaling and replacements cannot happen until the API server returns.

Q6Why did my command succeed but my application is not running yet?

Success means the object was stored. Scheduling, image downloads and container start happen afterwards through controllers and kubelets, and can take time or fail separately.

Q7What does a 409 Conflict mean when I update an object?

Someone else changed the object after you read it, so your copy is out of date. Read it again, reapply your change and retry. Server-side apply can help when several tools manage the same object.

Q8Is a dry run really safe?

A dry run goes through all the checks without saving the object. Webhooks that declare side effects must not act on dry runs, which is why that declaration matters.

Q9How does the API server know which version of a resource to store?

Each resource has a chosen storage version. Requests in other versions are converted to it before saving, and converted back when read.

Q10Why do controllers use watch instead of asking repeatedly?

Watch delivers changes the moment they happen and uses far fewer resources than repeated questions. It makes the whole system react quickly and keeps the API server calm.

Q11Can authorization rules deny a specific action?

RBAC has no deny rules, it only adds allowed actions. To block something, you remove the permission, or use admission policy or a webhook authorizer that can deny.

24Summary and Key Takeaways

Every action in Kubernetes begins as a request to the API server, and every request follows the same disciplined path. A secure connection is made, identity is proven, the request is placed fairly in line, permission is checked, the content is adjusted and judged by admission rules, the object is validated and converted, and finally it is saved in etcd and announced to every watcher. Understanding this path turns Kubernetes from a mysterious system into a predictable one, because each error, delay and security control maps to a specific stage you can inspect.

Key Takeaways

  • One front door — all components and users talk to the API server, and only the API server talks to etcd.
  • Who, then allowed — authentication proves identity, authorization decides permission, and RBAC only adds permissions, it never subtracts them.
  • Mutate, validate, then store — admission changes the object first and judges it second, so validators always see the final form.
  • Fairness protects the cluster — API Priority and Fairness keeps critical traffic moving and answers overload with 429 and a retry hint.
  • Watch beats polling — list once and watch for changes, using informers and the watch cache to keep load low.
  • Webhooks are part of the path — their speed and failure policy affect every matching write, so design them with care or prefer built-in policy rules.
  • Codes point to stages — 401, 403, 409, 422 and 429 each tell you where to look, which makes troubleshooting fast and calm.