오늘도 기록하는 중 GitHub

Container & Orchestration/Kubenetes

Kubernetes - 멀티 테넌시 환경 구축

YongE 2025. 5. 21. 11:50

🔄 쿠버네티스 멀티 테넌시 환경 구축


이번에 실습을 겸해 쿠버네티스의 멀티 테넌시 환경을 구축하게 됐다. 테넌시와 테넌트가 무엇인지, 어떻게 멀티 테넌시 환경을 구축할 수 있는지에 대해서 다뤄보고자 한다!

🤔 멀티 테넌시란 무엇인가?

멀티 테넌시(Multi-tenancy)는 하나의 소프트웨어 인스턴스가 여러 사용자 그룹, 즉 테넌트(tenant)에게 서비스를 제공하도록 설계된 소프트웨어 아키텍처다. 쿠버네티스 컨텍스트에서는 하나의 쿠버네티스 클러스터를 여러 테넌트가 공유하는 형태를 의미한다.

테넌트의 정의

테넌트는 쿠버네티스에서 다양하게 정의될 수 있다. 한 조직 내 여러 팀, 다수의 고객사, 또는 독립적인 사용자 그룹을 의미할 수 있다. 예를 들면 다음과 같다.

  • 다중 팀 사용 환경 조직 내 여러 팀이 클러스터를 공유하는 형태로, 각 팀은 일반적으로 서비스 복잡도에 따라 스케일되는 워크로드를 배포한다.
  • 다중 고객 환경 SaaS 회사가 여러 고객을 위한 서비스를 단일 클러스터에서 운영하는 경우다.

테넌시의 형태

쿠버네티스에서 멀티 테넌시는 크게 다음과 같은 형태로 나눌 수 있다.

  1. 단일 테넌트 모델 각 클러스터가 단일 테넌트를 위해 전용으로 운영되는 방식이다. 매우 일반적인 경우다.
  2. 완전 멀티 테넌트 환경 하나의 클러스터에서 다양한 테넌트의 워크로드가 함께 실행되는 방식이다.
┌─────────────────────┐     ┌─────────────────────────────────┐
│     단일 테넌트 모델    │     │      완전 멀티 테넌트 환경           │
├─────────────────────┤     ├─────────────────────────────────┤
│ ┌───────┐ ┌───────┐ │     │ ┌───────┬───────┬───────────┐   │
│ │클러스터 │ │ 클러스터│ │     │ │테넌트A  │테넌트B  │ 테넌트C    │   │
│ │ 테넌트A │ │ 테넌트B│ │  vs │ ├───────┴───────┴───────────┤   │
│ └───────┘ └───────┘ │     │ │       단일 클러스터          │   │
│                     │     │ └───────────────────────────┘   │
└─────────────────────┘     └─────────────────────────────────┘

💰 왜 멀티 테넌시를 구현하지?

멀티 테넌시 환경 구축은 다음과 같은 여러 가지 이점을 제공한다.

비용 효율성

여러 테넌트가 하나의 인프라를 공유함으로써 다양한 비용 절감 효과를 얻을 수 있다.

  • 인프라 비용 절감 AWS EKS 베스트 프랙티스에 따르면, 전용 클러스터 대비 멀티 테넌트 클러스터 운영 시 인프라 비용을 40-60% 절감할 수 있다.
  • 관리 오버헤드 감소 여러 클러스터를 별도로 관리하는 것보다 하나의 클러스터를 관리하는 것이 더 효율적이다.
  • 리소스 활용 최적화 컨테이너 기반으로 리소스를 효율적으로 활용할 수 있어 리소스 낭비를 줄일 수 있다.

운영 효율성 향상

멀티 테넌시 환경은 운영적인 측면에서도 많은 이점을 제공한다.

  • 유지보수 용이성 오류 발생 시 단일 시스템만 수정하면 모든 테넌트에게 적용되며, 업데이트 역시 한 번의 작업으로 모든 테넌트에게 배포할 수 있다.
  • 관리의 간소화 vCluster와 같은 도구를 사용하면 모든 네임스페이스와 가상 클러스터의 관리를 단일화할 수 있다.
  • 자동화 확장 쿠버네티스 환경에서 서비스 확장을 자동화하여 테넌트 요구사항에 따라 신속하게 대응할 수 있다.

유연성과 확장성

비즈니스 요구사항 변화에 유연하게 대응할 수 있는 장점이 있다.

  • 동적 자원 할당 필요에 따라 테넌트 간 리소스를 동적으로 재분배할 수 있다.
  • 가상 클러스터 활용 vCluster를 이용한 가상 클러스터 구현 시 물리 노드 1개에서 최대 32개 테넌트 환경을 운영할 수 있다.
  • 절전 모드 기능 유휴 시간에는 리소스 사용량을 80%까지 축소할 수 있어 효율적인 확장이 가능하다.

