이 페이지에서는 Google Kubernetes Engine(GKE)의 클러스터 멀티테넌시를 설명합니다. 여기에서는 단일 조직의 여러 사용자가 공유하는 클러스터 및 SaaS(Software as a service) 애플리케이션의 고객별 인스턴스가 공유하는 클러스터가 포함됩니다. 수많은 단일 테넌트 클러스터를 관리하는 대신 클러스터 다중 테넌트를 사용할 수 있습니다.
또한 이 페이지에서는 다중 테넌트 클러스터를 관리하는 데 사용되는 Kubernetes 및 GKE 기능을 요약합니다.
다중 테넌트란 무엇인가요?
다중 테넌트 클러스터는 '테넌트'라고 호칭되는 여러 사용자 및 작업 부하에 공유됩니다. 다중 테넌트 클러스터의 운영자는 각 테넌트를 격리하여 한 테넌트가 해킹을 당하거나 악의적인 행동을 할 때 다른 테넌트와 클러스터가 입는 피해를 최소화해야 합니다. 또한 클러스터 리소스를 테넌트 간에 공정하게 할당해야 합니다.
다중 테넌트 아키텍처를 계획할 때는 Kubernetes의 리소스 격리 계층인 클러스터, 네임스페이스, 노드, pod, 컨테이너를 고려해야 합니다. 또한 다양한 리소스 유형을 테넌트 간에 공유할 때 보안상 문제가 없는지를 고려해야 합니다. 예를 들어 서로 다른 테넌트의 pod를 같은 노드에 예약하면 클러스터에 필요한 머신 수를 줄일 수 있습니다. 그러나 특정한 작업 부하는 코로케이션을 피해야 할 수 있습니다. 예를 들어 조직 외부의 신뢰할 수 없는 코드는 민감한 정보를 처리하는 컨테이너와 같은 노드에서 실행되도록 허용하지 말아야 합니다.
Kubernetes는 테넌트 간의 완벽한 보안 격리를 보장하지는 못하지만, 특정 사용 사례에서 충분한 보안성을 발휘하는 기능을 제공합니다. 각 테넌트와 해당 Kubernetes 리소스를 자체 네임스페이스로 분리할 수 있습니다. 그런 다음 정책을 사용하여 테넌트 격리를 적용할 수 있습니다. 정책은 일반적으로 네임스페이스 범위로 적용되며 API 액세스와 리소스 사용, 그리고 컨테이너에서 가능한 작업을 제한하는 데 사용할 수 있습니다.
다중 테넌트 클러스터의 테넌트는 다음을 공유합니다.
- 확장 프로그램, 컨트롤러, 부가기능, 커스텀 리소스 정의(CRD)
- 클러스터 제어 영역. 따라서 클러스터 운영, 보안 감사가 중앙화됩니다.
다중 테넌트 클러스터를 운영하면 여러 단일 테넌트 클러스터를 운영할 때보다 몇 가지 장점이 있습니다.
- 관리 오버헤드 감소
- 리소스 파편화 감소
- 신규 테넌트가 클러스터 생성을 기다릴 필요가 없음
다중 테넌트 사용 사례
이 섹션에서는 여러 가지 다중 테넌트 사용 사례에서 클러스터를 구성하는 방법을 설명합니다.
엔터프라이즈 다중 테넌트
엔터프라이즈 환경에서 클러스터의 테넌트는 조직에 속한 개별 팀입니다. 일반적으로 테넌트마다 네임스페이스가 한 개씩 있습니다. 멀티 테넌시 대신 클러스터별 테넌트 또는 Google Cloud 프로젝트별 테넌트를 사용하는 대체 모델을 관리하는 것이 더 어렵습니다. 네임스페이스 내부의 네트워크 트래픽은 제한되지 않습니다. 네임스페이스 간의 네트워크 트래픽은 명시적으로 허용되어야 합니다. Kubernetes 네트워크 정책을 사용하여 이러한 정책을 적용할 수 있습니다.
클러스터 사용자는 권한에 따라 세 가지 역할로 구분됩니다.
- 클러스터 관리자
- 모든 테넌트를 관리하는 전체 클러스터 관리자를 위한 역할입니다. 클러스터 관리자는 모든 정책 객체를 생성, 조회, 업데이트, 삭제할 수 있습니다. 또한 네임스페이스를 만들어 네임스페이스 관리자에게 할당할 수 있습니다.
- 네임스페이스 관리자
- 특정 단일 테넌트의 관리자를 위한 역할입니다. 네임스페이스 관리자는 자신의 네임스페이스에 속하는 사용자를 관리할 수 있습니다.
- 개발자
- 이 역할의 구성원은 네임스페이스에서 포드, 작업, 인그레스 등의 정책이 아닌 객체를 만들고, 읽고, 업데이트하고, 삭제할 수 있습니다. 개발자는 자신이 액세스할 수 있는 네임스페이스에서만 이러한 권한을 갖습니다.
엔터프라이즈 조직에 여러 멀티 테넌트 클러스터를 설정하는 방법에 대한 자세한 내용은 엔터프라이즈 멀티테넌시 권장사항을 참조하세요.
SaaS 제공업체 멀티테넌시
SaaS 제공업체 클러스터의 테넌트는 애플리케이션의 고객별 인스턴스 및 SaaS의 제어 영역입니다. 네임스페이스 범위 정책을 활용하려면 애플리케이션 인스턴스 및 SaaS의 제어 영역 구성요소를 자체 네임스페이스로 구성해야 합니다. 최종 사용자는 Kubernetes 제어 영역과 직접 상호작용할 수 없으며, Kubernetes 제어 영역과 상호작용하는 SaaS의 인터페이스를 대신 사용합니다.
예를 들어 블로그 플랫폼을 다중 테넌트 클러스터에서 실행할 수 있습니다. 이 경우 테넌트는 각 고객의 블로그 인스턴스 및 플랫폼의 자체 제어 영역입니다. 플랫폼의 제어 영역과 호스팅된 각 블로그는 모두 별도의 네임스페이스에서 실행됩니다. 고객은 클러스터 운영에 관여할 수 없지만 플랫폼의 인터페이스를 통해 블로그를 생성 및 삭제하고 블로그 소프트웨어 버전을 업데이트할 수 있습니다.
다중 테넌트 정책 적용
GKE 및 Kubernetes는 다중 테넌트 클러스터를 관리하는 데 사용할 수 있는 여러 가지 기능을 제공합니다. 다음 섹션에서는 이러한 기능을 개략적으로 설명합니다.
액세스 제어
GKE에는 두 가지 액세스 제어 시스템 즉, Identity and Access Management(IAM)와 역할 기반 액세스 제어(RBAC)가 있습니다. IAM은 Google Cloud 리소스를 대상으로 한 인증과 승인을 관리할 수 있는 Google Cloud 액세스 제어 시스템입니다. IAM을 사용하여 GKE 및 Kubernetes 리소스에 대한 액세스 권한을 사용자에게 부여합니다. Kubernetes에 내장된 RBAC는 클러스터에 속하는 특정 리소스와 작업에 대한 세분화된 권한을 부여합니다.
이러한 옵션과 각 옵션을 사용할 시기에 대한 자세한 내용은 액세스 제어 개요를 참조하세요.
이러한 액세스 제어 시스템을 사용하는 방법을 알아보려면 RBAC 안내 가이드 및 IAM 안내 가이드를 참조하세요.
네임스페이스와 함께 IAM 및 RBAC 권한을 사용하여 Google Cloud Console에서 클러스터 리소스와의 사용자 상호작용을 제한할 수 있습니다. 자세한 내용은 액세스 권한을 사용 설정하고 네임스페이스별 클러스터 리소스 보기를 참조하세요.네트워크 정책
클러스터 네트워크 정책을 통해 클러스터 포드 간의 통신을 제어할 수 있습니다. 정책은 특정 Pod가 통신할 수 있는 네임스페이스, 라벨, IP 주소 범위를 지정합니다.
GKE에서 네트워크 정책을 적용하는 방법은 네트워크 정책 안내를 참조하세요.
네트워크 정책을 작성하는 방법은 네트워크 정책 가이드를 참조하세요.
리소스 할당량
리소스 할당량은 네임스페이스의 객체가 사용하는 리소스의 양을 관리합니다. 할당량을 설정할 때 CPU 및 메모리 사용량을 기준으로 하거나 객체 수를 기준으로 할 수 있습니다. 리소스 할당량을 통해 모든 테넌트가 자신에게 할당된 클러스터 리소스까지만 사용하도록 제한할 수 있습니다.
자세한 내용은 리소스 할당량 문서를 참조하세요.
정책 기반 포드 허용 제어
보안 경계를 위반하는 포드가 클러스터에서 실행되지 않도록 하려면 허용 컨트롤러를 사용합니다. 허용 컨트롤러는 정의한 정책에 따라 포드 사양을 확인하고 해당 정책을 위반하는 포드가 클러스터에서 실행되지 않도록 할 수 있습니다.
GKE는 다음 유형의 허용 제어를 지원합니다.
- 정책 컨트롤러: 사전 정의된 정책이나 커스텀 정책을 선언하고 Fleet을 사용하여 규모에 맞게 클러스터에 적용합니다. 정책 컨트롤러는 오픈소스 Gatekeeper 개방형 정책 에이전트를 구현한 것으로, GKE Enterprise의 기능입니다.
- PodSecurity 허용 컨트롤러: 개별 클러스터 또는 특정 네임스페이스에서 포드 보안 표준에 해당하는 사전 정의된 정책을 적용합니다.
Pod 안티어피니티
포드 안티-어피니티를 사용하면 서로 다른 테넌트의 포드가 같은 노드에 예약되지 않게 할 수 있습니다.
안티어피니티는 Pod 라벨에 따라 제한됩니다.
예를 들어 아래 Pod 사양은 라벨이 "team":
"billing"
인 Pod를 기술하며, 이 Pod가 라벨이 없는 Pod와 함께 예약되지 않도록 하는 안티어피니티 규칙을 포함합니다.
apiVersion: v1
kind: Pod
metadata:
name: bar
labels:
team: "billing"
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: "kubernetes.io/hostname"
labelSelector:
matchExpressions:
- key: "team"
operator: NotIn
values: ["billing"]
이 기법의 단점은 악의적인 사용자가 임의의 Pod에 team: billing
라벨을 적용하여 규칙을 회피할 수 있다는 점입니다. 클러스터의 테넌트를 신뢰할 수 없는 경우 Pod 안티어피니티만으로는 안전하게 정책을 적용할 수 없습니다.
자세한 내용은 pod 안티어피니티 문서를 참조하세요.
taint 및 톨러레이션이 있는 전용 노드
노드 taint는 워크로드 예약을 제어하는 또 다른 방법입니다. 노드 taint를 사용하여 특정 테넌트가 특화된 노드를 사용하도록 예약할 수 있습니다. 예를 들어 워크로드에 GPU가 필요한 특정 테넌트 전용으로 GPU 탑재 노드를 할당할 수 있습니다. Autopilo 클러스터의 경우 노드 톨러레이션은 워크로드 분리에만 지원됩니다. 노드 taint는 필요에 따라 노드 자동 프로비저닝에 의해 자동으로 추가됩니다.
노드 풀을 특정 테넌트 전용으로 할당하려면 노드 풀에 effect: "NoSchedule"
taint를 적용합니다. 그러면 해당 톨러레이션을 갖는 pod만 노드 풀의 노드에 예약될 수 있습니다.
이 기법의 단점은 악의적인 사용자가 pod에 톨러레이션을 추가하여 전용 노드 풀에 액세스할 수 있다는 것입니다. 클러스터의 테넌트를 신뢰할 수 없는 경우 노드 taint 및 toleration만으로는 안전하게 정책을 적용할 수 없습니다.
자세한 내용은 Kubernetes 문서의 taint 및 톨러레이션(toleration)을 참조하세요.