AI

EKS 최적화 보고서(CloudOpsOne) 추가 기능 개발 - 노드 / 네트워크 편

Hanhorang31 2026. 3. 25. 21:43

개요

이전 글에서 소개한 EKS 최적화 보고서에 노드 모니터링 & 네트워크 최적화 항목을 추가하겠습니다.

네트워크 최적화 항목은 가시다님이 진행하는 AEWS4기 스터디 내용을 참고하였습니다.

 

자세한 소스 코드는 필자의 GitHub Repo(CloudOpsOne-EKS)에 공개되어 있습니다.

웹페이지에서 버튼 클릭만으로 생성된 보고서를 확인해 보세요.

 

버그 또는 추가하고 싶은 내용들은 댓글로 남겨주세요~

보고서 품질 향상에 도움이 됩니다

 

 

[변경 참고 사항] Strands Agents & MCP 서버 설계

바이브코딩으로 개발한 보고서 코드에 추가 기능을 넣어야 합니다.

 

바이브코딩의 단점 중 하나 변경이 어렵다는 것인데요.

Strands Agents와 MCP 서버에서 무엇을 변경해야 하는 지 소개하겠습니다.

현재 프로젝트 호출 구조는 다음과 같이 구별됩니다.

 

  • Strands Agents 영역 : AI 에이전트가 사용자 요청을 받아 적절한 툴을 선택하고 호출하는 영역
  • MCP 영역 : 툴 요청을 받아 실제 비즈니스 로직을 실행하고 AWS 서비스와 통신하는 영역

 

1. Strand Agents 영역

AI 에이전트가 사용자 요청을 받아 적절한 툴을 선택할 수 있도록 프롬프트만 수정하면 됩니다.

Strands Agents 은 복잡한 오케스트레이션 로직 없이 모델, 프롬프트, 도구만 정의만 하면 됩니다.

모델은 그대로 유지되며, 도구는 아래 MCP 영역에서 구성되기에 프롬프트만 추가합시다!

이해를 돕기 위해 아래 날씨 확인 에이전트에서 추가 시나리오가 필요한 경우 유저 프롬프트(Comtents) 만 수정하면 되는 것을 확인할 수 있습니다.

 

시나리오 : “날씨 확인하고 추우면 이메일 보내줘”

from anthropic import Anthropic

client = Anthropic()

# 1. 도구만 정의
tools = [
    {
        "name": "check_weather",
        "description": "현재 날씨를 확인합니다",
        "input_schema": {"type": "object", "properties": {}}
    },
    {
        "name": "send_email",
        "description": "이메일을 보냅니다",
        "input_schema": {
            "type": "object",
            "properties": {
                "content": {"type": "string"}
            }
        }
    }
]

# 2. 에이전트 실행 (Claude가 알아서 판단)
response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    tools=tools,
    messages=[{
        "role": "user",
        "content": "날씨 확인하고 추우면 이메일 보내줘"
    }]
)

# Claude가 자동으로:
# 1. check_weather 호출
# 2. 결과 분석
# 3. 추우면 send_email 호출
# 4. 아니면 종료

 

 

변경 시나리오 : "날씨가 추우면 이메일 보내고, 비가 오면 보내지 말기”

# 자연어로 지시
messages = [{
    "role": "user",
    "content": "날씨 확인해서 추우면 이메일, 비오면 보내지 말아줘"
}]

→ Content(프롬프트) 만 수정하면 됩니다. 추가 기능들은 도구를 통해 정의합시다. 도구는 Strands Agent에서 정의할 수 있고 MCP 서버의 도구를 활용할 수 있습니다. 해당 프로젝트에서는 MCP 서버를 이용하기에 MCP영역에서 도구를 추가하겠습니다.

 

 

2. MCP 영역

MCP 영역은 툴 요청을 받아 실제 비즈니스 로직을 실행하고 AWS 서비스와 통신하는 영역입니다. 비즈니스 로직 실행을 위해 필요한 데이터를 가져와야 하므로, 데이터 파이프라인과 어떤 데이터를 가져올지 구분이 필요합니다. 본 MCP는 비즈니스 로직 또는 기능 단위로 하나의 도구(Tool)에 매핑하여 MCP 서버를 통해 제공합니다.

 

