Skip to content

Commit e7ea3e8

Browse files
kubectl metrics plugin update
Fixes: #1414
1 parent b702da8 commit e7ea3e8

File tree

10 files changed

+28
-311
lines changed

10 files changed

+28
-311
lines changed

.github/workflows/pr-minikube.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ jobs:
112112
kubectl describe resourcecomposition wordpress-service-composition
113113
until kubectl get pods -n wp-tenant1 | grep -e Running -e Pending; do kubectl describe pods -n wp-tenant1; echo "Waiting for Application Pods to start.."; sleep 1; done
114114
kubectl appresources WordpressService wp-tenant1 –k kubeplus-saas-provider.json
115-
kubectl metrics WordpressService wp-tenant1 $KUBEPLUS_NS -k kubeplus-saas-provider.json
115+
kubectl metrics WordpressService wp-tenant1 -k kubeplus-saas-provider.json
116116
kubectl delete wordpressservice wp-tenant1 --kubeconfig=kubeplus-saas-provider.json
117117
kubectl delete resourcecomposition wordpress-service-composition --kubeconfig=kubeplus-saas-provider.json
118118
echo "Running tests..starting in 5 seconds"

.github/workflows/pr.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ jobs:
141141
- name: Interact with Deployed Application
142142
run: |
143143
kubectl appresources WordpressService wp-tenant1 –k kubeplus-saas-provider.json
144-
kubectl metrics WordpressService wp-tenant1 $KUBEPLUS_NS -k kubeplus-saas-provider.json
144+
kubectl metrics WordpressService wp-tenant1 -k kubeplus-saas-provider.json
145145
146146
- name: Cleanup Deployed Resources
147147
run: |

examples/getting-started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ wp-tenant1 ResourceQuota wordpressservice-wp-tenant1
7878
### 7. Check Application Resource Consumption
7979

