CKS Notes — Audit log
This is a quick notes and summary from office doc.
- this is a quick look at log audit.
- more detail about the log audit, pls refer to the official doc about audit
- and also can check my previous article: kubernets related logs & configurations which shows clear log file paths and the config related files and their locations.
Audit workflow
edit the audit-policy.yaml:
apiVersion: audit.k8s.io/v1 # This is required.
kind: Policy
# Don't generate audit events for all requests in RequestReceived stage.
omitStages:
- "RequestReceived"
rules:
# Log pod changes at RequestResponse level
- level: RequestResponse
resources:
- group: ""
# Resource "pods" doesn't match requests to any subresource of pods,
# which is consistent with the RBAC policy.
resources: ["pods"]
# Log "pods/log", "pods/status" at Metadata level
- level: Metadata
resources:
- group: ""
resources: ["pods/log", "pods/status"]
# Don't log requests to a configmap called "controller-leader"
- level: None
resources:
- group: ""
resources: ["configmaps"]
resourceNames: ["controller-leader"]
# Don't log watch requests by the "system:kube-proxy" on endpoints or services
- level: None
users: ["system:kube-proxy"]
verbs: ["watch"]
resources:
- group: "" # core API group
resources: ["endpoints", "services"]
# Don't log authenticated requests to certain non-resource URL paths.
- level: None
userGroups: ["system:authenticated"]
nonResourceURLs:
- "/api*" # Wildcard matching.
- "/version"
# Log the request body of configmap changes in kube-system.
- level: Request
resources:
- group: "" # core API group
resources: ["configmaps"]
# This rule only applies to resources in the "kube-system" namespace.
# The empty string "" can be used to select non-namespaced resources.
namespaces: ["kube-system"]
# Log configmap and secret changes in all other namespaces at the Metadata level.
- level: Metadata
resources:
- group: "" # core API group
resources: ["secrets", "configmaps"]
# Log all other resources in core and extensions at the Request level.
- level: Request
resources:
- group: "" # core API group
- group: "extensions" # Version of group should NOT be included.
# A catch-all rule to log all other requests at the Metadata level.
- level: Metadata
# Long-running requests like watches that fall under this rule will not
# generate an audit event in RequestReceived.
omitStages:
- "RequestReceived"add flags to /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
containers:
- command:
- kube-apiserver
- --audit-policy-file=/etc/kubernetes/audit-policy.yaml
- --audit-log-path=/var/log/kubernetes/audit/audit.log
- --audit-log-maxage=8
- --audit-log-maxsize=9
- --audit-log-maxbackup=3--audit-policy-file=/etc/kubernetes/audit-policy.yaml--audit-log-path=/var/log/kubernetes/audit/audit.log--audit-log-maxage=8: max number of days--audit-log-maxsize=9: max file size in megabytes before rotate--audit-log-maxbackup=3: copy of audit log files
edit the volumeMounts
volumeMounts:
- mountPath: /etc/kubernetes/audit-policy.yaml
name: audit
readOnly: true
- mountPath: /var/log/kubernetes/audit/
name: audit-log
readOnly: falseedit the hostPath corresponding with --audit-policy-file and --audit-log-path
volumes:
- name: audit
hostPath:
path: /etc/kubernetes/audit-policy.yaml
type: File
- name: audit-log
hostPath:
path: /var/log/kubernetes/audit/
type: DirectoryOrCreateand then wait for some time and we can check the logs on path /var/log/kubernetes/audit/.
Notice:
in above Volume and VolumeMount, we see some difference settings for audit policy and audit logs.
Audit policy
- Path is a single YAML file:
/etc/kubernetes/audit-policy.yaml readOnly: API server only needs to read ittype: File: The file already exists, Kubelet should fail to start the apiserver if the file is missing
Audit logs
- Path is a directory
/var/log/kubernetes/audit/, API server writes out multiple log files (with rotation)audit.log,audit.log.1, etc readOnly: falsetype: DirectoryOrCreate: It may not exist yet on a fresh system, Kubelet will automatically create it so the API server can write logs
Policy
A Kubernetes audit policy has three important layers:
1. Resources you target
resources:
- group: "" # core API group
resources: ["pods", "configmaps", "secrets", "persistentvolumeclaims", ...]group: "" means Core API group, like pods, configmaps, secrets, services, pv, pvc.
Get Cheedge Lee’s stories in your inbox
Join Medium for free to get updates from this writer.
but there are also non-core-api
| Resource | Group |
| --- | --- |
| deployments | apps |
| daemonsets | apps |
| jobs | batch |
| ingresses | [networking.k8s.io](http://networking.k8s.io) |
| certificatesigningrequests | [certificates.k8s.io](http://certificates.k8s.io) |so the resource eg.
resources:
- group: "apps"
resources: ["deployments"]2. Which stages you log
stages: ["Request", "Response", "Metadata"]- Request: log the incoming request before it hits handlers
- Response: log the full response (including responseBody if enabled)
- Metadata: only logs the request metadata (verb, user, resource, namespace)
Normally not used, but we often define omitStages to reduce noise.
omitStages: ["RequestReceived"] is used to: Reduce extremely noisy logs with no loss of useful information.
| Stage | Meaning |
| --- | --- |
| `RequestReceived` | kube-apiserver got the request |
| `ResponseStarted` | apiserver is sending stream response |
| `ResponseComplete`| finished sending full response |
| `Panic` | apiserver crashed during request |3. Log level fields
level: None | Metadata | Request | RequestResponse3.1. level: None
No audit event produced, which is used to ignore noisy resources. eg.
- level: None
resources:
- group: ""
resources: ["events"]level: Metadata
Logs:
- user (e.g., system:serviceaccount:default:sa)
- verb (get, list, update, patch…)
- resource (configmaps, pods…)
- namespace
- request URI
- response code
No request/response bodies. This is lightweight and safe for Secrets.
3.2. level: Request
Logs everything from “Metadata” plus the request body. eg.
- the new version of a ConfigMap
- the PVC spec submitted by kubectl
- the PATCH operations
Does NOT log the response body.
3.3. level: RequestResponse
Logs:
- metadata
- request body
- response body
eg. when we run command kubectl apply -f my-pv.yaml
the audit logs include:
- the PV YAML sent
- the PV YAML that apiserver stored after admission
This is the most expensive but also the most complete.
3.4 Summary
| Level | Logs | Notes |
| --- | --- | --- |
| **None** | nothing | Useful to exclude noisy resources |
| **Metadata** | verb, user, resource, namespace, stage | Very cheap, no bodies |
| **Request** | request headers + request body | More expensive |
| **RequestResponse** | request + response body | Most expensive |Originally published at https://dev.to on November 28, 2025.