하나의 도구로 매핑하는 이유는 중요합니다. AI가 모든 로직을 직접 처리하면 불필요한 토큰 소모가 발생하지만, 도구 안에 비즈니스 로직을 정의해두면 토큰 낭비를 줄이고, 사용자 정의 로직 기반으로 데이터를 가져오기 때문에 응답의 정확도도 향상시킬 수 있습니다.

기능 추가는 다음과 같습니다.

📁 mcp_server_with_runbooks.py
└─ @server.list_tools() 데코레이터 함수
   └─ tools 리스트에 새 도구 추가
      {
        "name": "eks_cost_analysis",  ◄─── 새 도구 이름
        "description": "...",
        "inputSchema": {...}
      }

└─ @server.call_tool() 데코레이터 함수
   └─ elif name == "eks_cost_analysis":  ◄─── 라우팅 추가
        return await run_eks_cost_analysis(arguments)

📁 playbooks/eks/eks_optimization.py
└─ async def run_eks_cost_analysis(arguments):  ◄─── 새 함수 구현
     ...

 

 

추가 기능 개발 (노드 모니터링)

파드 모니터링에 이어 노드 모니터링도 보고서에 꼭 들어가야할 항목입니다.

노드 CPU/Memory/GPU 사용률을 수집하고 설정한 임계치에 따라 Right Sizing 을 가이드하도록 설계하였습니다.

지표 수집

사전 addon 으로 Amazon CloudWatch Observability 가 필요합니다.

  • _get_node_utilization_metrics : Container Insights를 통해 노드별 CPU/Memory 사용률을 CloudWatch Logs Insights로 쿼리하여 수집합니다.
  • _get_gpu_metrics_from_cloudwatch : GPU는 DCGM Exporter가 수집한 Prometheus 메트릭을 CloudWatch 를 통해 수집합니다.

 

(참고) Amazon CloudWatch Observability addon을 활성화하면 Daemonset으로 각노드에 배포되며 Cloudwatch-Agent를 통해 수집 → cloudwatch 로 조회가 가능합니다.

┌─────────────────────────────────────────┐
│  GPU Node                               │
│                                         │
│  ┌──────────────────────────────────┐   │
│  │ dcgm-exporter (DaemonSet)        │   │
│  │ - Port: 9400                     │   │
│  │ - Endpoint: /metrics             │   │
│  │ - Config: dcp-metrics-included   │   │
│  └──────────────┬───────────────────┘   │
│                 │ Prometheus format     │
│                 │ (DCGM_FI_DEV_*)       │
│  ┌──────────────▼───────────────────┐   │
│  │ cloudwatch-agent (DaemonSet)     │   │
│  │ - Scrapes localhost:9400/metrics │   │
│  │ - Converts to CloudWatch format  │   │
│  │ - Sends to CloudWatch Metrics    │   │
│  └──────────────┬───────────────────┘   │
└─────────────────┼───────────────────────┘
                  │
                  ▼
         ┌────────────────┐
         │  CloudWatch    │
         │  Namespace:    │
         │  ContainerInsights│
         └────────────────┘

kubectl get cm dcgm-exporter-config-map    -n amazon-cloudwatch -o yaml
...

dcp-metrics-included.csv:
----
DCGM_FI_DEV_GPU_UTIL,      gauge, GPU utilization (in %).
DCGM_FI_DEV_MEM_COPY_UTIL, gauge, Memory utilization (in %).
DCGM_FI_DEV_FB_FREE, gauge, Framebuffer memory free (in MiB).
DCGM_FI_DEV_FB_USED, gauge, Framebuffer memory used (in MiB).
DCGM_FI_DEV_FB_TOTAL, gauge, Framebuffer memory used (in MiB).
DCGM_FI_DEV_FB_USED_PERCENT, gauge, Percentage used of Frame Buffer
DCGM_FI_DEV_MEMORY_TEMP, gauge, Memory temperature (in C).
DCGM_FI_DEV_GPU_TEMP,    gauge, GPU temperature (in C).
DCGM_FI_DEV_POWER_USAGE, gauge, Power draw (in W).
DCGM_FI_PROF_PIPE_TENSOR_ACTIVE, gauge, Tensor Core utilization (in %).

