프로덕션을 위한 Oracle Kubernetes Engine(OKE) 배포: 모범 사례 및 지침

소개

이 자습서는 Oracle Cloud Infrastructure Kubernetes Engine(OKE) 자동화 시리즈의 세 번째 자습서로, 두 번째 자습서인 고급 Terraform 모듈을 사용하여 Oracle Cloud Infrastructure Kubernetes Engine(OKE) 배포에 소개된 개념을 기반으로 합니다. 이 가이드에서는 프로덕션 준비 OKE 배포에 중점을 두고 클러스터 안정성을 개선하고 비용을 최적화하며 운영을 간소화하는 주요 모범 사례를 살펴봅니다. Terraform을 사용하는 모범 사례 중 일부를 시연하는 동시에 사용자가 클러스터를 구축할 때 겪는 일반적인 함정을 강조합니다.

기존 VCN에 OKE를 배포하는 것이 중요한 이유

프로덕션급 OKE 클러스터를 구축하려면 네트워킹, 노드 배치 및 운영 프로세스 전반에서 신중하게 계획해야 합니다. 기존 VCN(가상 클라우드 네트워크)에 배포하면 클러스터가 사전 구성된 서브넷, 라우팅 테이블 및 보안 규칙과 원활하게 통합될 수 있습니다. 이를 통해 운영 오버헤드가 줄어들고, 조직의 인프라와의 일관성이 보장되며, 여러 워크로드 또는 클러스터가 동일한 네트워크 내에서 효율적으로 공존할 수 있습니다.

기존 VCN에 배포할 때의 주요 Terraform 매개변수는 다음과 같습니다.

또는 새 환경을 처음부터 배치할 때 새 네트워크를 프로비전하도록 is_vcn_created = true를 설정합니다. terraform apply에 성공한 후 Terraform은 새로 생성된 VCN 및 해당 서브넷의 OCID를 출력에 캡처합니다. 이러한 값은 is_vcn_created = false를 설정하고 terraform.tfvars 파일에서 저장된 OCID를 참조하여 이후 배치에서 재사용할 수 있으며, 이를 통해 Terraform은 새 네트워크를 생성하는 대신 기존 네트워크를 사용할 수 있습니다. 이 단계에서 terraform plan를 실행하면 현재 VCN 및 서브넷이 보존되어 불필요한 인프라 변경사항이 발생하지 않도록 합니다.

네트워크 기반이 마련된 이 자습서에서는 OKE 클러스터를 보다 탄력적이고 확장 가능하며 쉽게 작동할 수 있도록 프로덕션 지향 모범 사례 세트에 초점을 맞춥니다. 이러한 관행을 적용함으로써 고객은 조직의 정책, 거버넌스 표준 및 프로덕션 준비 운영 요구 사항에 부합하는 고가용성, 비용 효율성 및 부합하는 OKE 클러스터를 배포할 수 있습니다. oke_advanced_module.zip에서 최신 코드를 다운로드합니다.

OKE 모범 사례: 프로덕션 준비 지침

1. 노드 순환을 사용하여 OKE 노드 풀을 업그레이드합니다.

노드 사이클링은 워크로드의 중단 없이 노드 이미지, Kubernetes 버전 또는 시스템 구성을 업데이트하는 안전한 롤링 업그레이드 전략입니다. 노드 순환은 시간이 지남에 따라 클러스터를 안전하게 발전시키고 운용 작업 로드에 영향을 주지 않으면서 패치 또는 업그레이드를 적용하기 때문에 중요합니다. 이를 통해 고객은 운영 위험을 줄이고 업그레이드하는 동안 지속적인 가용성을 보장하며 최신 버전을 유지하면서 워크로드를 안정적으로 실행할 수 있습니다. OKE는 다음 두 가지 유형을 지원합니다.

maximum_surgemaximum_unavailable와 같은 매개변수는 업그레이드가 속도와 가용성의 균형을 맞추는 방법을 제어합니다. 제로 작동 중지 시간 업그레이드의 경우 maximum_surge = 1 및 maximum_unavailable = 0을 설정하여 이전 노드를 교체하기 전에 하나의 새 노드가 온라인 상태로 전환되도록 합니다. 다음은 Max surge 1 및 Max unavailable 0이 있는 노드 순환 예제를 보여줍니다.

