(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

【Kubernetes】特定ユーザに対してkube-apiserverのAudit機能を有効にする

スポンサーリンク

はじめに

KubernetesのAPIサーバには監査機能があり、時系列情報として各アクティビティをテキストファイルとして吐き出すことが可能です。

本記事ではkubeadmでインストールしたNodeにてauditログを出力する設定を行い、その中でも特にkube-adminが行った操作のみを対象にログ出力するように変更を行う流れについて記載しました。

環境情報
  • Kubernetes v1.23

Audit機能の確認

事前にpolicy.yamlというファイルを任意の場所に配置します。下記の監査の内容は「リクエストのメタデータを全量記録する」という設定となります。

# cat /etc/kubernetes/audit/policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata

同Configファイルをapiserver側で読ませるために/etc/kubernetes/manifests/kube-apiserver.yamlにて記載されている引数に以下を追記します。

    - --audit-policy-file=/etc/kubernetes/audit/policy.yaml
    - --audit-log-path=/etc/kubernetes/audit/log/audit.log

尚、それぞれのディレクトリはマウントが必要で--audit-log-pathに指定するディレクトリに関しては書き込み権限も必要となります。よって以下のようになります。

volumeMounts:
...
    - mountPath: /etc/kubernetes/audit
      name: audit
      readOnly: false
...
 volumes:
...
  - hostPath:
      path: /etc/kubernetes/audit
      type: DirectoryOrCreate
    name: audit

同ファイルを編集すると自動的に起動されるので、apiserverの起動を待ちます。
尚、yamlファイルの文法誤りがあれば以下のようにkubelet側のログに出ます。

... kubelet[60244]: E0316 00:55:29.225326   60244 file.go:187] "Could not process manifest file" err="/etc/kubernetes/manifests/kube-apiserver.yaml: couldn't parse as pod(yaml: line 93: did not find expected key), please check config file" path="/etc/kubernetes/manifests/kube-apiserver.yaml"

特定ユーザの情報に絞る

上記の設定では絞ることなく全量が監査ログファイルに出力されるので、それを避ける方法としてrulesの部分のカスタマイズがあります。具体的には、特権ユーザであるkubenetes-adminの操作に関してのみ情報を絞るべくuser部分に指定を入れます。

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
  users:
  - "kubernetes-admin"

同設定が反映されると、kubernetes-adminユーザの操作のみが記録されるようになり、例えばget podを行うとRequestReceivedとResponseCompleteのログが記録されていました。

{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"x","stage":"RequestReceived","requestURI":"/api/v1/namespaces/default/pods?limit=500","verb":"list","user":{"username":"kubernetes-admin","groups":["system:masters","system:authenticated"]},"sourceIPs":["x"],"userAgent":"kubectl/v1.23.2 (linux/amd64) kubernetes/9d14243","objectRef":{"resource":"pods","namespace":"default","apiVersion":"v1"},"requestReceivedTimestamp":"xx","stageTimestamp":"xx"}
{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"xx","stage":"ResponseComplete","requestURI":"/api/v1/namespaces/default/pods?limit=500","verb":"list","user":{"username":"kubernetes-admin","groups":["system:masters","system:authenticated"]},"sourceIPs":["xx"],"userAgent":"kubectl/v1.23.2 (linux/amd64) kubernetes/9d14243","objectRef":{"resource":"pods","namespace":"default","apiVersion":"v1"},"responseStatus":{"metadata":{},"code":200},"requestReceivedTimestamp":"xx","stageTimestamp":"xx","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":""}}

そして、別ユーザやsystem上でのAPI操作ログは記録されないのでファイルのボリュームの削減が可能です。

終わりに

監査イベントはJSON形式で蓄積されていくため、絞らずにaudit.log上で絞る・・という方針もありだとは思いますが、今回はボリュームを考慮して特定ユーザの操作に絞ってファイルを出力したいというケースを想定しました。

以上、ご参考になれば幸いです。