(참고) Cloudwatch 수집 로직

# CPU/메모리 지표 수집 로직
async def _get_node_utilization_metrics(region: str, cluster_name: str, instance_id: str, 
                                       lookback_days: int, is_gpu_instance: bool) -> Optional[Dict]:
    """노드 리소스 사용률 메트릭 조회 (Container Insights + CloudWatch Metrics)"""
    
    # 1. CloudWatch Logs Insights 쿼리 (Container Insights 데이터)
    query_string = f"""
    fields @timestamp, node_cpu_utilization, node_memory_utilization, 
           node_cpu_limit, node_memory_limit, node_cpu_usage_total, node_memory_working_set
    | filter Type = "Node" and InstanceId = "{instance_id}"
    | stats avg(node_cpu_utilization) as avg_cpu_util,
            max(node_cpu_utilization) as max_cpu_util,
            avg(node_memory_utilization) as avg_mem_util,
            max(node_memory_utilization) as max_mem_util
    """
    
    # 2. 쿼리 실행 및 결과 대기
    # 3. GPU 인스턴스면 GPU 메트릭 추가 수집
    if is_gpu_instance:
        gpu_metrics = await _get_gpu_metrics_from_cloudwatch(...)
        
..   
..

# GPU 지표 수집
gpu_util_response = cloudwatch.get_metric_statistics(
    Namespace='ContainerInsights/Prometheus',
    MetricName='DCGM_FI_DEV_GPU_UTIL',
    Dimensions=[
        {'Name': 'ClusterName', 'Value': cluster_name},
        {'Name': 'InstanceId', 'Value': instance_id}
    ],
    StartTime=start_time,
    EndTime=end_time,
    Period=3600,  # 1시간 단위
    Statistics=['Average', 'Maximum']
)

임계치는 다음과 같이 구성하였습니다.

메트릭
과다 프로비저닝 (Over-provisioning)
과소 프로비저닝 (Under-provisioning)
경고 (Alert/Critical)
노드 CPU
평균 < 20%
최대 > 80%
-
노드 Memory
평균 < 20%
최대 > 80%
-
GPU 사용률
평균 < 30%
최대 > 90%
-
GPU 온도
-
-
최대 > 80°C

기능 호출 구조는 다음과 같이 진행됩니다.

User Request (Strands Agent)
    │
    ├─ "EKS 클러스터 GPU 사용률 분석해줘"
    │
    ▼
Strands Agent (LLM)
    │
    ├─ Tool 선택: eks_node_optimization
    ├─ 파라미터: {cluster_name: "my-cluster", lookback_days: 7}
    │
    ▼
MCP Client
    │
    ├─ call_tool("eks_node_optimization", {...})
    │
    ▼
MCP Server (stdio)
    │
    ├─ 도구 이름 매칭
    ├─ Playbook 함수 호출
    │
    ▼
Playbook (eks_optimization.py)
    │
    ├─ run_eks_node_optimization(arguments)
    ├─ EKSResourceIdentifier로 인스턴스 조회
    ├─ CloudWatch API로 GPU 메트릭 수집
    ├─ 분석 및 권장사항 생성
    │
    ▼
Return JSON Result
    │
    ├─ {status: "success", nodes: [...], recommendations: [...]}
    │
    ▼
Strands Agent (LLM)
    │
    ├─ JSON 결과 해석
    ├─ HTML 리포트 생성
    │
    ▼
User (HTML Report)

 

 

결과 확인

 

추가 기능 개발 (네트워크 최적화)

EKS 네트워크 최적화로 기능 추가한 함수는 총 4개입니다.