멀티 테넌시의 도전 과제

멀티 테넌시 구현 시 고려해야 할 주요 도전 과제도 있다.

  • 보안 위험 모든 테넌트의 데이터가 동일한 시스템에 공존하므로, 보안 침해 발생 시 모든 테넌트의 정보가 유출될 위험이 있다.
  • Noisy Neighbor 문제 특정 테넌트가 과도한 자원을 소비하여 다른 테넌트의 워크로드 성능에 영향을 미치는 현상이 발생할 수 있다.
  • 장애 전파 위험 시스템에 버그나 장애가 발생하면 모든 테넌트에게 영향이 미칠 수 있다.

🌟 멀티 테넌시 구현 방식


쿠버네티스에서 멀티 테넌시를 구현하는 다양한 접근 방식이 있다.

소프트 멀티테넌시

소프트 멀티테넌시는 네이티브 쿠버네티스 구조를 사용하여 테넌트를 논리적으로 분리하는 방식이다.

  • 적용 요소 네임스페이스, RBAC, 네트워크 정책, 리소스 쿼터 등을 활용한다.
  • 특징 구현이 상대적으로 간단하지만, 노드 레벨까지 완전한 격리를 제공하지는 않는다.
  • 적합한 환경 조직 내 여러 팀이 서로 신뢰하는 환경에 적합하다.

하드 멀티테넌시

하드 멀티테넌시는 테넌트 간 더 강력한 격리를 제공하는 접근 방식이다.

  • 적용 요소 각 테넌트에 대해 별도의 클러스터를 프로비저닝한다.
  • 특징 보안성은 높지만 운영 복잡도와 비용이 증가한다.
  • 적합한 환경 테넌트 간 신뢰가 낮거나 엄격한 보안 요구사항이 있는 환경에 적합하다.

가상 클러스터 접근법

가상 클러스터는 호스트 쿠버네티스 클러스터 내에 가상 컨트롤 플레인을 생성하는 방식이다.

  • 적용 요소 vCluster와 같은 도구를 사용하여 클러스터 내에 가상 컨트롤 플레인을 생성한다.
  • 특징 각 가상 클러스터는 고유한 API 서버, 컨트롤러 매니저를 가지며 호스트 클러스터와 리소스를 공유한다.
  • 적합한 환경 테넌트에게 완전한 쿠버네티스 경험을 제공하면서도 리소스를 효율적으로 활용하고자 하는 환경에 적합하다.
┌─────────────────────────────────────────────────┐
│             호스트 쿠버네티스 클러스터                │
│ ┌───────────────────┐  ┌───────────────────┐    │
│ │   가상 클러스터A     │  │    가상 클러스터B     │   │
│ │ ┌───────────────┐ │  │ ┌───────────────┐ │   │
│ │ │  컨트롤 플레인   │ │  │ │   컨트롤 플레인  │ │   │
│ │ └───────────────┘ │  │ └───────────────┘ │   │
│ └───────────────────┘  └───────────────────┘   │
│                                                 │
│ ┌─────────────────────────────────────────────┐ │
│ │               물리적 노드 풀                   │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘

🔧 쿠버네티스 멀티 테넌시 구현 요소


쿠버네티스에서 멀티 테넌시 환경을 구현하기 위한 핵심 요소들을 살펴본다.

네임스페이스 분리

네임스페이스는 테넌트 간 기본적인 논리적 분리를 제공한다.

  • 역할 리소스를 그룹화하고 테넌트 간에 리소스 이름 충돌을 방지한다.
  • 한계 전역적으로 범위가 지정된 유형(노드, PV, StorageClass 등)에는 적용되지 않는다.
  • 주의사항 네임스페이스로 구현된 소프트 멀티테넌시는 테넌트에게 필터링된 네임스페이스 목록을 제공할 수 없다. 특정 네임스페이스를 볼 수 있는 테넌트는 모든 네임스페이스를 볼 수 있다.

리소스 쿼터(ResourceQuota)

ResourceQuota는 테넌트별 리소스 사용량을 제한하여 공정한 자원 분배를 보장한다.

  • 제한 대상 CPU, 메모리, 스토리지, 파드 수, 서비스 수 등 다양한 자원을 제한할 수 있다.
  • 필요성 특정 테넌트가 클러스터의 모든 자원을 독점하여 다른 테넌트의 워크로드에 영향을 주는 것을 방지한다.
  • 구현 방법 네임스페이스별로 ResourceQuota 객체를 생성하여 해당 네임스페이스의 총 리소스 사용량을 제한한다.

네트워크 정책(NetworkPolicy)