OKENodepoolupgraded

노드 순환을 유발하는 기존 OKE 클러스터의 업그레이드를 트리거하려면 다음을 수행합니다.

terraform.tfvars 파일에서 다음을 수행합니다.

그런 다음 terraform plan를 실행합니다.

다음과 같은 출력이 표시됩니다.

terraform apply를 실행하면 OKE는 BOOT_VOLUME_REPLACE 전략을 사용하여 한 번에 한 노드씩 노드 풀 순환을 시작합니다. 이 모드에서는 기본 컴퓨트 인스턴스가 동일하게 유지되는 동안 노드의 부트 볼륨만 교체됩니다. 결과적으로 노드 업그레이드가 수행되며 개인 IP 주소와 같은 네트워크 속성은 다음과 같이 변경되지 않습니다.

OKEclusterUpgrading OKEclusterUpgrading OKEclusterUpgrading

INSTANCE_REPLACE 옵션을 사용하여 노드를 순환하려면 OKE에 대해 cycle_modesINSTANCE_REPLACE로 설정하여 노드 풀을 한 번에 하나씩 순환합니다. 이 모드에서는 컴퓨트 인스턴스 및 해당 부트 볼륨을 포함하여 각 노드가 삭제되고 처음부터 재생성됩니다. 결과적으로 노드 업그레이드는 새 Kubernetes 버전 또는 구성 변경과 같은 업데이트된 모든 속성을 적용하지만 개인 IP와 같은 네트워크 속성이 변경될 수 있습니다. 이 접근 방식은 최신 구성으로 완전히 새로 고쳐진 노드를 보장하며, 아래와 같이 롤링 교체를 통해 클러스터 가용성을 유지하면서 최대 업데이트 적용 범위를 제공합니다.

OKEclusterUpgrading OKEclusterUpgrading

2. OKE 작업자 노드 및 로드 밸런서에서 OCI 태깅을 사용하여 비용 추적

Oracle Cloud Infrastructure(OCI)에서 Kubernetes 워크로드를 실행할 때는 비용이 어디에서 발생하는지 파악하는 것이 필수적입니다. 태그 지정이 핵심입니다. OCI를 사용하면 OKE 클러스터, 작업자 노드, 로드 밸런서 및 영구 볼륨을 비롯한 모든 리소스에 정의된 태그 및 자유 형식 지정 태그를 적용할 수 있습니다. 이는 클라우드 소비에 대한 상세한 비용 보고, 손쉬운 감사 및 책임감을 가능하게 하기 때문에 중요합니다. 고객의 경우 태깅은 어떤 워크로드가 가장 많은 리소스를 소비하는지에 대한 통찰력을 제공하고, 비용 투명성을 개선하고, 클라우드 지출을 제어하기 위한 최적화 의사결정을 지원합니다.

태그 지정이 중요한 이유:

# Cluster-level tagging
cluster_freeform_tag_key   = "Environment"
cluster_freeform_tag_value = "Development"

# Node pool-level tagging
node_pool_freeform_tag_key   = "LOB"
node_pool_freeform_tag_value = "DevOps Tech"

# Bastion host tagging
freeform_tags = {
  project     = "devops"
  environment = "production"}

# Defined tagging
defined_tags = { 
  “Corporate_Standard.CostCenter”  = “Finance-123"
  “Corporate_Standard.Environment” = “Production” }

이러한 태그를 사용하면 OCI 비용 분석에서 자세한 비용 보고서를 생성하고, 가장 많은 리소스를 소비하는 워크로드를 식별하고, 확장 또는 최적화에 대한 정보에 기반한 의사 결정을 내릴 수 있습니다.

3. API 엔드포인트, 노드, 로드 밸런서 및 Pod 서브넷(해당하는 경우)을 분리합니다.