CoreDNS & East-West 최적화 항목은 devfloor9 님의 EKS 플레이북을 네트워크 설정 관련 최적화 내용은 가시다님의 AEWS4기 내용을 참고하였습니다.

  • CoreDNS 최적화
  • East-West 트래픽 최적화
  • Load Balancer 최적화
  • VPC CNI 설정 최적화

 

 

Kubectl 모듈 추가 구성

쿠버네티스 내부 자원 현황을 파악하기 위해 kubectl 모듈을 MCP서버에 구성하여 클러스터 정보를 얻도록 합니다.

다만, kubectl을 AI에게 도구로 제공하는 것은 수정 위험이 있어 권한 제한이 필요합니다.

kubectl 모듈에서는 클래스화이트리스트를 통해 조회 권한만 실행되고, 나머지 명령어는 실행되지 않도록 구성하여 원지 않은 동작을 하지 않도록 설계했습니다.

# 클래스 
class KubectlHelper:
    """kubectl 명령어 실행 및 데이터 파싱 (읽기 전용)"""
    
    # 허용된 읽기 전용 kubectl 명령어 화이트리스트
    ALLOWED_COMMANDS = {
        'get',      # 리소스 조회
        'describe', # 리소스 상세 정보
        'top',      # 리소스 사용량 (metrics-server 필요)
    }
    
    # 허용된 리소스 타입 화이트리스트
    ALLOWED_RESOURCES = {
        'pods', 'pod',
        'nodes', 'node',
        'services', 'service', 'svc',
        'ingresses', 'ingress', 'ing',
        'deployments', 'deployment', 'deploy',
        'daemonsets', 'daemonset', 'ds',
        'statefulsets', 'statefulset', 'sts',
        'configmaps', 'configmap', 'cm',
        'secrets', 'secret',
        'namespaces', 'namespace', 'ns',
        'persistentvolumeclaims', 'persistentvolumeclaim', 'pvc',
        'persistentvolumes', 'persistentvolume', 'pv',
        'storageclasses', 'storageclass', 'sc',
        'endpoints', 'endpoint', 'ep',
        'events', 'event',
        'replicasets', 'replicaset', 'rs',
        'jobs', 'job',
        'cronjobs', 'cronjob', 'cj',
        'networkpolicies', 'networkpolicy', 'netpol',
        'serviceaccounts', 'serviceaccount', 'sa',
        'roles', 'role',
        'rolebindings', 'rolebinding',
        'clusterroles', 'clusterrole',
        'clusterrolebindings', 'clusterrolebinding',
    }
    
    # 금지된 위험한 명령어 (명시적 블랙리스트)
    FORBIDDEN_COMMANDS = {
        'apply', 'create', 'delete', 'edit', 'patch', 'replace',
        'set', 'scale', 'autoscale', 'rollout', 'label', 'annotate',
        'taint', 'drain', 'cordon', 'uncordon', 'exec', 'attach',
        'port-forward', 'proxy', 'cp', 'run', 'expose', 'debug'
    }
    

from playbooks.eks.kubectl_helper import KubectlHelper

# 초기화 (자동으로 kubeconfig 설정)
kubectl = KubectlHelper('my-cluster', 'ap-northeast-2')

# ✅ 허용: Pod 조회
pods = kubectl.get_pods()
print(f"Total pods: {len(pods)}")

# ✅ 허용: 노드 조회
nodes = kubectl.get_nodes()
print(f"Total nodes: {len(nodes)}")

# ✅ 허용: VPC CNI 설정 조회
vpc_cni = kubectl.get_vpc_cni_config()
print(f"Prefix Delegation: {vpc_cni['prefix_delegation_enabled']}")

# ❌ 차단: Pod 삭제 시도
# kubectl._run_kubectl(['delete', 'pod', 'my-pod'])
# Security Error: Command 'delete' is forbidden (write operation)

# 보안 테스트 실행
test_results = kubectl.test_security()
print(f"Security tests: {test_results['passed']}/{test_results['total_tests']} passed")

 

 

 

CoreDNS 최적화

최적화 항목은 devfloor9 님의 CoreDNS 최적화 모니터링 가이드를 참고하였습니다.

 

