Kubernetes 클러스터의 안전한 운영을 위한 접근 제어
2024년 11월 22일
서문
Kubernetes 클러스터의 사용이 증가함에 따라 보안 및 운영 효율성을 높이기 위한 접근 제어의 중요성이 커지고 있습니다. 그러나 Kubernetes가 제공하는 RBAC(Role-Based Access Control) 기능은 설정과 관리가 복잡하여 많은 조직이 이를 충분히 활용하지 못하고 있습니다. 결과적으로, 많은 실무자들이 Admin 권한을 공유하여 사용하게 되며, 이는 보안 위협을 증가시키고 운영상의 문제를 야기할 수 있습니다.

공유된 Admin 권한은 모든 사용자에게 무제한의 권한을 부여하여, 실수로 인해 잘못된 리소스를 삭제하거나 변경할 위험을 높입니다. 이는 서비스 장애로 이어질 수 있으며, 문제 발생 시 누가 어떤 작업을 수행했는지 추적하기가 어렵습니다. 따라서, Kubernetes 클러스터의 안전하고 효율적인 운영을 위해서는 사용자별로 명확한 접근 제어 정책을 수립하는 것이 필수적입니다.
그래서 클러스터에 대한 접근제어를 위해 Kubernetes RBAC 도입을 고려는 하지만, 기능상 여러가지 제약 조건이나 관리의 어려움 등으로 막상 적극적으로 Kubernetes RBAC 을 사용하는 곳은 많지 않습니다. Kubernetes RBAC 에는 어떤 어려움이 있는 것일까요? 그리고 이를 해결하기 위해서는 어떻게 해야지 더 안전하게 Kubernetes 클러스터를 사용할 수 있을까요?
이런 고민들을 해결하기 위해 만든 Kubernetes 접근제어 제품의 기능들을 소개하고, 개발하면서 다루었던 기술들을 소개하겠습니다.
문제 정의
Kubernetes 에는 RBAC 이라는 Role 을 기반으로 한 접근제어 기능이 이미 내장되어 있습니다. Kubernetes RBAC 을 사용하면 자연스럽게 클러스터 내의 리소스별로 접근권한을 나누어서 Role 을 만들고, 이 Role 을 권한이 필요한 사람에게만 부여하는 방식으로 사용 할 수 있습니다. 예를 들어서 사용자별로 클러스터내의 namespace 를 나누고, 각각의 사용자는 본인의 namespace 내의 리소스들만 접근할 수 있는 방식이죠. 이를 위해서는 사용자별로 인증정보가 담긴 kubeconfig 를 생성하고 이를 각 사용자한테 전달해서 사용합니다. 그림을 보시면 David 은 David namespace 안의 리소스들만 접근할 수 있고, Andrew 와 Sam 도 각자의 namespace 안의 리소스들만 접근할 수 있죠. 이렇게 사용자별로 kubeconfig 를 따로 관리함으로서 어느 정도 권한 관리와 클러스터내 리소스 충돌 문제는 해결될 수 있습니다.

그런데 Kubernetes RBAC 을 적용하면 운영은 편해질까요? 실제로 Kubernetes RBAC 을 적용하신 분들의 얘기를 들어보면 여러가지 불편함이 있다고 얘기를 합니다.
kubeconfig 관리 어려움

어떤 어려움이 있을까요? 먼저 kubeconfig 관리를 생각해 볼까요? 클러스터에 사용자별로 RBAC 을 적용한다고 했을때 클러스터 관리자가 해야할 일은 생각보다 많습니다. 일단 어떤 리소스에 어떤 액션을 할 수 있는지 Role 명세를 만들어야 하구요. 그 Role 을 사용자에게 RoleBinding 해줘야 합니다.그리고 사용자가 그 Role 을 가지고 클러스터에 접근할 수 있게 하기 위해서, X.509 인증서나 토큰 방식을 사용해서 사용자별로 kubeconfig 를 생성해줘야 합니다. 즉 클러스터 관리자가 사용자마다 그리고 Role 명세마다 다 관리를 해줘야 하는거죠.
멀티 클러스터면?

그리고 서비스 규모가 커지면서 멀티 클러스터를 운영하는 경우도 늘어납니다. 관리해야 할 클러스터가 하나가 아니라 여러개가 되면 어떻게 될까요? 클러스터 관리자는 앞서 말씀 드린 Role 명세 생성, Role 바인딩, 사용자별 kubeconfig 관리를 각 클러스터별로 또 해줘야 합니다. 클러스터가 늘어날 수록 그리고 사용자가 늘어날 수록 점점 운영 리소스가 많이 들겠죠.
Audit Log는요?

Audit log 는 어떻게 관리해야 할까요? Kubernetes Audit log 에는 누가 언제 어떤 리소스에 접근했는지 기록이 남는데요. audit 로그를 남기기위해서는 클러스터 관리자가 각 클러스터마다 audit 설정을 해줘야 하는 부담이 있습니다. 또 감사시에 어떤 사용자가 한 행위를 audit log 에서 모두 찾아봐야 한다면, 각 클러스터마다의 audit log 를 하나씩 검색해봐야 합니다. 즉 audit log 설정과 로그 데이터 관리에 어려움이 있습니다.
RBAC Deny Rule의 부재