OKE는 보안, 성능 및 확장성을 개선하기 때문에 적절한 네트워크 설계를 수행하는 것이 가장 좋습니다. API 엔드포인트, 작업자 노드, Pod, 로드 밸런서 및 배스천 호스트를 별도의 서브넷으로 분리하면 중요한 트래픽이 격리되고, 사용자정의 경로 테이블 또는 NSG(네트워크 보안 그룹)가 허용되며, 한 유형의 트래픽이 다른 트래픽을 방해하지 않도록 방지합니다. 이 접근 방식은 프로덕션 환경에서 안전한 통신, 예측 가능한 라우팅 및 강력한 리소스 격리를 유지하는 데 필수적입니다.

고객은 워크로드에 영향을 주지 않고 효율적으로 확장하고 트래픽 급증 또는 공격을 처리할 수 있는 보다 안전하고 관리 가능하며 탄력적인 클러스터를 보유함으로써 이점을 누릴 수 있습니다. 다음은 서브넷에 대한 CIDR 블록을 정의할 수 있는 terrform.tfvars의 코드 조각입니다.

k8apiendpoint_private_subnet_cidr_block       = "REPLACE_WITH_YOUR_CIDR"   # API endpoint subnet
workernodes_private_subnet_cidr_block         = "REPLACE_WITH_YOUR_CIDR"   # Worker nodes subnet
pods_private_subnet_cidr_block                = "REPLACE_WITH_YOUR_CIDR"   # Pod subnet (CNI)
serviceloadbalancers_public_subnet_cidr_block = "REPLACE_WITH_YOUR_CIDR"   # Load balancer subnet
bastion_public_subnet_cidr_block              = "REPLACE_WITH_YOUR_CIDR"   # Bastion host subnet

이 연습을 수행하면 보안을 향상시키고 네트워크 관리를 단순화하며 트래픽 급증이나 공격에 대한 클러스터의 탄력성을 높일 수 있습니다.

4. 클러스터 자동 스케일러를 사용할 때 가용성 도메인 구조당 노드 풀 사용

OCI에서는 각 AD(가용성 도메인)의 용량이 독립적입니다. 노드 풀은 고가용성을 향상시키기 위해 여러 AD에 걸쳐 있을 수 있지만, 클러스터 자동 스케일러가 사용으로 설정된 경우에는 권장되지 않습니다. 자동 스케일러는 선택된 모든 AD의 용량을 필요로 하며, AD의 리소스가 부족한 경우 확장을 실패할 수 있습니다.

이를 방지하려면 자동 크기 조정이 사용으로 설정된 경우 단일 AD를 사용하도록 노드 풀을 구성해야 합니다. 한 AD에서 용량을 사용할 수 없는 경우 자동 스케일러는 다른 AD에서 대체 노드 풀을 확장할 수 있습니다.

노드 풀 구성 예:

availability_domains = [
      "REPLACE_WITH_YOUR_AD"
    ]

클러스터 자동 스케일러 구성 예:

cluster_autoscaler_config = {
  node_mapping = {
    key = "nodes"
    value = "1:5:ocid1.nodepool....."
  }
}

5. 다양한 작업 로드 요구 사항에 맞는 별도의 노드 풀(x86, ARM, GPU)

x86, ARM 또는 GPU와 같이 서로 다른 컴퓨트 구성이 필요한 워크로드에는 별도의 노드 풀을 사용합니다. 이 접근 방식은 각 워크로드가 가장 적합한 인프라에서 실행되도록 하여 리소스 활용도, 일정 관리 효율성 및 자동 크기 조정 동작을 개선합니다.

파드는 노드 레이블, 선택기, 유사성 또는 테인트와 허용을 사용하여 올바른 노드 풀로 일정이 잡혀 있으므로 Kubernetes는 필요한 아키텍처 또는 기능을 갖춘 노드에 워크로드를 배치할 수 있습니다.

고객은 전용 노드 풀과 명시적 포드 배치를 결합하여 예측 가능한 성능, 효율적인 확장 및 간소화된 클러스터 관리를 달성합니다. 이 예에서는 Intel 및 AMD 구성용으로 별도의 노드 풀이 만들어져 최적의 작업 로드 배치와 탄력적인 클러스터 작업을 보장합니다.