NetworkPolicy는 테넌트 간 네트워크 트래픽을 제어하여 보안을 강화한다.

  • 역할 파드 간 통신을 제한하여 테넌트 워크로드 간의 네트워크 격리를 제공한다.
  • 권장 접근법 기본 정책으로 모든 트래픽을 차단한 후, 필요한 통신만 명시적으로 허용하는 화이트리스트 방식을 사용한다.
  • 주의사항 기본적으로 테넌트는 CoreDNS를 통해 클러스터 내 모든 서비스에 대한 정보를 쿼리할 수 있으므로, DNS 보안을 위한 추가 조치가 필요할 수 있다.

RBAC(역할 기반 접근 제어)

RBAC는 테넌트의 권한을 세밀하게 제어하는 메커니즘을 제공한다.

  • 역할 테넌트가 액세스할 수 있는 쿠버네티스 리소스와 수행할 수 있는 작업을 정의한다.
  • 구성요소 Role(네임스페이스 범위)과 RoleBinding, ClusterRole(클러스터 전체 범위)과 ClusterRoleBinding을 사용한다.
  • 베스트 프랙티스 최소 권한의 원칙에 따라 테넌트에게 필요한 최소한의 권한만 부여한다.

정책 엔진

정책 엔진은 쿠버네티스 내에서 정책을 강제하여 보안과 컴플라이언스를 향상시킨다.

  • Kyverno 쿠버네티스 네이티브 정책 엔진으로, 리소스 생성 및 변경 시 정책을 검증하고 자동으로 수정할 수 있다.
  • OPA Gatekeeper Kubernetes 어드미션 컨트롤러로서 OPA(Open Policy Agent)로 생성된 정책을 시행한다.
  • 활용 사례 네임스페이스 생성 시 자동으로 PodSecurityStandards를 적용하거나, 권한 상승 시도를 차단하는 정책을 구현할 수 있다.

💻 멀티 테넌시 환경 구현 예시

쿠버네티스 멀티 테넌시 환경을 다음과 같은 설정 파일을 활용하여 구현해볼 수 있다.

네임스페이스와 리소스 쿼터 설정

테넌트별 네임스페이스를 생성하고 리소스 쿼터를 설정한다.

apiVersion: v1
kind: Namespace
metadata:
  name: tenant-a-ns
  labels: 
    tenant: tenant-a
    kubernetes.io/metadata.name: tenant-a-ns
---
apiVersion: v1
kind: Namespace
metadata:
  name: tenant-b-ns
  labels:
    tenant: tenant-b
    kubernetes.io/metadata.name: tenant-b-ns
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: tenant-a-quota
  namespace: tenant-a-ns
spec:
  hard:
    requests.cpu: "1"  
    requests.memory: 512Mi 
    limits.cpu: "2"     
    limits.memory: 1Gi  
    pods: "10"          
    services: "2"       
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: tenant-b-quota
  namespace: tenant-b-ns
spec:
  hard:
    requests.cpu: "0.5"
    requests.memory: 512Mi
    limits.cpu: "1"
    limits.memory: 1Gi
    pods: "5"
    services: "2"

네트워크 정책 구현

테넌트 간 네트워크 트래픽을 격리하고 필요한 통신만 허용한다.

# 모든 인그레스 트래픽 차단
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: tenant-a-ns
spec:
  podSelector: {} # 네임스페이스 내 모든 파드에 적용
  policyTypes:
  - Ingress
---
# DNS 통신 및 외부 인터넷 접속 허용
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-egress
  namespace: tenant-a-ns
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0

RBAC 설정

테넌트 사용자에게 적절한 권한을 부여한다.

# 테넌트 A의 개발자를 위한 롤 생성
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: tenant-a-developer
  namespace: tenant-a-ns
rules:
- apiGroups: [""]
  resources: ["pods", "services", "configmaps", "secrets"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
  resources: ["deployments", "statefulsets"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# NetworkPolicy는 명시적으로 제외됨
---
# 롤 바인딩
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: tenant-a-developers
  namespace: tenant-a-ns
subjects:
- kind: Group
  name: tenant-a-dev
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: tenant-a-developer
  apiGroup: rbac.authorization.k8s.io

아래는 네임스페이스와 네트워크 정책 적용로 간단히 구축 과정을 진행한 예시다.

Kyverno 정책 적용

위에서 언급한 Kyberno로 자동화된 보안 정책을 적용할 수 있다.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-pod-security-standard
spec:
  validationFailureAction: enforce
  background: false
  rules:
  - name: require-pod-security-restricted
    match:
      resources:
        kinds:
        - Namespace
    generate:
      kind: LabelSelector
      name: pod-security.kubernetes.io/enforce
      namespace: "{{request.object.metadata.name}}"
      data:
        value: "restricted"

💡 팁

Calico CNI와 결합된 네트워크 정책(NetworkPolicy)은 테넌트 네임스페이스 간 트래픽 차단 기본 정책(default-deny)을 적용한 후, DNS 서비스(coredns:53) 접근 등 필수 통신만 허용하는 화이트리스트 방식을 채택하는 것이 보안 관점에서 권장된다.

반응형