해당 스터디는 90DaysOfDevOps
https://github.com/MichaelCade/90DaysOfDevOps
를 기반으로 진행한 내용입니다.
Day 4 - Manage Kubernetes Add-Ons for Multiple Clusters Using Cluster Run-Time State
쿠버네티스는 수많은 애플리케이션(앱)을 여러 컴퓨터에서 효율적으로 관리해주는 시스템이다. 이때 관리해야 할 컴퓨터 묶음을 '클러스터'라고 부른다.
그런데 회사가 커지면, 이런 클러스터를 한두 개가 아니라 수십, 수백 개씩 운영 (멀티 클러스터 아키텍쳐)하게 된다. (개발팀용 클러스터, 테스트팀용 클러스터, 실제 서비스용 클러스터 등)
이 모든 클러스터에 보안 프로그램, 모니터링 도구, 네트워크 설정 등 필수 프로그램(애드온)을 일일이 설치하고, 버전이 바뀔 때마다 업데이트하고, 설정이 바뀌지 않도록 관리하는 것은 매우 번거롭고 실수하기 쉬운 작업들이다.
Project Sveltos는 바로 이 문제를 해결하기 위해 만들어졌다.
Sveltos는 1번 주제에서 언급된 멀리클러스터 환경의 애드온 추가에 대한 설정 불일치, 반복적인 수작업, 중앙 가시성의 부재 등 문제를 해결하기 위해 '중앙 집중식 선언적 관리' 라는 방식으로 해결한다.
Sveltos는 지시서의 내용을 한번만 실행하고 끝내는 것이 아닌, 끊임없이 현재 상태와 원하는 상태를 비교하고 차이를 조정한다.
해당 작동 방식으로, Sveltos는 멀티 클러스터 환경의 일관성을 보장하고, 수작업을 자동화, 인적 오류를 방지하는 자동 관리 매니저의 역할을 수행할 수 있다.
해당 YAML은 Sveltos의 가장 기본적인 기능으로, 특정 레이블이 붙은 모든 클러스터에 지정된 버전의 HELM CHART를 설치하는 간단한 지시서이다.
apiVersion: config.projectsveltos.io/v1alpha1
kind: ClusterProfile
metadata:
name: demo
spec:
clusterSelector: env=prod # 해당 레이블이 있는 모든 Cluster 지정
syncMode: Continuous
helmCharts: # 헬름 차트를 이용하여 설치하고 싶은 애드온 지정
- repositoryURL: https://kyverno.github.io/kyverno/
repositoryName: kyverno
chartName: kyverno/kyverno
chartVersion: v2.5.0
releaseName: kyverno-latest
releaseNamespace: kyverno
helmChartAction: Install
ClusterSelector 필드를 사용하여 'env=prod' 레이블이 있는 모든 클러스터에 보안 정책 도구인 Kyverno v2.5.0을 일괄적으로 설치하고 싶을때 사용하는 YAML 예시이다.
HELM CHART로 패키징되지 않은 일반적인 쿠버네티스 YAML 리소스를 배포하는 기능이다.
여러 YAML 파일을 하나의 ConfigMap이나 Secret에 묶어둔 후, ClusterProfile의 policyRefs 섹션에서 이를 참조하여 배포하는 방식이다.
# 참조의 대상이 되는 ConfigMap YAML
apiVersion: v1
kind: ConfigMap
metadata:
name: contour-gateway
namespace: default
data:
gatewayclass.yaml: |
kind: GatewayClass
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
name: contour
spec:
controllerName: projectcontour.io/projectcontour/contour
gateway.yaml: |
kind: Namespace
apiVersion: v1
metadata:
name: projectcontour
---
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
name: contour
namespace: projectcontour
spec:
gatewayClassName: contour
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
해당 YAML은 Sveltos의 ClusterProfile이 참조하는 소스가 되는 ConfigMap으로, 여러 개의 YAML 리소스를 하나의 ConfigMap 안에 데이터로 저장한 명세서이다.
해당 YAML의 경우에는 쿠버네티스 Gateway를 설정하는 데 필요한 여러 YAML 리소스 (GatewayClass, Namespace, Gateway) 들을 ConfigMap 안에 묶어둔 YAML이다.
apiVersion: config.projectsveltos.io/v1alpha1
kind: ClusterProfile
metadata:
name: deploy-contour-gateway
spec:
clusterSelector: env=production # 'env=production' 레이블이 붙은 모든 클러스터를 대상으로 지정
# 참조할 ConfigMap or Secret 목록을 정의
policyRefs:
- name: contour-gateway # 'contour-gateway' ConfigMap을 가리킴.
namespace: default
kind: ConfigMap
이후, Sveltos의 ClusterProfile을 통해 policyRefs 섹션에 앞서 명세한 'contour-gateway' ConfigMap을 가리킨다.
그러면 Sveltos는 해당 ConfigMap의 data 섹션에 있는 YAML 내용을 가져와서 clusterSelector에 해당하는 모든 클러스터에 배포해준다.
Sveltos의 가장 강력한 기능 중 하나로, 배포 시점에 각 클러스터의 고유한 정보를 가져와 설정 파일을 동적으로 완성하는 기능이다.
apiVersion: config.projectsveltos.io/v1alpha1
kind: ClusterProfile
metadata:
name: deploy-calico
spec:
clusterSelector: env=prod
helmCharts:
- repositoryURL: https://projectcalico.docs.tigera.io/charts
repositoryName: projectcalico
chartName: projectcalico/tigera-operator
chartVersion: v3.24.5
releaseName: calico
releaseNamespace: tigera-operator
helmChartAction: Install
values: |
installation:
calicoNetwork:
ipPools:
{{ range $cidr := .Cluster.spec.clusterNetwork.pods.cidrBlocks }}
- cidR: {{ $cidr }} # 동적 템플릿 적용
{{ end }}
encapsulation: VXLAN
네트워크 프로그램인 Calico를 설치할 때, 각 클러스터마다 다른 네트워크 주소 범위 (Pod CIDR)을 설정값으로 넣어주어야 한다.
해당 YAML의 values 필드를 이용하여 Sveltos가 배포 대상 클러스터 (.Cluster)의 정보에서 pods.cidrBlocks 값을 자동으로 조회하여 cidr 필드를 채워 놓도록 지시하고 있다.
해당 기능을 사용함으로써, 관리자는 클러스터마다 다른 설정 파일을 만들 필요 없이, 템플릿 하나로 모든 클러스터에 배포할 수 있다.
추가적으로, 강의에서는 sveltos와 Crossplane (쿠버네티스를 사용하여 클라우드 인프라를 관리하게 해주는 도구) 를 사용하여, Google Storage bucket을 생성하는 과정을 자동화하는 일련의 메커니즘을 설명한다.
1. 관리자가 ClusterProfile을 Management Cluster에 배포
apiVersion: config.projectsveltos.io/v1alpha1
kind: ClusterProfile
metadata:
name: crossplane-orchestration-profile
spec:
clusterSelector: create-bucket=true
templateResourceRefs:
# Sveltos에게 Bucket 리소스가 생성되면, 그 리소스의 상태를 StorageBucket이라는 이름으로 계속 주시(Watch)하고 있으라고 지시
- resource: # Crossplane이 생성할 Bucket 리소스를 가리킴
kind: Bucket
name: user-storage-bucket-{{ .Cluster.Name }} # 버킷 이름은 클러스터마다 고유하게 설정
namespace: default
identifier: StorageBucket # 해당 리소스를 템플릿 안에서 "StorageBucket"이라는 이름으로 사용
# 사용할 템플릿들이 저장된 ConfigMap 목록입니다.
policyRefs:
# 템플릿 1: Crossplane Bucket 생성용
- name: crossplane-bucket-template
namespace: default
kind: ConfigMap
# 템플릿 2: 최종 애플리케이션 Pod 생성용
- name: app-pod-template
namespace: default
kind: ConfigMap
2. Sveltos가 policyRefs에 따라 ConfigMap의 내용을 Management Cluster에 배포하여 Bucket 리소스를 생성한다. (Bucket 리소스 생성 요청)
# Google Cloud Storage 버킷을 생성하도록 Crossplane에 요청하는 ConfigMap YAML
apiVersion: v1
kind: ConfigMap
metadata:
name: crossplane-bucket-template
namespace: default
data:
bucket.yaml: |
# bucket.YAML은 매니지먼트 클러스터에 생성
apiVersion: storage.gcp.crossplane.io/v1alpha1
kind: Bucket
metadata:
# ClusterProfile에서 이 리소스를 찾을 수 있도록 이름이 일치해야함
name: user-storage-bucket-{{ .Cluster.Name }}
spec:
forProvider:
location: ASIA-NORTHEAST3
providerConfigRef:
name: gcp-provider-config
3. Crossplane 작업 수행 및 Sveltos의 상태 감지
4. Sveltos가 최종적으로 배포할 Pod의 YAML에서 동적 템플릿 기능을 사용하여 실제 URL값으로 교체하여 최종 Pod YAML을 완성하여 Managed Cluster에 배포한다.
apiVersion: v1
kind: ConfigMap
metadata:
name: app-pod-template
namespace: default
data:
pod.yaml: |
apiVersion: v1
kind: Pod
metadata:
name: file-uploader
spec:
containers:
- name: uploader
image: busybox
command: ["sleep", "3600"]
env:
# --- Sveltos의 동적 템플릿 기능이 사용되는 부분---
- name: BUCKET_URL
value: "{{ .StorageBucket.status.atProvider.url }}"
Sveltos는 단순히 애드온을 한번 배포하고 끝내는 것이 아니라, 배포된 상태가 관리자가 정의한 대로 계속 유지되도록 보장하는 기능을 제공한다.
만약 누군가가 Managed Cluster에 직접 접속하여 Sveltos가 배포한 리소스를 수동으로 변경하거나 삭제하면, Sveltos는 이를 '설정 드리프트 (Configuration Drift)'로 감지하고 즉시 원래 상태로 자동 복구한다.
apiVersion: config.projectsveltos.io/v1alpha1
kind: ClusterProfile
metadata:
name: kyverno
spec:
clusterSelector: env=fv
syncMode: ContinuousWithDriftDetection # 해당 기능 활성화 필드
helmCharts:
- repositoryURL: https://kyverno.github.io/kyverno/
repositoryName: kyverno
chartName: kyverno/kyverno
chartVersion: v2.5.0
releaseName: kyverno-latest
releaseNamespace: kyverno
helmChartAction: Install
클러스터의 실시간 상태 (ex. 쿠버네티스 버전)를 조건으로 클러스터를 자동으로 Labeling하고, 그 분류에 따라 적절한 애드온을 배포하는 기능이다.
이를 위해 Classifier라는 별도의 CRD를 사용해야 한다.
해당 기능을 통해 "쿠버네티스 1.24.X 버전을 실행하는 클러스터에는 Gatekeeper 3.9.0 버전을 배포하라"와 같은 정교한 자동화 소프트웨어 관리가 가능해진다.
1. 먼저, 클러스터를 분류할 규칙 (Classifier)를 정의
apiVersion: lib.projectsveltos.io/v1alpha1
kind: Classifier
metadata:
name: deploy-gatekeeper-3-9
spec:
# Classifier가 추가할 레이블
classifierLabels:
- key: gatekeeper
value: v3-9
# 클러스터가 만족해야 할 쿠버네티스 버전 조건
kubernetesVersionConstraints:
- version: 1.24.0
comparison: GreaterThanOrEqualTo
- version: 1.25.0
comparison: LessThan
만약 쿠버네티스 버전이 1.24.0 이상이고, 1.25.0 미만인 클러스터를 발견하면, 해당 클러스터에 gatekeeper: v3-9라는 레이블을 붙이라는 Classifier CRD를 정의한다.
2. 특정 레이블이 붙은 클러스터에 Gatekeeper를 배포할 ClusterProfile 정의
apiVersion: config.projectsveltos.io/v1alpha1
kind: ClusterProfile
metadata:
name: deploy-gatekeeper-3-9
spec:
# Classifier가 붙여준 레이블을 가진 클러스터 대상
clusterSelector: gatekeeper=v3-9
syncMode: Continuous
helmCharts:
- repositoryURL: https://open-policy-agent.github.io/gatekeeper/charts
repositoryName: gatekeeper
chartName: gatekeeper
chartVersion: 3.9.0
releaseName: gatekeeper
releaseNamespace: gatekeeper
helmChartAction: Install
해당 ClusterProfile YAML을 통해 gatekeeper=v3-9라는 레이블이 붙은 Cluster를 찾아서 Gatekeeper 3.9.0 버전을 설치할 수 있다.
이때, 미래에 해당하는 클러스터 중 하나가 만약 쿠버네티스 1.25 버전으로 업그레이드하게 되면, 해당 클러스터는 더이상 이 Classifier의 조건과 맞지 않게 되어 레이블이 자동으로 제거되며, 동시에 Gatekeeper 3.9.0 애드온도 해당 클러스터에서 삭제되게 된다.
Project Sveltos는 멀티 클러스터 환경의 복잡성을 해결하기 위해 4가지 핵심 가치를 제공한다.
1. 중앙 집중식 선언적 관리 (Centralized Declarative Management)
모든 클러스터의 '원하는 상태'를 매니지먼트 클러스터의 ClusterProfile을 통해 선언적으로 정의
이를 통해 관리자는 여러 클러스터를 일일이 신경 쓸 필요 없이, 단일 지점 (ManageMent Cluster)에서 전체 클러스터의 구성을 일관되게 통제할 수 있다.
2. 강력한 배포 유연성 (Powerful Deployment Flexibility)
Helm Chart, Kustomize, 그리고 일반 YAML 리소스(policyRefs) 등 다양한 형식의 애플리케이션과 설정 파일을 손쉽게 배포할 수 있다.
어떤 방식으로 패키징된 애드온이든 Sveltos를 통해 표준화된 방식으로 관리할 수 있는 유연성을 제공한다.
3. 지능형 자동화 및 오케스트레이션 (Intelligent Automation & Orchestration)
동적 템플릿을 사용하여 각 클러스터의 고유한 정보나 외부 도구 (Crossplane 등)의 작업 결과물을 배포에 동적으로 활용할 수 있다.
Classifier를 통해 클러스터의 실시간 상태(런타임)를 감지하고, 이에 맞는 정책을 자동으로 적용하는 지능적인 라이프사이클 관리를 수행할 수 있다.
4. 상태 보증 및 일관성 유지 (State Assurance & Consistency)
설정 드리프트 감지 기능을 통해 관리자가 정의한 상태가 항상 유지되도록 보장한다.
외부의 수동 변경이 발생하더라도 Sveltos가 자동으로 상태를 복구하여 전체 클러스터의 안정성과 일관성을 강력하게 유지한다.