worker_node_pools = {
  AMD_node_pool = {
    name               = "node_pool_one"                # Node pool name
    shape              = "VM.Standard.E5.Flex"          # Compute shape
    shape_config = {
      memory = 16                                       # Memory (GB)
      ocpus  = 1                                        # OCPUs
    }
    boot_volume_size   = 50                             # Boot volume size (GB)
    operating_system   = "Oracle-Linux"                 # OS for worker nodes
    kubernetes_version = "v1.33"                        # Node Kubernetes version
    source_type        = "IMAGE"                        # Source type for image
    node_labels = {
      Trigger = "Nodes_Cycling_0"                       # Node label
    }
    availability_domains = [                            # Availability_domain setting
      "REPLACE_WITH_YOUR_AD"
    ]                                                   # ADs for node distribution
    number_of_nodes          = 1                        # Number of worker nodes
    pv_in_transit_encryption = false                    # Boot volume in-transit encryption
    node_cycle_config = {
      node_cycling_enabled = true                       # Enable node cycling by default
      maximum_surge        = 1                          # Number of surge nodes
      maximum_unavailable  = 0                          # Max unavailable nodes
      cycle_modes          = ["BOOT_VOLUME_REPLACE"]    # cycle_modes"BOOT_VOLUME_REPLACE" or "INSTANCE_REPLACE"

    }
    ssh_key = "REPLACE_WITH_YOUR_KEY"                   # SSH public key for workers nodes
  }
  Intel_node_pool = {
    name               = "node_pool_two"                # Node pool name
    shape              = "VM.Standard2.8"      	        # Compute shape
    shape_config = {
      memory = 120                                      # Memory (GB)
      ocpus  = 8                                        # OCPUs
    }
    boot_volume_size   = 50                             # Boot volume size (GB)
    operating_system   = "Oracle-Linux"                 # OS for worker nodes
    kubernetes_version = "v1.33"                        # Node Kubernetes version
    source_type        = "IMAGE"                        # Source type for image
    node_labels = {
      Trigger = "Nodes_Cycling_0"                       # Node label
    }
    availability_domains = [                            # Availability_domain setting
      "REPLACE_WITH_YOUR_AD"  
    ]                                                   # ADs for node distribution
    number_of_nodes          = 1                        # Number of worker nodes
    pv_in_transit_encryption = false                    # Boot volume in-transit encryption
    node_cycle_config = {
      node_cycling_enabled = true                       # Enable node cycling by default
      maximum_surge        = 1                          # Number of surge nodes
      maximum_unavailable  = 0                          # Max unavailable nodes
      cycle_modes          = ["BOOT_VOLUME_REPLACE"]    # cycle_modes"BOOT_VOLUME_REPLACE" or "INSTANCE_REPLACE"

    }
    ssh_key = "REPLACE_WITH_YOUR_KEY"                   # SSH public key for workers nodes
  }

}

terraform apply를 실행한 후 OKE 클러스터에 두 개의 개별 노드 풀이 표시됩니다.

OKEtwonodepools OKEIntelnodepool OKEAMDnodepool

6. 노드 커스터마이제이션에 Cloud-Init 사용

OKE에서 작업자 노드 구성을 자동화하려면 클라우드 초기화 스크립트가 필수적이며, 모든 노드에서 일관된 OS 설정, 패키지 설치 및 시스템 조정을 보장합니다. cloud-init와 Terraform을 통합하면 부팅 시 자동으로 노드를 프로비저닝하여 배포를 반복 가능하고 감사 가능하며 운영 준비가 가능합니다. cloud-init 스크립트에 대한 자세한 내용은 이 문서 사용자정의 Cloud-init 초기화 스크립트를 사용하여 관리 노드 설정을 검토하십시오.

제공된 Terraform 코드에서 각 노드 풀은 cloud_init_path 매개변수를 사용하여 cloud-init 스크립트를 참조합니다. 고객은 위 문서의 지침에 따라 요구 사항에 따라 cloud-init-general.sh의 내용을 수정할 수 있습니다. 이 데모에서는 참조된 설명서에 제공된 기본 시작 스크립트를 사용합니다. 고객은 아래와 같이 cloud_init_path 매개변수를 업데이트하여 cloud-init 스크립트의 위치를 변경할 수도 있습니다.

cloud_init_path = "cloud-init-general.sh"

