Ready to Boost Your Startup? Click to Start Up Your Free Subscription!

Kubernetes

Kubernetes 클러스터의 안전한 운영을 위한 접근 제어

저자: David Choi

November 22, 2024

White Paper Thumbnail

서문

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

Introduction

공유된 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 를 따로 관리함으로서 어느 정도 권한 관리와 클러스터내 리소스 충돌 문제는 해결될 수 있습니다.


Challenges

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

kubeconfig 관리 어려움


Challenges

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

멀티 클러스터면?


Challenges

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

Audit Log는요?


Challenges

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

RBAC Deny Rule의 부재


Challenges

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


Challenges

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

RBAC 패턴 매칭 기능의 부재


Challenges

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


Challenges

아쉽지만 현재 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 서버를 두어 접근제어를 하는 방식입니다.


Solution Overview

클라이언트와 kubernetes API 서버 중간에서 사용자 요청이 담긴 kubernetes API 요청을 가로채서 동작하는데요. API 호출을 가로챈 후 어떤 리소스에 어떤 액션을 취하려고 하는지 요청을 분석하고, 해당 사용자가 그런 권한 체크이 있는지를 체크합니다. 물론 추후 감사를 위해 누가 언제 어떤 리소스에 어떤 액션을 취했는지에 대한 Audit 로그를 남기는 기능을 기본 제공합니다.

이후 API 요청 종류에 따라 여러가지 부가 기능을 제공하는데요. 예를 들어 만약 Pod exec 처럼 컨테이너 안에 들어가는 요청 이라면 사용자가 컨테이너 안에서 입력하는 명령들과 출력들을 레코딩하여 나중에 재생해 볼 수 있도록 했습니다. 만약 Pod 리스트를 조회하는 경우라면 Kubernetes API 서버 응답을 필터링하여, 실제 사용자가 권한이 있는 Pod 들만 볼 수 있도록 하는 기능도 제공합니다. 물론 이러한 기능들을 제공함에 있어서, 기존에 사용하던 Kubernetes 클라이언트 툴들은 기존처럼 그대로 사용할 수 있어야 하는데요. 이를 위해 KAC Proxy 서버는 transparent 하게 설계하여, 사용자 클라이언트 툴 입장에서는 KAC Proxy 서버가 존재하는지 모르도록 하였습니다.

기술적 설명

KAC 접근제어 기능이 어떻게 동작하는지 기술적 관점에서 단계별로 설명하겠습니다. 기본적으로 클러스터 내의 리소스 접근에 대한 허용과 차단은 KAC Proxy 서버에서 이루어집니다.


Technical Description

클라이언트가 요청을 보내면 KAC Proxy 서버에서는 해당 요청에 대한 권한이 있는지를 체크하는데요. 정책 체크 결과에 따라서 권한이 있으면 Kubernetes API 서버로 사용자의 요청을 전송하고, 권한이 없으면 클라이언트에 요청 권한이 없다는 에러 메세지를 전달합니다.


Technical Description

KAC Proxy 서버에서 정책에 따라 접근을 차단하거나 허용하려면 먼저, 누가 접근하려고 하는지를 식별해야 합니다. 즉 인증 기능이 필요한데요. Kubernetes 에는 클라이언트의 인증 정보를 kubeconfig 파일을 통해 관리 하고 있습니다. 그리고 대부분의 Kubernetes 클라이언트 툴들 역시 이 kubeconfig 를 사용합니다. 따라서 KAC 는 호환성을 위해 kubeconfig 를 사용한 클러스터 접근 방식은 그대로 유지하였습니다.


Technical Description

그리고 kubeconfig 파일은 사용자가 번거롭게 괸리하지 않아도 되겠끔 사용자 로컬에 KAC Agent 를 두고 Agent 가 kubeconfig 파일을 관리하는 방식을 채택하였습니다. 이를 통해 관리자의 운영부담을 덜어주었습니다.