CoreDNS는 클러스터 내 모든 서비스 디스커버리와 외부 도메인 이름 해석을 담당하는 핵심 addon입니다. CoreDNS의 성능과 가용성은 애플리케이션 응답 시간과 안정성에 직접적인 영향을 미치기 때문에, 효과적인 모니터링 및 최적화 아키텍처를 구축하는 것이 중요합니다.(가이드 발췌)

 

CoreDNS 지표 수집 방안

CoreDNS 최적화를 위해 지표 수집이 필요합니다.

 

Prometheus 나 Cloudwatch 에서 집계된 데이터를 가지고 분석하면 좋으나, 추가 구성에 대한 오버헤드가 클 것으로 예상됩니다. 이에, CoreDNS 파드에서 출력하는 지표 확인하여 분석하도록을 설계하였습니다.

 

지표 확인은 kubectl 모듈을 통해 확인합니다.

 

 

CoreDNS 파드 공고 지표 리스트

- dns_requests_total: 총 DNS 요청 수
- dns_responses_total: DNS 응답 수
- dns_request_duration_seconds: 요청 처리 시간
- cache_hits_total: 캐시 히트 수
- cache_misses_total: 캐시 미스 수
- forward_requests_total: 포워딩된 요청 수
- panic_count_total: 패닉 발생 횟수
- cache_hit_rate: 캐시 히트율 (계산)
- avg_request_duration_ms: 평균 요청 처리 시간 (ms)

MCP 서버를 통해 수집되는 정보

# MCP 서버에서 호출
result = await run_eks_network_optimization({
    'region': 'ap-northeast-2',
    'cluster_name': 'my-cluster'
})

# 결과에 포함되는 정보
{
    "coredns_optimization": {
        "pod_count": 2,
        "actual_pod_names": ["coredns-abc123", "coredns-def456"],
        "realtime_metrics": [
            {
                "pod_name": "coredns-abc123",
                "status": "success",
                "dns_requests_total": 15234,
                "cache_hit_rate": 78.5,
                "avg_request_duration_ms": 2.3
            }
        ],
        "realtime_summary": {
            "total_pods": 2,
            "pods_with_metrics": 2,
            "aggregate_metrics": {
                "total_dns_requests": 30468,
                "overall_cache_hit_rate": 79.2,
                "avg_request_duration_ms": 2.1
            }
        }
    }
}

 

 

결과 확인

 

 

East-West 트래픽 분석

Amazon EKS 기반의 내부 서비스 간 통신(East-West 트래픽) 지연(latency) 최소화와 비용 효율화를 분석하여 제공하는 기능을 추가하겠습니다.

  • Pod 간 East-West 트래픽 사용량 분석
  • Cross-AZ 트래픽 비용 및 전송량 분석
  • 아키텍처별 비용 구조 비교 (ClusterIP / ALB / Lattice)
  • Cross-AZ 트래픽 비용을 줄이기 위한 가이드 안내

 

지표 수집

Cross-AZ 비용 모니터링을 통해 리포트에 UsageType 비용을 가져오고, 주어진 가이드를 제공합니다.

# AWS Cost and Usage Report에서 Regional Data Transfer 비용 확인
aws ce get-cost-and-usage \
  --time-period Start=2026-02-01,End=2026-02-28 \
  --granularity MONTHLY \
  --metrics "BlendedCost" \
  --filter '{"Dimensions":{"Key":"USAGE_TYPE","Values":["APN2-DataTransfer-Regional-Bytes"]}}'

또한, AZ 간 트래픽을 유발하는 특정 포드 간 연결을 식별하기 위해 VPC Flow log를 활성화합니다.

VPC Flow Log가 활성화되지 않은 경우 실제 통신 비용을 기반으로 추정하여 보고서를 작성합니다.

VPC Flow log를 활성화 방법은 보고서에 안내되어 있습니다.

 

 

 

1. 흐름 로그용 IAM 역할 생성

# Create trust policy
cat > flow-logs-trust-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "vpc-flow-logs.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

