-
Notifications
You must be signed in to change notification settings - Fork 0
/
optimize.py
103 lines (86 loc) · 3.82 KB
/
optimize.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import os
from kubernetes import client, config
def load_kubernetes_config():
"""Load the appropriate Kubernetes configuration."""
if os.path.exists("/var/run/secrets/kubernetes.io/serviceaccount/token"):
# Running inside a Kubernetes pod
config.load_incluster_config()
else:
# Running locally (e.g., for testing)
config.load_kube_config()
def collect_cluster_data():
"""Fetch node and pod data from the Kubernetes cluster."""
load_kubernetes_config()
v1 = client.CoreV1Api()
# Collect node data
nodes = []
node_list = v1.list_node()
for node in node_list.items:
allocatable = node.status.allocatable
nodes.append({
"name": node.metadata.name,
"cpu": allocatable["cpu"],
"memory": allocatable["memory"]
})
# Collect pod data
pods = []
pod_list = v1.list_pod_for_all_namespaces()
for pod in pod_list.items:
if pod.status.phase == "Running":
for container in pod.spec.containers:
requests = container.resources.requests or {}
pods.append({
"node": pod.spec.node_name,
"cpu": parse_resource(requests.get("cpu", "50m")), # Default fallback
"memory": parse_resource(requests.get("memory", "64Mi")) # Default fallback
})
print("Nodes:", nodes)
print("Pods:", pods)
return nodes, pods
def optimize_pod_resources(nodes, existing_pods, default_pod_requests):
"""Optimizes resource requests for new pods based on cluster resources."""
# Calculate remaining resources per node
for node in nodes:
cpu_used = sum(pod['cpu'] for pod in existing_pods if pod['node'] == node['name'])
memory_used = sum(pod['memory'] for pod in existing_pods if pod['node'] == node['name'])
node['remaining_cpu'] = parse_resource(node['cpu']) - cpu_used
node['remaining_memory'] = parse_resource(node['memory']) - memory_used
# Allocate resources for new pods
optimized_pod_requests = []
for node in nodes:
remaining_cpu = node['remaining_cpu']
remaining_memory = node['remaining_memory']
pods_per_node_cpu = remaining_cpu // default_pod_requests['cpu']
pods_per_node_memory = remaining_memory // default_pod_requests['memory']
num_pods = min(pods_per_node_cpu, pods_per_node_memory)
for _ in range(num_pods):
optimized_pod_requests.append({
"node": node['name'],
"cpu": default_pod_requests['cpu'],
"memory": default_pod_requests['memory']
})
return optimized_pod_requests
def parse_resource(resource_str):
"""Converts Kubernetes resource strings to integer values."""
if resource_str.endswith('m'): # CPU in millicores
return int(resource_str[:-1])
elif resource_str.endswith('Ki'): # Memory in Kibibytes
return int(resource_str[:-2]) * 1024
elif resource_str.endswith('Mi'): # Memory in Mebibytes
return int(resource_str[:-2]) * 1024 * 1024
elif resource_str.endswith('Gi'): # Memory in Gibibytes
return int(resource_str[:-2]) * 1024 * 1024 * 1024
else:
return int(resource_str)
def main():
# Step 1: Collect data from the cluster
nodes, existing_pods = collect_cluster_data()
print("Collected Node Data:", nodes)
print("Collected Pod Data:", existing_pods)
# Step 2: Define default pod resource requests for optimization
default_pod_requests = {"cpu": 50, "memory": 64 * 1024 * 1024}
# Step 3: Optimize resource allocation
optimized_requests = optimize_pod_resources(nodes, existing_pods, default_pod_requests)
print("Optimized Pod Resource Requests:", optimized_requests)
if __name__ == "__main__":
main()