KAC proxy 는 클라이언트의 다양한 요청들을 프로토콜별로 분석을 합니다. kubectl create pod, kubectl get pod, kubectl delete pod 명령어 처럼 리소스 생성이나 조회, 삭제 등에서 사용하는 API 뿐만 아니라 kubectl exec 명령어로 pod 내의 컨테이너에 접속하는 경우 그리고 kubectl 명령어에 –watch 옵션을 주어 사용하는 경우에도 이벤트를 분석합니다.


Technical Description

특히 kubectl exec 명령어로 pod 내의 컨테이너에 접속하는 경우 KAC proxy 서버는 stream 을 분석하여 컨테이너 안에서 사용자가 어떤 입력을 했고 어떤 출력을 받았는지를 확인할 수 있습니다. 그리고 이를 플레이어를 통해 재생할 수 있도록 기능을 구현하였습니다.


Technical Description

사용자가 kubectl 명령어에 –watch 옵션을 주어 조회하는 경우, 리소스에 상태변화가 생길때마다 스트림으로 응답을 받는데요. KAC proxy 서버는 이 과정에서 이벤트 스트림 내용을 분석해서, 사용자에게 권한이 있는 리소스 정보들만 볼 수 있도록 기능을 구현하였습니다. 예를 들어 kubectl –watch 옵션으로 리소스 상태를 감시하면, 리소스 상태가 변경되었을때 각 이벤트에는 추가, 삭제, 수정 정보뿐만 아니라 pod, deployment 등의 실제 리소스 정보도 같이 전달되는데요. KAC proxy 서버에서는 이러한 이벤트 스트림을 실시간으로 decode 하여, 접근 제어 정책에 위반하는 리소스가 없는지를 체크하고 필터링하였습니다.


Technical Description

다음으로 사용자가 kubectl get pod –all-namespaces 명령어처럼 클러스터내의 전체 pod 리스트를 조회하는 경우도 있습니다. KAC는 이 경우에도 전체 Pod 리스트 응답 중에, 각 Pod 마다 사용자 권한을 체크해서 권한이 없는 리소스는 필터링 후 사용자에게 보여주도록 기능을 제공합니다. 즉 전체 Pod 리스트를 조회하더라도 실제 접근 권한이 있는 Pod 들만 볼 수 있게 되는 것이죠.

KAC proxy 서버는 사용자가 Kubernetes 리소스에 접근할 때 세밀한 권한 제어를 수행하는 핵심 구성 요소입니다. 이 서버는 Kubernetes API와 리소스에 대한 깊은 이해를 바탕으로, 들어오는 요청을 면밀히 분석하여 정확한 대상 리소스와 작업 유형을 식별합니다. 특히 주목할 만한 점은 기존 Kubernetes의 사용성을 그대로 유지하면서도, 모든 클라이언트 요청에 대해 철저한 접근 권한 검증을 수행한다는 것입니다.

RBAC 명세 개선

서두에서 말씀드린 것처럼 Kubernetes RBAC 명세에는 몇가지 한계가 존재합니다. 그렇다면 KAC 에서는 이를 어떻게 개선했는지 설명드리겠습니다.


RBAC Specifications

Kubernetes RBAC 명세로는 표현하지 못하는 것들을 지원하기 위하여 KAC는 자체 Policy 명세를 제공합니다. 위 그림이 KAC Policy 명세 예제 인데요. 내용을 보시면, 크게 resources, subjects, actions, conditions 4가지 항목으로 나뉩니다. 먼저 resources 항목에는 어떤 클러스터를 대상으로 할 것인지 클러스터 이름을 지정할 수 있습니다. 다음으로 subjects 항목에는 어떤 kubernetes group이나 user 권한으로 리소스에 접근할 것인지를 지정합니다. 그리고 actions 항목에는 pod나 deployment 같은 리소스에 어떤 action을 할 수 있는지를 지정하고, 마지막으로 conditions 항목에는 태그나 사용자 속성으로도 접근제어 조건을 걸 수 있도록 명세를 제공합니다.


RBAC Specifications