kubeconfig와 audit log 관리만 어려운게 아닙니다. Kubernete RBAC 에는 몇가지 아쉬운 기능들이 있는데요. 그중 하나가 Kubernete RBAC 명세에서 Deny rule 을 지원하지 않는다는 것입니다. 예를 들어 위 그림처럼 사용자에게 nginx pod 만 제외하고 다른 모든 리소스에 대한 접근 권한을 부여해주고 싶다고 가정할게요. 이럴때 Kubernete RBAC의 Role 설정을 어떻게 해야 할까요?

Kubernetes Role 명세는 Allow Rule 만 지원하므로, 위 그림처럼 Role 명세에다가 nginx 를 제외한 모든 리소스 이름들을 하나씩 다 추가해줘야 합니다. Role 명세에 추가해야 할 리소스가 3~4개면 그나마 괜찮을텐데, 10개 20개면 어떻게 해야 할까요? 그리고 리소스가 수시로 추가 삭제가 된다면 어떻게 해야 할까요? 그때마다 Role 명세를 관리하는 것은 운영 부담을 늘릴 것입니다.
RBAC 패턴 매칭 기능의 부재

두번째 아쉬운 점은 RBAC 설정시에 패턴 매칭을 지원하지 않는 부분입니다. 예를 들어 pod 이름이 david 으로 시작하는 pod 가 여러개 있다고 가정할게요. 이때 사용자에게 david 으로 시작하는 Pod 들에 대해서만 접근 권한을 부여하고 싶다고 하면 어떻게 해야 할까요?

아쉽지만 현재 Kubernetes Role 명세에는 리소스 이름을 넣을 때 패턴 매칭을 지원하지 않습니다. 즉 david 으로 시작하는 Pod 들만 패턴으로 지정해서 설정 할 방법이 없죠. 그래서 보시는 것처럼 david-1, david-2, david-3 이런식으로 pod의 이름들을 하나씩 모두 넣어줘야 합니다. 이것또한 클러스터 관리자 입장에서 번거로운 부분입니다.
이밖에도 Kubernetes 접근제어 기능에서는 RBAC 과 ABAC 을 동시에 사용하고 싶을때 설정이 복잡하다던지, Pod 리스트 조회시에 접근 권한이 있는 Pod 들만 필터링 해서 사용자에게 보여줄 수 없다던지 등의 부족한 점들이 있습니다.
목표 설정
그래서 앞서 설명드린 부족한 Kubernetes 의 기본 RBAC 기능들을 보완하고, 클러스터 관리자의 접근제어 운영 부담을 덜어주기 위한 Kubernetes 접근제어 제품을 개발하자는 목표를 세웠습니다. 그리고 이 새로운 Kubernetes 접근제어 제품을 도입할때에, 사용자의 거부감이 없도록 기존의 Kubernetes 사용성도 그대로 유지하자라는 목표를 세웠습니다.
솔루션 개요
Kubernetes 접근 제어 제품은(이하 KAC)는 클라이언트와 Kubernete API 서버 사이에 KAC Proxy 서버를 두어 접근제어를 하는 방식입니다.

클라이언트와 kubernetes API 서버 중간에서 사용자 요청이 담긴 kubernetes API 요청을 가로채서 동작하는데요. API 호출을 가로챈 후 어떤 리소스에 어떤 액션을 취하려고 하는지 요청을 분석하고, 해당 사용자가 그런 권한 체크이 있는지를 체크합니다. 물론 추후 감사를 위해 누가 언제 어떤 리소스에 어떤 액션을 취했는지에 대한 Audit 로그를 남기는 기능을 기본 제공합니다.
이후 API 요청 종류에 따라 여러가지 부가 기능을 제공하는데요. 예를 들어 만약 Pod exec 처럼 컨테이너 안에 들어가는 요청 이라면 사용자가 컨테이너 안에서 입력하는 명령들과 출력들을 레코딩하여 나중에 재생해 볼 수 있도록 했습니다. 만약 Pod 리스트를 조회하는 경우라면 Kubernetes API 서버 응답을 필터링하여, 실제 사용자가 권한이 있는 Pod 들만 볼 수 있도록 하는 기능도 제공합니다. 물론 이러한 기능들을 제공함에 있어서, 기존에 사용하던 Kubernetes 클라이언트 툴들은 기존처럼 그대로 사용할 수 있어야 하는데요. 이를 위해 KAC Proxy 서버는 transparent 하게 설계하여, 사용자 클라이언트 툴 입장에서는 KAC Proxy 서버가 존재하는지 모르도록 하였습니다.
기술적 설명
KAC 접근제어 기능이 어떻게 동작하는지 기술적 관점에서 단계별로 설명하겠습니다. 기본적으로 클러스터 내의 리소스 접근에 대한 허용과 차단은 KAC Proxy 서버에서 이루어집니다.