# Create IAM role
aws iam create-role \
  --role-name VPCFlowLogsRole \
  --assume-role-policy-document file://flow-logs-trust-policy.json

# Attach policy
aws iam attach-role-policy \
  --role-name VPCFlowLogsRole \
  --policy-arn arn:aws:iam::aws:policy/CloudWatchLogsFullAccess

 

2. CloudWatch 로그 그룹 생성

# Create log group
aws logs create-log-group \
  --log-group-name /aws/vpc/flowlogs/myeks \
  --region ap-northeast-2

# Set retention (7 days recommended to control costs)
aws logs put-retention-policy \
  --log-group-name /aws/vpc/flowlogs/myeks \
  --retention-in-days 7 \
  --region ap-northeast-2

3. VPC 흐름 로그 활성화

# Get VPC ID from EKS cluster
VPC_ID=$(aws eks describe-cluster \
  --name myeks \
  --region ap-northeast-2 \
  --query 'cluster.resourcesVpcConfig.vpcId' \
  --output text)

echo "VPC ID: $VPC_ID" 

# Get IAM Role ARN
ROLE_ARN=$(aws iam get-role \
  --role-name VPCFlowLogsRole \
  --query 'Role.Arn' \
  --output text)

# Create Flow Logs
aws ec2 create-flow-logs \
  --resource-type VPC \
  --resource-ids $VPC_ID \
  --traffic-type ALL \
  --log-destination-type cloud-watch-logs \
  --log-group-name /aws/vpc/flowlogs/myeks \
  --deliver-logs-permission-arn $ROLE_ARN \
  --region ap-northeast-2

# Verify Flow Logs are active
aws ec2 describe-flow-logs \
  --filter "Name=resource-id,Values=$VPC_ID" \
  --region ap-northeast-2

 

VPC Flow log 쿼리를 통해 Cross AZ간의 비용을 산정합니다.

# Step 2: VPC Flow Logs 쿼리 (srcaddr, dstaddr, bytes)
query_string = """
fields @timestamp, srcaddr, dstaddr, bytes, action
| filter action = "ACCEPT"
| filter srcaddr like /^10\\./
| filter dstaddr like /^10\\./
| stats sum(bytes) as total_bytes by srcaddr, dstaddr
| limit 5000
"""

# 예시 
# VPC Flow Logs 레코드 분석
srcaddr: 10.0.1.10 (AZ-a) → dstaddr: 10.0.2.20 (AZ-b) = Cross-AZ! ✅
srcaddr: 10.0.1.10 (AZ-a) → dstaddr: 10.0.1.30 (AZ-a) = Same-AZ ✅

결과 예시

{
  "status": "success",
  "cross_az_gb": 45.23,              // 실제 Cross-AZ 트래픽
  "total_traffic_gb": 150.50,
  "same_az_gb": 95.27,
  "cross_az_percentage": 30.05,      // 실제 비율
  "top_cross_az_connections": [
    {
      "srcaddr": "10.0.1.10",
      "dstaddr": "10.0.2.20",
      "src_az": "ap-northeast-2a",
      "dst_az": "ap-northeast-2b",
      "gb": 12.5
    }
  ],
  "estimation_method": "vpc_flow_logs_actual"  
}

 

결과 확인

 

VPC CNI 최적화

VPC CNI 설정 값과 노드별 IP 할당 개수를 식별하여 추천 옵션 값을 제공합니다.

파라미터는 공식 깃허브가이드를 참고하였습니다.

  • IP Allocation Mode (ENABLE_PREFIX_DELEGATION, ENABLE_IPv4, ENABLE_IPv6)
  • IP Warm Pool (WARM_ENI_TARGET, WARM_IP_TARGET, WARM_PREFIX_TARGET, MINIMUM_IP_TARGET, MAX_ENI)
  • Custom Networking (AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG, ENI_CONFIG_ANNOTATION_DEF, ENI_CONFIG_LABEL_DEF)
  • Pod ENI (ENABLE_POD_ENI, POD_SECURITY_GROUP_ENFORCING_MODE)
  • IPv6, Network Policy, Performance, IPAMD, Security settings

 

 