resources 항목에는 접근 제어할 클러스터 이름을 넣습니다. 위 그림처럼 여러개를 지정할 수 있기에, 멀티 클러스터를 운영하더라도 하나의 명세로 통합적으로 접근제어 policy 를 관리할 수 있습니다. subject 항목에는 KAC proxy 서버가 Kubernetes API 서버를 호출할때에 어떤 kubernetes group 이나 user 권한으로 호출할지를 지정할 수 있는데요. 이는 kubernetes 의 impersonation 기능을 사용하는 것으로 KAC proxy 서버가 Kubernetes API 서버를 호출할때에 여기에 지정된 Kubernetes group 의 권한으로 Kubernetes API 서버를 호출하게 됩니다. 다음으로 actions 항목에는 실제 접근 제어할 Kubernetes 리소스 타입와 namespace, 그리고 이름, verb 등을 지정하는데요. wild card 나 pattern matching 표현을 지원하기 때문에, 기존 Kubernetes Role 명세처럼 하나씩 리소스 이름을 지정할 필요가 없어졌습니다.


RBAC Specifications

Deny rule도 지원합니다. 서두에서 말씀드린 것처럼 현재 Kubernetes RBAC의 Role 명세는 allow rule만 지원하는데요. deny rule을 지원함으로서 black list 기반으로도 접근제어를 할 수 있게 되었습니다. 이어서 conditions 항목에 이 policy가 적용될 조건을 넣을 수 있는데요. 여기서는 클러스터의 태그나 사용자의 속성값을 기반으로 policy를 언제 적용할지를 지정할 수 있습니다. 사용자 속성의 경우 예를 들어 팀을 지정할 수 있는데요. 팀별로 속성을 지정할 수 있게 함으로서, 정책 적용이 좀 더 편해집니다. 마지막으로 클러스터 태그는 클러스터의 속성인데요. 태그는 멀티 클러스터 환경에서 정책관리를 할때 유용하게 사용할 수 있습니다.


RBAC Specifications

KAC는 QueryPie의 다른 DAC, SAC 제품과 마찬가지로 클러스터 동기화 기능을 제공합니다. 몇번의 클릭만으로 cloud provider 마다 managed Kubernetes 목록을 불러와서 접근 제어 서버에 쉽게 등록할 수 있는데요. Kubernetes 클러스터 목록이 등록이 되고나면, 관리자가 각 클러스터마다 태그를 부여할 수 있습니다. 그리고 이 태그는 KAC Policy 명세에서 참고하여 접근 제어 설정에 활용 할 수 있는데요.

예를 들어서 클러스터 타입이 개발 클러스터 인것들만, 별도의 접근 제어 정책을 적용하고 싶다고 가정하겠습니다. 자동으로 불러와진 클러스터 목록에서 개발 클러스터들에 Clutertype은 dev 라고 태그를 입력하고요. Policy 명세의 conditions 항목에 입력한 태그 내용을 넣어주면, 해당 Policy 명세는 모든 dev 클러스터들에 일괄 적용되게 됩니다. 정리하면 kubernetes 클러스터 목록 자동 동기화 기능과, 클러스터 tag 기능을 활용하여, 수많은 클러스터들도 접근 제어 정책을 쉽게 관리할 수 있습니다.

결론

KAC는 기존 Kubernetes RBAC의 한계를 보완하여 더욱 강화된 접근 제어 기능과 효율적인 관리 경험을 제공합니다. 기술적으로는 투명한 Proxy 아키텍처와 다양한 요청 타입별 분석을 통해 기존 Kubernetes 도구들과의 완벽한 호환성을 보장하면서도, 컨테이너 접근에 대한 상세한 감사 추적이 가능합니다. 정책 관리 측면에서도 중앙 집중형 관리 방식을 통해 관리자가 수많은 클러스터에 대한 접근 통제를 일관성 있게 설정하고 관리할 수 있도록 지원합니다.

SaaS 환경의 확산으로 증가하는 Kubernetes 클러스터를 보다 안전하고 효율적으로 운영하기 위해 QueryPie KAC 는 필수 도구로 자리잡고 있습니다. 이제 QueryPie KAC를 활용해 기업의 클러스터 자산을 보호하고 운영 효율성을 극대화해보세요.

3 Minutes to Wow !

Let us show you how QueryPie can transform the way you govern and share your sensitive data.

Take a Virtual Tour