이렇게 하면 노드 프로비저닝 또는 노드 순환 중에 모든 새 노드 또는 교체된 노드가 필요한 시스템 구성으로 일관되게 초기화됩니다. Terraform과 결합된 cloud-init을 사용하면 버전 제어 스크립트가 자동으로 적용되므로 수동 사후 프로비저닝 작업이 필요하지 않습니다.

작업자 노드의 주요 이점:

7. 애드온을 사용하여 OKE 기능 향상

OKE 애드온은 가관측성, 확장성, 보안 및 트래픽 관리를 위해 클러스터 기능을 확장합니다. Terraform을 사용하면 워크로드 요구 사항에 따라 애드온을 선택적으로 활성화 또는 비활성화하고 리소스 사용을 최소화할 수 있습니다.

kubernetes_dashboard_enabled       = false
metrics_server_enabled             = false
cluster_autoscaler_enabled         = false
certificate_manager_enabled        = false
istio_enabled                      = false
native_ingress_controller_enabled  = false

일반적인 부가 기능 및 혜택:

부가 기능 모범 사례:

8. 외부 리소스가 k8s 클러스터에 액세스해야 하는 경우 OIDC 인증/검색을 사용합니다.

OCI 외부의 개발자 또는 자동화 툴이 Kubernetes 클러스터에 대해 인증해야 하는 경우 OIDC 검색을 외부 ID 제공자(예: Okta 또는 Azure AD)와 통합합니다. 이를 통해 로컬 Kubernetes 사용자를 관리하거나 kubeconfig 파일을 배포할 필요 없이 중앙 집중식 ID 관리 및 통합 액세스를 수행할 수 있습니다. 이 접근 방식은 특히 GitHub 작업과 같은 외부 CI/CD 도구가 클러스터에 액세스해야 하거나 클러스터 내의 작업 부하가 HashiCorp 저장소와 같은 외부 서비스와 안전하게 통합되어야 하는 경우에 유용합니다. 조직은 OIDC에 의존하여 일관된 인증 정책을 시행하고, 액세스 관리를 단순화하며, 강력한 보안 경계를 유지하면서 자격 증명 순환의 운영 오버헤드를 줄일 수 있습니다.

9. 보안 목록 대신 네트워크 보안 그룹 사용

OKE 클러스터를 보안할 때는 기존 보안 목록보다 NSG(네트워크 보안 그룹)가 선호됩니다. NSG를 사용하면 작업자 노드, 로드 밸런서 또는 POD와 같은 특정 리소스에 직접 연결할 수 있는 보다 세분화되고 유연하며 재사용 가능한 보안 규칙을 사용할 수 있습니다. 따라서 리소스가 자주 확장되거나 변경되는 동적 Kubernetes 환경에 더 적합합니다. 반면, 보안 목록은 서브넷 레벨에서 적용되며 전체 VCN 또는 서브넷을 포함하도록 설계되어 세분화된 애플리케이션 보안 요구 사항을 구현할 때 제어 권한을 줄입니다. NSG를 사용하면 보안 위생을 개선하고 규칙 관리를 간소화하며 클러스터 구성요소 간 격리를 더욱 강화할 수 있습니다.

10. OCI Logging Analytics 및 OKE 측정항목으로 관찰 가능

OKE를 OCI Logging Analytics 및 Monitoring과 통합하여 클러스터 및 워크로드 성능에 대한 심층적인 가시성을 확보할 수 있습니다. Logging Analytics는 고급 로그 집계, 구문 분석 및 이상 감지를 제공하며 Monitoring은 Kubernetes 제어 플레인 및 작업자 노드에서 측정항목을 수집합니다. 이러한 서비스를 통해 팀은 추세를 시각화하고 문제를 더 빠르게 해결하며 사전 예방적 관리를 위한 경고를 구성할 수 있습니다. 이 솔루션은 특히 다른 OCI 서비스와 원활하게 통합하면서 로그 수집, 스토리지 및 분석의 복잡성을 추상화하는 OCI 전용 관찰 가능성 플랫폼을 찾는 고객에게 적합합니다.

