|
| 1 | +# Kubernetes Auditing |
| 2 | + |
| 3 | +Auditing provides records of each request that arrives in the kube-apiserver. The audit record will indicate what happened and who requested it. |
| 4 | + |
| 5 | +## Enable Auditing |
| 6 | + |
| 7 | +Enable auditing by installing an audit policy configuration file on each k8s master, creating a directory on the master to hold the audit logs, and providing the appropriate commandline options to kube-apiserver. |
| 8 | + |
| 9 | +### Install an audit policy |
| 10 | + |
| 11 | +The audit policy file will be installed on each k8s master node as `/etc/kubernetes/policies/audit-policy.yaml`. |
| 12 | + |
| 13 | +The following is an example audit policy file that captures events for the NNF stack. Other examples can be found later in this document. |
| 14 | + |
| 15 | +```bash |
| 16 | +apiVersion: audit.k8s.io/v1 |
| 17 | +kind: Policy |
| 18 | + |
| 19 | +omitStages: |
| 20 | +- RequestReceived |
| 21 | + |
| 22 | +rules: |
| 23 | +- level: Metadata |
| 24 | + verbs: ["get", "list", "watch", "create", "patch", "update"] |
| 25 | + resources: |
| 26 | + |
| 27 | + - group: lus.cray.hpe.com |
| 28 | + - group: dataworkflowservices.github.io |
| 29 | + - group: nnf.cray.hpe.com |
| 30 | + - group: dm.cray.hpe.com |
| 31 | +``` |
| 32 | + |
| 33 | +### Create a log directory |
| 34 | + |
| 35 | +Create a directory on each k8s master to contain the audit logs. |
| 36 | + |
| 37 | +```console |
| 38 | +mkdir /var/log/kubernetes |
| 39 | +``` |
| 40 | + |
| 41 | +### Configure the kube-apiserver |
| 42 | + |
| 43 | +The following is an example patch to apply to the `/etc/kubernetes/manifests/kube-apiserver.yaml` file on each k8s master node. The arguments in this patch refer to the audit policy file location and audit log location used earlier in this document. |
| 44 | + |
| 45 | +**Do not copy the `kube-apiserver.yaml` file to other master nodes. It contains IP addresses that are specific to one master node.** |
| 46 | + |
| 47 | +After applying this patch to `kube-apiserver.yaml`, clear any extra patch or backup files out of `/etc/kubernetes/manifests` because kubelet will read all of them, regardless of the file suffix. |
| 48 | + |
| 49 | +The kubelet on that master will detect the change to the `kube-apiserver.yaml` file and will restart the kube-apiserver. |
| 50 | + |
| 51 | +```bash |
| 52 | +--- a/kube-apiserver.yaml-orig 2024-05-13 12:18:48.256680095 -0700 |
| 53 | ++++ b/kube-apiserver.yaml 2024-05-28 13:39:50.342694448 -0700 |
| 54 | +@@ -41,6 +41,9 @@ |
| 55 | + - --service-cluster-ip-range=10.96.0.0/12 |
| 56 | + - --tls-cert-file=/etc/kubernetes/pki/apiserver.crt |
| 57 | + - --tls-private-key-file=/etc/kubernetes/pki/apiserver.key |
| 58 | ++ - --audit-policy-file=/etc/kubernetes/policies/audit-policy.yaml |
| 59 | ++ - --audit-log-path=/var/log/kubernetes/kube-apiserver-audit.log |
| 60 | ++ - --audit-log-maxsize=100 |
| 61 | + image: registry.k8s.io/kube-apiserver:v1.29.3 |
| 62 | + imagePullPolicy: IfNotPresent |
| 63 | + livenessProbe: |
| 64 | +@@ -86,6 +89,12 @@ |
| 65 | + - mountPath: /etc/kubernetes/pki |
| 66 | + name: k8s-certs |
| 67 | + readOnly: true |
| 68 | ++ - mountPath: /etc/kubernetes/policies/audit-policy.yaml |
| 69 | ++ name: k8s-policies |
| 70 | ++ readOnly: true |
| 71 | ++ - mountPath: /var/log/kubernetes/ |
| 72 | ++ name: k8s-log |
| 73 | ++ readOnly: false |
| 74 | + hostNetwork: true |
| 75 | + priority: 2000001000 |
| 76 | + priorityClassName: system-node-critical |
| 77 | +@@ -105,4 +114,12 @@ |
| 78 | + path: /etc/kubernetes/pki |
| 79 | + type: DirectoryOrCreate |
| 80 | + name: k8s-certs |
| 81 | ++ - hostPath: |
| 82 | ++ path: /etc/kubernetes/policies/audit-policy.yaml |
| 83 | ++ type: File |
| 84 | ++ name: k8s-policies |
| 85 | ++ - hostPath: |
| 86 | ++ path: /var/log/kubernetes/ |
| 87 | ++ type: DirectoryOrCreate |
| 88 | ++ name: k8s-log |
| 89 | + status: {} |
| 90 | + ``` |
| 91 | + |
| 92 | +## Disable auditing |
| 93 | + |
| 94 | +Disable auditing by editing the `/etc/kubernetes/manifests/kube-apiserver.yaml` on each master to remove the `--audit-*` commandline options from the kube-apiserver configuration. The kubelet on that master will detect the change to the `kube-apiserver.yaml` file and will restart the kube-apiserver. |
| 95 | + |
| 96 | +Clear any extra patch or backup files out of `/etc/kubernetes/manifests` because kubelet will read all of them, regardless of the file suffix. |
| 97 | + |
| 98 | +## Auditing in KIND |
| 99 | + |
| 100 | +The KIND environment that is created by the tools in nnf-deploy already has auditing enabled. See the notes in nnf-deploy's [audit-policy.yaml](https://github.com/NearNodeFlash/nnf-deploy/blob/master/config/audit-policy.yaml) to access the audit log. |
| 101 | + |
| 102 | +## Reading the audit log |
| 103 | + |
| 104 | +The `jq(1)` command can be used to make sense of the audit logs. The following `jq` commands have proven useful to the NNF project: |
| 105 | + |
| 106 | +Pretty-print the log events: |
| 107 | + |
| 108 | +```console |
| 109 | +jq -M . kube-apiserver-audit.log | less |
| 110 | +``` |
| 111 | + |
| 112 | +Dump a quick-to-digest summary of the log events: |
| 113 | + |
| 114 | +```console |
| 115 | +jq -M '[.auditID,.verb,.requestURI,.user.username,.responseStatus.code,.stageTimestamp]' kube-apiserver-audit.log | less |
| 116 | +``` |
| 117 | + |
| 118 | +Extract a specific event record from the log: |
| 119 | + |
| 120 | +```console |
| 121 | +jq -M '. | select(.auditID=="d1053ee5-0734-4b40-815f-3f6831f82bac")' kube-apiserver-audit.log | less |
| 122 | +``` |
| 123 | + |
| 124 | +## Example audit policies |
| 125 | + |
| 126 | +Log all activity from the clientmountd daemon. Extract records from the log with: |
| 127 | + |
| 128 | +```console |
| 129 | +jq -M '.|select(.user.username=="system:serviceaccount:nnf-system:nnf-clientmount")' kube-apiserver-audit.log |
| 130 | +``` |
| 131 | + |
| 132 | +This could also be adjusted to isolate any other ServiceAccount. |
| 133 | + |
| 134 | +```bash |
| 135 | +apiVersion: audit.k8s.io/v1 |
| 136 | +kind: Policy |
| 137 | + |
| 138 | +omitStages: |
| 139 | +- RequestReceived |
| 140 | + |
| 141 | +rules: |
| 142 | + |
| 143 | +- level: Metadata |
| 144 | + users: ["system:serviceaccount:nnf-system:nnf-clientmount"] |
| 145 | + resources: |
| 146 | + - group: "" # core |
| 147 | + - group: lus.cray.hpe.com |
| 148 | + - group: dataworkflowservices.github.io |
| 149 | + - group: nnf.cray.hpe.com |
| 150 | + - group: dm.cray.hpe.com |
| 151 | +``` |
| 152 | + |
| 153 | +A more complex [audit-policy.yaml](https://github.com/NearNodeFlash/nnf-deploy/blob/master/config/audit-policy.yaml) can be found in the nnf-deploy configuration for KIND environments. |
| 154 | + |
| 155 | +## References |
| 156 | + |
| 157 | +### Kubernetes |
| 158 | + |
| 159 | +[Auditing](https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/) |
| 160 | + |
| 161 | +### nnf-deploy |
| 162 | + |
| 163 | +Nnf-deploy contains a more complex audit policy: |
| 164 | +[audit-policy.yaml](https://github.com/NearNodeFlash/nnf-deploy/blob/master/config/audit-policy.yaml) |
0 commit comments