kubectl 모듈을 통해 VPC CNI 옵션 수집하는 형태는 다음과 같습니다.

# get_vpc_cni_config() 메서드 반환값
{
    "image": "602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon-k8s-cni:v1.18.0",
    "env_vars": {
        "ENABLE_PREFIX_DELEGATION": "true",
        "WARM_ENI_TARGET": "1",
        "WARM_IP_TARGET": "5",
        "WARM_PREFIX_TARGET": "1",
        "MINIMUM_IP_TARGET": "10",
        "AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG": "false",
        "ENABLE_POD_ENI": "false"
    },
    "prefix_delegation_enabled": True,  # 파싱된 boolean
    "warm_eni_target": "1",
    "warm_ip_target": "5",
    "warm_prefix_target": "1",
    "minimum_ip_target": "10"
}

 

결과 확인

 

오픈소스

위 리포트는 필자의 깃허브 Repo(CloudOpsOne-EKS)에 해당 프로젝트에서 확인할 수 있습니다.

git clone https://github.com/HanHoRang31/CloudOpsOne-EKS

# 1. Install dependencies
pip install flask boto3 strands-agents mcp flask-cors

# 2. Configure AWS credentials
aws configure --profile my-profile

# 3. Start the web server
python eks_web_app.py

# 4. Open browser
curl  http://localhost:5001

 

기능

1. Network Optimization Report

 

분석 항목

  • CoreDNS 최적화 (리소스 사용률, 캐시 히트율)
  • East-West 트래픽 분석 (Cross-AZ 비용)
  • Pod IP/ENI 최적화 (Prefix Delegation)
  • Load Balancer 최적화 (Idle LB 식별)
  • VPC CNI 설정 최적화

필요 데이터

  • kubectl 접근 (필수)
  • Container Insights (권장 - 메트릭용)
  • VPC Flow Logs (선택 - 정확한 Cross-AZ 측정)

생성 시간 : 약 5-10분

 

2. Full EKS Optimization Report

 

분석 항목

  • Cluster Inventory (현재 상태)
  • Version & EOS Warnings
  • Pod Right-Sizing (지난 7일 메트릭)
  • Node Optimization (인스턴스 타입, 사용률)
  • Storage Optimization (EBS, PVC)
  • Network Optimization (전체)
  • Cost Optimization Summary

필요 데이터

  • kubectl 접근 (필수)
  • Container Insights (필수 - Pod/Node 메트릭용)
  • VPC Flow Logs (선택)

생성 시간: 약 10-20분

 

 

최소 권한 원칙

본 프로젝트는 AWS IAM 읽기 권한과 kubectl 조회 및 포트포워딩 권한만 가지고 수행됩니다.

  • 읽기 전용 액세스: 모든 작업은 읽기 전용이며, 생성, 업데이트 또는 삭제 권한이 없습니다.
  • 리소스 수정 불가: 이 도구는 AWS 리소스를 수정, 종료 또는 생성할 수 없습니다.
  • 감사 추적 : 모든 API 호출은 보안 모니터링을 위해 CloudTrail에 기록됩니다.
  • kubectl 제어 : kubectl 명령어 중 조회(get, top, describe, 포트포워딩) 목적으로만 수행됩니다.

 

실행 방법

# 3. Start the web server
python eks_web_app.py

 http://localhost:5001 를 통해 접속해주세요.

 

웹 인터페이스 사용

  1. AWS Authentication 설정
  2. EKS Cluster 선택
  3. Report Type 선택
  4. 리포트 생성
  • 약 5~10분정도 소요됩니다. 40%에서 오래 유지되므로 서버 로깅을 통해 진행 상황을 확인하는 것이 좋습니다.

 

Report 다운로드 후 HTML 파일을 확인하면 보고서를 확인할 수 있습니다.

버그 또는 추가하고 싶은 내용들은 댓글로 남겨주세요~ 보고서 품질 향상에 도움이 됩니다

 

 

참고

Strands Server

CFM-tip MCP server

devfloor9 님 기술 블로그

CloudNet@ AEWS4기