Secure the Kubernetes API server
/etc/kubernetes/manifests/kube-apiserver.yamlspec: containers: - command: - kube-apiserver - --anonymous-auth=false - --authorization-mode=Node,RBAC - --profiling=false - --audit-log-path=/var/log/kubernetes/audit.logOn a managed cluster (EKS/GKE/AKS) this is the provider’s job — you can’t set these flags, and shouldn’t need to. This page is for self-managed control planes.
Why it matters
Section titled “Why it matters”The API server is the single front door to everything: workloads, secrets, RBAC,
nodes. Every kubectl command, every controller, every pod’s service account
talks to it. Compromise it and you have the cluster; expose it carelessly and you
invite the attempt.
Three flags carry most of the risk.
anonymous-auth
Section titled “anonymous-auth”--anonymous-auth=true lets requests that present no credentials through to
the authorization stage as the user system:anonymous. On its own that’s not
fatal — RBAC still has to grant anonymous something — but it’s a foot-gun: a
single over-broad ClusterRoleBinding to system:unauthenticated (which people
create by accident, or copy from a bad tutorial) turns anonymous into real access.
--anonymous-auth=false removes the category. There’s rarely a reason for
anonymous API access; the health endpoints that legitimately need it
(/livez, /readyz) can be allowed explicitly.
authorization-mode
Section titled “authorization-mode”--authorization-mode=Node,RBAC is what you want. The danger values:
AlwaysAllow— every authenticated request is permitted. RBAC is not consulted. This is catastrophic and occasionally appears in dev clusters that escaped to production.- Missing
RBAC— if RBAC isn’t in the authorizer chain, none of your carefully scoped roles are enforced.
Node restricts what kubelets can read to what their own pods need;
RBAC enforces everything else. Both, in that order.
Don’t expose it, and mind the unauthenticated endpoints
Section titled “Don’t expose it, and mind the unauthenticated endpoints”The API server should be reachable by your operators and nodes, not the internet. On a self-managed cluster that means binding it appropriately and firewalling 6443. Even authenticated, an internet-facing API server is a continuous brute-force and CVE target.
And a few endpoints answer before authentication:
/healthz,/livez,/readyz— fine, but they confirm a cluster is there./metrics— should require auth; unauthenticated metrics leak cluster internals.--profiling=trueexposes/debug/pprof, which can leak memory contents. Turn it off in production.
Related
Section titled “Related”- RBAC least privilege — only enforced if RBAC is the authorizer.
- Secure etcd — the API server’s data store, equally sensitive.
- Kubernetes cluster exposed — what a reachable API server invites.