11. Pod가 OCI 리소스에 액세스해야 하는 경우 작업 로드 ID를 사용합니다.

OCI 인증 시 API 키가 일반적으로 사용되지만 이러한 자격 증명은 수명이 길고 영구 스토리지가 필요하므로 대규모로 안전하게 관리하기가 어렵습니다. 인스턴스 및 리소스 주체는 컴퓨트 인스턴스 또는 서비스가 자신의 ID를 가정할 수 있도록 허용함으로써 이를 개선하는 반면, OKE 워크로드 ID는 개별 Kubernetes POD가 자신의 OCI ID를 가정할 수 있도록 함으로써 이 개념을 더욱 확장합니다. Pod는 OCI 워크로드 ID를 사용으로 설정하여 인증서를 하드 코딩하거나 노드 레벨 권한에 의존하지 않고도 IAM 정책을 사용하여 오브젝트 스토리지 또는 로깅과 같은 OCI 서비스에 안전하게 액세스할 수 있습니다. 이는 프로덕션급 다중 테넌트 Kubernetes 환경에 필수적인 세분화되고 감사 가능한 보안 액세스 제어를 제공합니다.

12. OKE 노드 및 POD에 적합한 서브넷 크기를 사용합니다.

각 노드에는 POD에 대한 기본 IP 및 추가 보조 IP가 필요하므로 서브넷 CIDR 블록을 올바르게 계획하는 것이 가장 좋습니다. 작은 서브넷은 신속하게 IP를 소진하여 확장 또는 업그레이드를 방지할 수 있습니다. 이는 클러스터 안정성을 유지 관리하고 성장을 뒷받침하는 데 중요합니다. 고객은 클러스터가 예측 가능한 확장성을 보장하고, 운영 중단을 방지하며, 네트워크 재설계 없이 미래의 워크로드를 지원함으로써 이점을 누릴 수 있습니다. 운용 환경의 경우 더 큰 CIDR 블록을 할당하고 OKE 서브넷 크기 조정 안내서를 참조하여 VCN이 현재 및 미래의 작업 로드 요구를 지원할 수 있도록 합니다.

13. 전체 스택 재해 복구 서비스를 사용하여 k8s 클러스터 백업

OKE 클러스터에 OCI Full Stack Disaster Recovery를 활용하는 것이 가장 좋은 방법은 여러 지역에 걸쳐 조정된 페일오버 및 페일백을 통해 클러스터 구성, 애플리케이션, 네트워킹을 보호하는 것입니다. 이는 지역별 정전 또는 시스템 장애 시 비즈니스 연속성 및 규정 준수에 중요합니다. 고객은 다운타임 감소, 신속한 복구, 재해 발생 시에도 미션 크리티컬 워크로드가 계속 운영되고 있다는 확신을 얻을 수 있습니다.

자세한 내용은 OCI Full Stack Disaster Recovery를 통한 OCI Kubernetes Engine(Stateful)용 스위치오버 및 페일오버 계획 자동화를 참고하세요.

다음 단계:

Terraform을 사용하면 OKE 프로비저닝을 일관되고 자동화되며 확장할 수 있습니다. OCI 태깅, 서브넷 분리 및 표준화된 노드 구성과 같은 모범 사례를 따르면 클러스터는 안전하고 체계적이며 비용 투명하게 유지됩니다. 다음 블로그에서는 AI 기반 운영을 살펴보고, Oracle AIOps을 통합하고, AI 기반 관찰을 지원하고, AI 워크로드를 위한 엔드투엔드 OKE 청사진을 생성하는 방법을 소개하기 위한 토대를 마련하겠습니다. 최신 LiveLabs 세션에 대한 최신 정보를 확인해 보세요. 이 세션에서는 이러한 기술을 실습하고 라이브 환경에서 OKE 배포를 실험해 볼 수 있습니다.

승인

추가 학습 자원

docs.oracle.com/learn에서 다른 랩을 탐색하거나 Oracle Learning YouTube 채널에서 더 많은 무료 학습 콘텐츠에 액세스하세요. 또한 education.oracle.com/learning-explorer를 방문하여 Oracle Learning Explorer가 되십시오.

제품 설명서는 Oracle Help Center를 참조하십시오.