Develop/DevOps

[Kubernetes] Audit log(감사로그)

재융 2025. 4. 27. 17:40
반응형

쿠버네티스 보안을 위해서 사용자들의 행위를 기록하기 위한 감사로그를 kube-apiserver의 옵션을 통해서 활성화가 가능하다.

  • 행위: kube-apiserver를 통한 행동(e.g. create, delete등)

https://kubernetes.io/ko/docs/tasks/debug/debug-cluster/audit/

 

감사(auditing)

쿠버네티스 감사(auditing) 는 클러스터의 작업 순서를 문서화하는 보안 관련 시간별 레코드 세트를 제공한다. 클러스터는 사용자, 쿠버네티스 API를 사용하는 애플리케이션 및 컨트롤 플레인 자체

kubernetes.io

 

이러한 감사로그에는 다음과 같은 정보를 수집한다. (위 페이지에서 발췌)

  • 무슨 일이 일어났는지?
  • 언제 일어난 일인지?
  • 누가 시작했는지?
  • 어떤 일이 있었는지?
  • 어디서 관찰되었는지?
  • 어디서부터 시작되었는지?
  • 그래서 어디까지 갔는지?

Stage - 단계

각 행위(요청)들은 연관된 단계(stage)와 함께 기록될 수 있다. 단계의 정보는 다음과같다. (위 페이지에서 발췌)

  • RequestReceived - 감사 핸들러가 요청을 수신한 직후, 그리고 핸들러 체인으로 위임되기 전에 생성되는 이벤트에 대한 단계이다.
  • ResponseStarted - 응답 헤더는 전송되었지만, 응답 본문(body)은 전송되기 전인 단계이다. 이 단계는 오래 실행되는 요청(예: watch)에 대해서만 생성된다.
  • ResponseComplete - 응답 내용이 완료되었으며, 더 이상 바이트가 전송되지 않을 때의 단계이다.
  • Panic - 패닉이 발생했을 때 생성되는 이벤트이다.

Level - 수준

감사로그의 수준(Level)을 정하여 어느정도까지의 정보를 수집할것인지 정할수있다. (위 페이지에서 발췌)

  • None - 이 규칙에 해당되는 이벤트는 로깅하지 않는다.
  • Metadata - 요청 메타데이터(요청하는 사용자, 타임스탬프, 리소스, 동사(verb) 등)는 로깅하지만 요청/응답 본문은 로깅하지 않는다.
  • Request - 이벤트 메타데이터 및 요청 본문을 로깅하지만 응답 본문은 로깅하지 않는다. 리소스 외의 요청에는 적용되지 않는다.
  • RequestResponse - 이벤트 메타데이터 및 요청/응답 본문을 로깅한다. 리소스 외의 요청에는 적용되지 않는다.

위에서 아래순으로 정보가 많으며, 당연하겠지만 정보가 많을수록 로그양이 커져서 기록시 잘 조율해야한다. 즉, 상세하게 기록해야하는 행위(e.g. create, update) 에 대해서는 RequestResponse 수준까지 기록하는것이 좋고, 그다지 상세하게  기록하지않아도 되는 행위(e.g. approve, renew)에 대해서는 아예 기록하지않거나 Metadata 수준까지만 기록하는것이 좋다.

추가로, delete 예시로 Metadata 수준까지만 기록해도 되니 굳이 RequestResponse수준까지의 기록은 필요없는것처럼 verbs에 따라서 적당한 로그 수준으로 기록해야지 효율적으로 로그를 쌓을수있다.

 

감사로그 policy

감사로그를 활성화 하게된다면 어떤 로그를 수집 할 것인지에 대한 정책(policy)이 필요하다. 그리고 어떤 로그를 수집할것인지에 대한걸 위에서 설명한 Level 과 Stage 그리고 apiGroups, verbs등을 지정하여 수집대상을 지정할수있다. policy yaml파일 예시는 다음과 같다.

 

아래 policy파일은 아래 조건(system:kube-proxy가 endpoints, services, services/status를 watch하는 행위)에 맞는 유형은 기록하지 않겠다(None)라는 의미이다.

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: None
    users: ["system:kube-proxy"]
    verbs: ["watch"]
    resources:
      - group: "" # core
        resources: ["endpoints", "services", "services/status"]

 

아래는 kubespray에서 제공하는 기본 Policy yaml이다

https://github.com/kubernetes-sigs/kubespray/blob/master/roles/kubernetes/control-plane/templates/apiserver-audit-policy.yaml.j2

 

kubespray/roles/kubernetes/control-plane/templates/apiserver-audit-policy.yaml.j2 at master · kubernetes-sigs/kubespray

Deploy a Production Ready Kubernetes Cluster. Contribute to kubernetes-sigs/kubespray development by creating an account on GitHub.

github.com

 

Kubespray를 이용한 감사로그 활성화

kubespray를 사용하여 클러스터를 구축했다면 아래와 같은 변수를 활용해서 감사로그를 활성화 할 수 있다.

kubespray는 왜인지, policy의 내용을 변경하고 kube-apiserver를 재시작해도 policy가 적용이 안되는것처럼 보인다. 따라서 변경된 policy를 적용하기 위해서는 kubernetes_audit을 false로 설정하고 다시 true로 변경하여 적용해야지만 변경된 policy가 반영된다.
kubernetes_audit: true # audit log 활성화 유무

# true로 설정하게 되면 아래 변수들이 기본값으로 세팅됨
# audit_log_path: /var/log/audit/kube-apiserver-audit.log
# audit_log_maxage: 30 # 로그 최대 보관 일수
# audit_log_maxbackups: 10 # 로그 최대 보관 개수
# audit_log_maxsize: 100 # 로그 최대 보관 크기 (MB)
# audit_policy_file: "{{ kube_config_dir }}/audit-policy/apiserver-audit-policy.yaml"

 

변수를 설정한 다음 audit은 kube-apiserver에 영향을 주는 요소이고 kube-apiserver는 Master노드에서만 실행되니 아래와같이 master에서만 동작하게끔 ansible-playbook을 실행한다.

ansible-playbook \
  -i inventory -b \
  -e upgrade_cluster_setup=true \
  --limit kube_control_plane \
  --tags master \
  cluster.yml

kube-apiserver 옵션을 추가하는 방식

사실 위와같이 kubernetes_audit을 true로 하고 마스터노드의 kube-apiserver 프로세스를 보면 아래와같은 옵션이 생성되어있다.

kube-apiserver --apiserver-count=3 \
  --audit-log-maxage=30 \
  --audit-log-maxbackup=10 \
  --audit-log-maxsize=100 \
  --audit-log-path=/var/log/audit/kube-apiserver-audit.log \
  --audit-policy-file=/etc/kubernetes/audit-policy/apiserver-audit-policy.yaml
반응형