8080
```sh
81-
kubectl metrics WordpressService wp-tenant1 $KUBEPLUS_NS -k kubeplus-saas-provider.json
81+
kubectl metrics WordpressService wp-tenant1 -k kubeplus-saas-provider.json
8282

8383
----------------------------------------------------------
8484
Kubernetes Resources created:

examples/multitenancy/application-hosting/odoo/steps.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ This example shows delivering Bitnami Odoo Helm chart as-a-service using KubePlu
8282
- Navigate to $appurl/web/login in the browser and login using ODOO_EMAIL and ODOO_PASSWORD
8383

8484
13. Check metrics:
85-
$ kubectl metrics OdooService sample-odooservice default -k kubeplus-saas-provider.json
86-
$ kubectl metrics OdooService sample-odooservice default -k kubeplus-saas-provider.json -o prometheus
85+
$ kubectl metrics OdooService sample-odooservice -k kubeplus-saas-provider.json
86+
$ kubectl metrics OdooService sample-odooservice -k kubeplus-saas-provider.json -o prometheus
8787

8888
14. Check resource topology:
8989
$ kubectl connections OdooService sample-odooservice default -k kubeplus-saas-provider.json

examples/multitenancy/application-hosting/wordpress/steps.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ $ kubectl kubeplus commands
7979
- should see logs for all the containers in both the Pods
8080

8181
14. Get metrics:
82-
$ kubectl metrics WordpressService wp-tenant1 $KUBEPLUS_NS -k kubeplus-saas-provider.json
82+
$ kubectl metrics WordpressService wp-tenant1 -k kubeplus-saas-provider.json
8383

8484
15. Visualize topology:
8585
$ kubectl connections WordpressService wp-tenant1 $KUBEPLUS_NS -o png -k kubeplus-saas-provider.json

examples/multitenancy/hello-world/saas-and-managed-app-testing.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Multi-namespace setup
6565
- Should see app logs
6666
21. kubectl connections HelloWorldService hs1 default -i Namespace:$KUBEPLUS_NS -k consumer.conf
6767
- Should see created resources' listing
68-
22. kubectl metrics HelloWorldService hs1 default -o prometheus -k consumer.conf
68+
22. kubectl metrics HelloWorldService hs1 -o prometheus -k consumer.conf
6969
- Should see the metrics
7070
23. kubectl delete -f hs1.yaml --kubeconfig=consumer.conf
7171
- kubectl get pods -A
@@ -110,7 +110,7 @@ Single namespace setup
110110
- Should see app logs
111111
20. kubectl connections HelloWorldService hs1 kubeplus -i Namespace:$KUBEPLUS_NS -k provider.conf
112112
- Should see created resources' listing
113-
21. kubectl metrics HelloWorldService hs1 kubeplus -o prometheus -k provider.conf
113+
21. kubectl metrics HelloWorldService hs1 -o prometheus -k provider.conf
114114
- Should see the metrics
115115
22. kubectl delete -f hs1.yaml --kubeconfig=provider.conf
116116
23. kubectl get pods -A

examples/multitenancy/hello-world/steps.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ You can use either the provider.conf or consumer.conf in below commands.
9090
- kubectl applogs HelloWorldService hs1 default -k consumer.conf
9191

9292
7. Retrievel application metrics
93-
- kubectl metrics HelloWorldService hs1 default -k consumer.conf
93+
- kubectl metrics HelloWorldService hs1 -k consumer.conf
9494
- Should see output of the following nature:
9595
----------------------------------------------------------
9696
Kubernetes Resources created:
@@ -113,7 +113,7 @@ You can use either the provider.conf or consumer.conf in below commands.
113113
9. Verify that 2 Pods are created in the hs1 namespace
114114
- kubectl get pods -n hs1
115115
- kubectl appresources HelloWorldService hs1 default -k consumer.conf
116-
- kubectl metrics HelloWorldService hs1 default -k consumer.conf
116+
- kubectl metrics HelloWorldService hs1 -k consumer.conf
117117

118118

119119
Clean up:

examples/multitenancy/platform-engineering/steps.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ Product team
8585
$ kubectl applogs CustomMysqlService prod-mysql default -k consumer.conf
8686

8787
7. Check metrics:
88-
$ kubectl metrics CustomMysqlService prod-mysql default -k consumer.conf
89-
$ kubectl metrics CustomMysqlService prod-mysql default -k consumer.conf -o prometheus
88+
$ kubectl metrics CustomMysqlService prod-mysql -k consumer.conf
89+
$ kubectl metrics CustomMysqlService prod-mysql -k consumer.conf -o prometheus
9090

9191

9292
Clean up:

plugins/crmetrics.py

Lines changed: 11 additions & 262 deletions
Original file line numberDiff line numberDiff line change
@@ -759,65 +759,6 @@ def _parse_pods_from_connections_op(self, output):
759759
pod_list.append(pod)
760760
return pod_list
761761

762-
def _get_pods_for_helmrelease_2(self, release_name):
763-
cmd = "helm get " + release_name
764-
try:
765-
output = subprocess.Popen(cmd,
766-
stdout=subprocess.PIPE,
767-
stderr=subprocess.PIPE,
768-
shell=True).communicate()[0]
769-
output = output.decode('utf-8')
770-
output = output.strip("\n")
771-
except Exception as e:
772-
print(e)
773-
774-
pod_list_to_return = []
775-
776-
output1 = output.decode("utf-8")
777-
#print(output1)
778-
processed_output = []
779-
start = False
780-
for line in output1.split("\n"):
781-
if not start and line == "---":
782-
start = True
783-
if start:
784-
processed_output.append(line)
785-
processed_output.append("\n")
786-
787-
#print("CBC")
788-
#print(processed_output)
789-
yamls = ''.join(processed_output)
790-
#print("DEF")
791-
#print(yamls)
792-
yamls_bytes = yamls.encode()
793-
#print("EFG")
794-
#print(yamls_bytes)
795-
796-
for project in yaml.load_all(yamls_bytes):
797-
#pprint.pprint(project)
798-
if project != None:
799-
kind = project['kind']
800-
name = ''
801-
namespace = 'default'
802-
if 'metadata' in project:
803-
if 'name' in project['metadata']:
804-
name = project['metadata']['name']
805-
if 'namespace' in project['metadata']:
806-
name = project['metadata']['namespace']
807-
808-
if kind not in ['ConfigMap', 'CustomResourceDefinition', 'ClusterRole', 'ClusterRoleBinding']:
809-
if kind != '' and name != '' and namespace != '':
810-
#print("Kind:"+ kind + " Namespace:" + namespace + " Instance:" + instance)
811-
composition = self._get_composition(kind, name, namespace)
812-
pod_list = self._parse_number_of_pods(composition)
813-
if pod_list:
814-
#print(pod_list)
815-
for p in pod_list:
816-
pod = {}
817-
pod['Name'] = p['Name']
818-
pod['Namespace'] = p['Namespace']
819-
pod_list_to_return.append(pod)
820-
return pod_list_to_return
821762

822763
def _get_pods_for_helmrelease(self, release_name):
823764
cmd = "helm get manifest " + release_name
@@ -1053,82 +994,15 @@ def _get_metrics_creator_account_with_connections(self, account):
1053994
print(" Total Storage(bytes): " + str(storage) + "Gi")
1054995
print("---------------------------------------------------------- ")
1055996

1056-
def get_metrics_creator_account(self, account):
1057-
# 1. Get all custom resource instances - their count
1058-
all_cpu = 0
1059-
all_mem = 0
1060-
1061-
print("---------------------------------------------------------- ")
1062-
print(" Creator Account Identity: " + account)
1063-
print("---------------------------------------------------------- ")
1064-
1065-
print("Checking Custom Resources..")
1066-
cr_cpu, cr_mem, cr_count = self._get_metrics_cr_instances(account)
1067-
1068-
# 2. Get all deployments
1069-
print("Checking Deployments..")
1070-
dep_cpu, dep_mem, dep_count = self._get_metrics_deployments(account)
1071-
1072-
# 3. Get all statefulsets
1073-
print("Checking StatefulSets..")
1074-
ssets_cpu, ssets_mem, ss_count = self._get_metrics_statefulsets(account)
1075-
1076-
# 4. Get all replicasets -
1077-
# Replicasets seem to carry over annotations from deployment.
1078-
# So we will ignore the memory and cpu of deployments from final totals.
1079-
# To correctly count replicasets we will subtract dep_count from rsets_count
1080-
print("Checking ReplicaSets..")
1081-
rsets_cpu, rsets_mem, rsets_count = self._get_metrics_replicasets(account)
1082-
rsets_count = rsets_count - dep_count
1083-
1084-
# 5. Get all daemonsets
1085-
print("Checking DaemonSets..")
1086-
dsets_cpu, dsets_mem, dsets_count = self._get_metrics_daemonsets(account)
1087-
1088-
# 6. Get all replicationcontrollers
1089-
print("Checking ReplicationControllers..")
1090-
rcsets_cpu, rcsets_mem, rcsets_count = self._get_metrics_replicationcontrollers(account)
1091-
1092-
# 7. Get all pods
1093-
print("Checking Pods..")
1094-
p_cpu, p_mem, p_count = self._get_metrics_pods(account)
1095-
1096-
all_cpu = cr_cpu + ssets_cpu + rsets_cpu + dsets_cpu + rcsets_cpu + p_cpu
1097-
all_mem = cr_mem + ssets_mem + rsets_mem + dsets_mem + rcsets_mem + p_mem
1098-
1099-
print("Kubernetes Resources created:")
1100-
print(" Number of Custom Resources: " + str(cr_count))
1101-
print(" Number of Deployments: " + str(dep_count))
1102-
print(" Number of StatefulSets: " + str(ss_count))
1103-
print(" Number of ReplicaSets: " + str(rsets_count))
1104-
print(" Number of DaemonSets: " + str(dsets_count))
1105-
print(" Number of ReplicationControllers: " + str(rcsets_count))
1106-
print(" Number of Pods: " + str(p_count))
1107-
print("Underlying Physical Resoures consumed:")
1108-
print(" Total CPU(cores): " + str(all_cpu) + "m")
1109-
print(" Total MEMORY(bytes): " + str(all_mem) + "Mi")
1110-
print(" Total Storage(bytes): (Upcoming)")
1111-
1112-
def get_metrics_cr(self, custom_resource, custom_res_instance, namespace, follow_connections, opformat, kubeconfig):
997+
def get_metrics_cr(self, custom_resource, custom_res_instance, opformat, kubeconfig):
998+
namespace = self.get_kubeplus_namespace(kubeconfig)
1113999
accountidentity = self._get_identity(custom_resource, custom_res_instance, namespace)
11141000
accountidentity = ''
11151001
pod_list = []
1116-
if follow_connections == "false":
1117-
composition = self._get_composition(custom_resource, custom_res_instance, namespace)
1118-
num_of_resources = self._parse_number_of_resources(composition)
1119-
pod_list = self._parse_number_of_pods(composition)
1120-
if follow_connections == "true":
1121-
num_of_resources = "-"
1122-
conn_op_format = "json"
1123-
#pod_list = self._get_pods_for_cr_connections(custom_resource, custom_res_instance, namespace, kubeconfig, conn_op_format)
1124-
#pod_list = self.get_pods(custom_resource, custom_res_instance, kubeconfig) # uses label selectors
1125-
pod_list = self.get_pods_in_ns(custom_resource, custom_res_instance, kubeconfig) # queries Pods in the CR NS
1126-
if len(pod_list) == 0:
1127-
# uses kubectl connections plugin - slower than label selectors
1128-
pod_list = self._get_pods_for_cr_connections(custom_resource, custom_res_instance, namespace, kubeconfig, conn_op_format)
1129-
1130-
#cpu, memory = self._get_cpu_memory_usage(pod_list)
1131-
#print(pod_list)
1002+
num_of_resources = "-"
1003+
conn_op_format = "json"
1004+
pod_list = self.get_pods_in_ns(custom_resource, custom_res_instance, kubeconfig) # queries Pods in the CR NS
1005+
11321006
num_of_containers_conn = self._parse_number_of_containers(pod_list, kubecfg=kubeconfig)
11331007
total_storage_conn = self._parse_persistentvolumeclaims(pod_list, kubecfg=kubeconfig)
11341008
num_of_hosts_conn = self._parse_number_of_hosts(pod_list, kubecfg=kubeconfig)
@@ -1179,9 +1053,6 @@ def get_metrics_cr(self, custom_resource, custom_res_instance, namespace, follow
11791053
metricsToReturn = cpuMetrics + "\n" + memoryMetrics + "\n" + storageMetrics + "\n" + numOfPods + "\n" + numOfContainers + "\n" + networkReceiveBytes + "\n" + networkTransmitBytes + "\n" + numOfNotRunningPods + "\n" + oomEvents
11801054
print(metricsToReturn)
11811055
elif opformat == 'pretty':
1182-
#print("---------------------------------------------------------- ")
1183-
#print(" Creator Account Identity: " + accountidentity)
1184-
#print("---------------------------------------------------------- ")
11851056
print("---------------------------------------------------------- ")
11861057
print("Kubernetes Resources created:")
11871058
print(" Number of Sub-resources: " + str(num_of_resources))
@@ -1199,134 +1070,12 @@ def get_metrics_cr(self, custom_resource, custom_res_instance, namespace, follow
11991070
else:
12001071
print("Unknown output format specified. Accepted values: pretty, json, prometheus")
12011072

1202-
def get_metrics_service(self, service_name, namespace):
1203-
print("---------------------------------------------------------- ")
1204-
pod_list, res_list = self._get_pods_for_service(service_name, namespace)
1205-
#print(res_list)
1206-
print("Kubernetes Resources created:")
1207-
print(" Total Number of Resources: " + str(len(res_list)))
1208-
print(" Number of Pods: " + str(len(pod_list)))
1209-
1210-
num_of_containers = self._parse_number_of_containers(pod_list)
1211-
print(" Number of Containers: " + str(num_of_containers))
1212-
1213-
total_storage = self._parse_persistentvolumeclaims(pod_list)
1214-
1215-
num_of_hosts = self._parse_number_of_hosts(pod_list)
1216-
print(" Number of Nodes: " + str(num_of_hosts))
1217-
1218-
cpu, memory = self._get_cpu_memory_usage(pod_list)
1219-
1220-
print("Underlying Physical Resoures consumed:")
1221-
print(" Total CPU(cores): " + str(cpu) + "m")
1222-
print(" Total MEMORY(bytes): " + str(memory) + "Mi")
1223-
print(" Total Storage(bytes): " + str(total_storage) + "Gi")
1224-
print("---------------------------------------------------------- ")
1225-
1226-
def get_metrics_helmrelease(self, release_name):
1227-
pod_list = self._get_pods_for_helmrelease(release_name)
1228-
1229-
time1 = int(round(time.time() * 1000))
1230-
num_of_containers = self._parse_number_of_containers(pod_list)
1231-
time2 = int(round(time.time() * 1000))
1232-
1233-
#print(" time:" + str(time2-time1))
1234-
1235-
# TODO: What should be the namespace parameter for Helm releases?
1236-
# Currently setting to "default"
1237-
time1 = int(round(time.time() * 1000))
1238-
total_storage = self._parse_persistentvolumeclaims(pod_list)
1239-
time2 = int(round(time.time() * 1000))
1240-
#print(" pvc time:" + str(time2-time1))
1241-
1242-
time1 = int(round(time.time() * 1000))
1243-
num_of_hosts = self._parse_number_of_hosts(pod_list)
1244-
time2 = int(round(time.time() * 1000))
1245-
#print(" time:" + str(time2-time1))
1246-
1247-
cpu, memory = self._get_cpu_memory_usage(pod_list)
1248-
1249-
metrics_helm_release = {}
1250-
metrics_helm_release['num_of_pods'] = str(len(pod_list))
1251-
metrics_helm_release['num_of_containers'] = str(num_of_containers)
1252-
metrics_helm_release['num_of_hosts'] = str(num_of_hosts)
1253-
metrics_helm_release['cpu'] = str(cpu)
1254-
metrics_helm_release['memory'] = str(memory)
1255-
metrics_helm_release['storage'] = str(total_storage)
1256-
return metrics_helm_release
1257-
1258-
def print_metrics_helmrelease(self, metrics_helm_release):
1259-
num_of_pods = metrics_helm_release['num_of_pods']
1260-
num_of_containers = metrics_helm_release['num_of_containers']
1261-
num_of_hosts = metrics_helm_release['num_of_hosts']
1262-
cpu = metrics_helm_release['cpu']
1263-
memory = metrics_helm_release['memory']
1264-
total_storage = metrics_helm_release['storage']
1265-
1266-
print("---------------------------------------------------------- ")
1267-
print("Kubernetes Resources created:")
1268-
print(" Number of Pods: " + num_of_pods)
1269-
print(" Number of Containers: " + num_of_containers)
1270-
print(" Number of Nodes: " + num_of_hosts)
1271-
print("Underlying Physical Resoures consumed:")
1272-
print(" Total CPU(cores): " + str(cpu) + "m")
1273-
print(" Total MEMORY(bytes): " + str(memory) + "Mi")
1274-
print(" Total Storage(bytes): " + str(total_storage) + "Gi")
1275-
print("---------------------------------------------------------- ")
1276-
1277-
def prometheus_metrics_helmrelease(self, release_name, metrics_helm_release):
1278-
millis = int(round(time.time() * 1000))
1279-
metricsToReturn = ''
1280-
cpu = metrics_helm_release['cpu']
1281-
memory = metrics_helm_release['memory']
1282-
storage = metrics_helm_release['storage']
1283-
num_of_pods = metrics_helm_release['num_of_pods']
1284-
num_of_containers = metrics_helm_release['num_of_containers']
1285-
cpuMetrics = 'cpu{helmrelease="'+release_name+'"} ' + str(cpu) + ' ' + str(millis)
1286-
memoryMetrics = 'memory{helmrelease="'+release_name+'"} ' + str(memory) + ' ' + str(millis)
1287-
storageMetrics = 'storage{helmrelease="'+release_name+'"} ' + str(storage) + ' ' + str(millis)
1288-
numOfPods = 'pods{helmrelease="'+release_name+'"} ' + str(num_of_pods) + ' ' + str(millis)
1289-
numOfContainers = 'containers{helmrelease="'+release_name+'"} ' + str(num_of_containers) + ' ' + str(millis)
1290-
metricsToReturn = cpuMetrics + "\n" + memoryMetrics + "\n" + storageMetrics + "\n" + numOfPods + "\n" + numOfContainers
1291-
return metricsToReturn
12921073

12931074
if __name__ == '__main__':
12941075
crMetrics = CRMetrics()
12951076

1296-
res_type = sys.argv[1]
1297-
1298-
if res_type == "cr":
1299-
custom_resource = sys.argv[2]
1300-
custom_resource_instance = sys.argv[3]
1301-
namespace = sys.argv[4]
1302-
outputformat = sys.argv[5]
1303-
follow_connections = sys.argv[6]
1304-
kubeconfig = sys.argv[7]
1305-
crMetrics.get_metrics_cr(custom_resource, custom_resource_instance, namespace, follow_connections, outputformat, kubeconfig)
1306-
1307-
if res_type == "account":
1308-
creator_account = sys.argv[2]
1309-
if len(sys.argv) == 4:
1310-
crMetrics._get_metrics_creator_account_with_connections(creator_account)
1311-
else:
1312-
crMetrics.get_metrics_creator_account(creator_account)
1313-
1314-
if res_type == "service":
1315-
service_name = sys.argv[2]
1316-
namespace = sys.argv[3]
1317-
crMetrics.get_metrics_service(service_name, namespace)
1318-
1319-
if res_type == "helmrelease":
1320-
release_name = sys.argv[2]
1321-
op_format = sys.argv[3]
1322-
metrics_helm_release = crMetrics.get_metrics_helmrelease(release_name)
1323-
if op_format == "pretty":
1324-
crMetrics.print_metrics_helmrelease(metrics_helm_release)
1325-
elif op_format == "prometheus":
1326-
prom_metrics = crMetrics.prometheus_metrics_helmrelease(release_name, metrics_helm_release)
1327-
print(prom_metrics)
1328-
elif op_format == "json":
1329-
metrics_helm_release_json = json.dumps(metrics_helm_release)
1330-
print(metrics_helm_release_json)
1331-
else:
1332-
print("Unrecognized output format. Supported formats - pretty/json/prometheus")
1077+
custom_resource = sys.argv[1]
1078+
custom_resource_instance = sys.argv[2]
1079+
outputformat = sys.argv[3]
1080+
kubeconfig = sys.argv[4]
1081+
crMetrics.get_metrics_cr(custom_resource, custom_resource_instance, outputformat, kubeconfig)

0 commit comments

Comments
 (0)