Skip to content

Commit

Permalink
Merge pull request #290 from linkernetworks/revert-282-phstsai/VX-280
Browse files Browse the repository at this point in the history
Revert "[Bug] VX-280: GetContainer API should require pod name"
  • Loading branch information
John-Lin authored Aug 28, 2018
2 parents 41494d1 + fb4d02d commit 50b64eb
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 50 deletions.
77 changes: 54 additions & 23 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
- [List NICs of certain node](#list-nics-of-certain-node)
- [List Pod](#list-pod)
- [Get Pod](#get-pod)
- [List Containers](#list-containers)
- [Get Container](#get-container)
- [List Services](#list-services)
- [Get Service](#get-service)
Expand Down Expand Up @@ -655,7 +656,7 @@ For each Pod, we have fileds need to handle.
- Always,OnFailure,Never
9. networkType: the string options for network type, support "host", "custom" and "cluster".
10. nodeAffinity: the string array to indicate whchi nodes I want my Pod can run in.
11. envVars: the environment variables for containers and it's map (string to stirng) form.
12. envVars: the environment variables for containers and it's map (string to stirng) form.

Example:

Expand Down Expand Up @@ -999,8 +1000,7 @@ Response Data:
"createAt": 1532573834,
"status": "Ready",
"os": "Ubuntu 16.04.4 LTS",
"kernelVersion": "4.4.0-133-generic",
"dockerVersion": "17.6.2",
"kernelVersion": "4.4.0-128-generic",
"kubeproxyVersion": "v1.11.0",
"kubernetesVersion": "v1.11.0",
"labels": {
Expand All @@ -1010,18 +1010,15 @@ Response Data:
}
},
"resource": {
"cpuRequests": 1.3,
"cpuLimits": 0,
"memoryRequests": 146800640,
"memoryLimits": 356515840,
"memoryTotalHugepages": 1024,
"memoryFreeHugepages": 512,
"memoryHugepagesSize": 2097152,
"cpuRequests": 1.05,
"cpuLimits": 0.6,
"memoryRequests": 283115520,
"memoryLimits": 3009413000,
"allocatableCPU": 2,
"allocatableMemory": 2948079600,
"allocatableMemory": 1891131400,
"allocatablePods": 110,
"capacityCPU": 2,
"capacityMemory": 5200421000,
"capacityMemory": 4143472600,
"capacityPods": 110
},
"nics": {
Expand Down Expand Up @@ -1255,8 +1252,38 @@ Response Data:
}
```

### List Containers
**GET /v1/monitoring/container?namespace=\.\*&node=\.\*&podpo=\.***

Example:
```
curl -X GET http://localhost:7890/v1/monitoring/containers
```

Response Data:
``` json
{
"node-exporter": { ... },
"prometheus": { ... },
"tiller": { ... },
"vortex-server": { ... },
...
```

Example:
```
curl -X GET http://localhost:7890/v1/monitoring/containers\?namespace\=vortex\&node\=vortex-dev\&pod\=vortex-server-6945b797bb-jbszk
```

Response Data:
``` json
{
"vortex-server": { ... }
}
```

### Get Container
**Get /v1/monitoring/pods/{pod}/{container}**
**Get /v1/monitoring/container/{id}**

Example:
```
Expand All @@ -1267,18 +1294,22 @@ Response Data:
``` json
{
"detail": {
"containerName": "test1",
"createAt": 1535361241,
"status": "running",
"restartTime": 4,
"pod": "atest",
"namespace": "default",
"containerName": "prometheus",
"createAt": 0,
"pod": "prometheus-7f759794cb-52t54",
"namespace": "vortex",
"node": "vortex-dev",
"image": "busybox:latest",
"image": "prom/prometheus:v2.2.1",
"command": [
"sleep",
"3600"
]
"/bin/prometheus"
],
"vNic": ""
},
"status": {
"status": "running",
"waitingReason": "",
"terminatedReason": "",
"restartTime": 0
},
"resource": {
"cpuUsagePercentage": [
Expand Down
16 changes: 8 additions & 8 deletions src/prometheuscontroller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,15 +344,15 @@ podStatusCheckingLoop:
}

// GetContainer will get container
func GetContainer(sp *serviceprovider.Container, podId string, containerId string) (entity.ContainerMetrics, error) {
func GetContainer(sp *serviceprovider.Container, id string) (entity.ContainerMetrics, error) {
container := entity.ContainerMetrics{}

// basic info from kube-state-metrics
expression := Expression{}
expression.Metrics = []string{
"kube_pod_container_info",
"kube_pod_container_status_restarts_total"}
expression.QueryLabels = map[string]string{"container": containerId, "pod": podId}
expression.QueryLabels = map[string]string{"container": id}

str := basicExpr(expression.Metrics)
str = queryExpr(str, expression.QueryLabels)
Expand All @@ -365,7 +365,7 @@ func GetContainer(sp *serviceprovider.Container, podId string, containerId strin
switch result.Metric["__name__"] {

case "kube_pod_container_info":
container.Detail.ContainerName = containerId
container.Detail.ContainerName = id
container.Detail.Pod = string(result.Metric["pod"])
container.Detail.Image = string(result.Metric["image"])
container.Detail.Namespace = string(result.Metric["namespace"])
Expand All @@ -380,7 +380,7 @@ func GetContainer(sp *serviceprovider.Container, podId string, containerId strin
expression.Metrics = []string{
"container_start_time_seconds",
"container_last_seen"}
expression.QueryLabels = map[string]string{"container_label_io_kubernetes_container_name": containerId, "container_label_io_kubernetes_pod_name": podId}
expression.QueryLabels = map[string]string{"container_label_io_kubernetes_container_name": id}

str = basicExpr(expression.Metrics)
str = queryExpr(str, expression.QueryLabels)
Expand All @@ -404,7 +404,7 @@ func GetContainer(sp *serviceprovider.Container, podId string, containerId strin
container.Detail.Status = ""

expression.Metrics = []string{"kube_pod_container_status.*"}
expression.QueryLabels = map[string]string{"container": containerId, "pod": podId}
expression.QueryLabels = map[string]string{"container": id}

str = basicExpr(expression.Metrics)
str = queryExpr(str, expression.QueryLabels)
Expand Down Expand Up @@ -443,7 +443,7 @@ containerStatusCheckingLoop:
}

for _, obj := range pod.Spec.Containers {
if obj.Name == containerId {
if obj.Name == id {
container.Detail.Command = obj.Command
break
}
Expand All @@ -455,7 +455,7 @@ containerStatusCheckingLoop:

// Memory resource
expression.Metrics = []string{"container_memory_usage_bytes"}
expression.QueryLabels = map[string]string{"container_label_io_kubernetes_container_name": containerId, "container_label_io_kubernetes_pod_name": podId}
expression.QueryLabels = map[string]string{"container_label_io_kubernetes_container_name": id}

str = basicExpr(expression.Metrics)
str = queryExpr(str, expression.QueryLabels)
Expand All @@ -471,7 +471,7 @@ containerStatusCheckingLoop:

// CPU resource
expression.Metrics = []string{"container_cpu_usage_seconds_total"}
expression.QueryLabels = map[string]string{"container_label_io_kubernetes_container_name": containerId, "container_label_io_kubernetes_pod_name": podId}
expression.QueryLabels = map[string]string{"container_label_io_kubernetes_container_name": id}

str = basicExpr(expression.Metrics)
str = queryExpr(str, expression.QueryLabels)
Expand Down
3 changes: 1 addition & 2 deletions src/prometheuscontroller/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,9 @@ func (suite *PrometheusExpressionTestSuite) TestGetContainer() {
namespace := "vortex"
pods, err := suite.sp.KubeCtl.GetPods(namespace)
suite.NoError(err)
podName := pods[0].Name
containerName := pods[0].Status.ContainerStatuses[0].Name

container, err := GetContainer(suite.sp, podName, containerName)
container, err := GetContainer(suite.sp, containerName)
suite.NoError(err)
suite.Equal(containerName, container.Detail.ContainerName)
}
Expand Down
52 changes: 44 additions & 8 deletions src/server/handler_prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ import (

func getContainerMetricsHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response
podId := req.PathParameter("pod")
containerId := req.PathParameter("container")
id := req.PathParameter("id")

container, err := pc.GetContainer(sp, podId, containerId)
container, err := pc.GetContainer(sp, id)
if err != nil {
response.InternalServerError(req.Request, resp.ResponseWriter, err)
return
Expand All @@ -24,7 +23,7 @@ func getContainerMetricsHandler(ctx *web.Context) {

func getPodMetricsHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response
id := req.PathParameter("pod")
id := req.PathParameter("id")

pod, err := pc.GetPod(sp, id)
if err != nil {
Expand All @@ -37,7 +36,7 @@ func getPodMetricsHandler(ctx *web.Context) {

func getServiceMetricsHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response
id := req.PathParameter("service")
id := req.PathParameter("id")

service, err := pc.GetService(sp, id)
if err != nil {
Expand All @@ -50,7 +49,7 @@ func getServiceMetricsHandler(ctx *web.Context) {

func getControllerMetricsHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response
id := req.PathParameter("controller")
id := req.PathParameter("id")

controller, err := pc.GetController(sp, id)
if err != nil {
Expand All @@ -63,7 +62,7 @@ func getControllerMetricsHandler(ctx *web.Context) {

func getNodeMetricsHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response
id := req.PathParameter("node")
id := req.PathParameter("id")

node, err := pc.GetNode(sp, id)
if err != nil {
Expand All @@ -74,6 +73,43 @@ func getNodeMetricsHandler(ctx *web.Context) {
resp.WriteEntity(node)
}

func listContainerMetricsHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response

query := query.New(req.Request.URL.Query())
queryLabels := map[string]string{}

if node, ok := query.Str("node"); ok {
queryLabels["node"] = node
}

if namespace, ok := query.Str("namespace"); ok {
queryLabels["namespace"] = namespace
}

if pod, ok := query.Str("pod"); ok {
queryLabels["pod"] = pod
}

containerNameList, err := pc.ListContainerName(sp, queryLabels)
if err != nil {
response.InternalServerError(req.Request, resp.ResponseWriter, err)
return
}

containerList := map[string]entity.ContainerMetrics{}
for _, containerName := range containerNameList {
container, err := pc.GetContainer(sp, containerName)
if err != nil {
response.InternalServerError(req.Request, resp.ResponseWriter, err)
return
}
containerList[containerName] = container
}

resp.WriteEntity(containerList)
}

func listPodMetricsHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response

Expand Down Expand Up @@ -194,7 +230,7 @@ func listNodeMetricsHandler(ctx *web.Context) {

func listNodeNicsMetricsHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response
id := req.PathParameter("node")
id := req.PathParameter("id")

nicList, err := pc.ListNodeNICs(sp, id)
if err != nil {
Expand Down
19 changes: 17 additions & 2 deletions src/server/handler_prometheus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,29 @@ func (suite *PrometheusTestSuite) TestGetPodMetrics() {
assertResponseCode(suite.T(), http.StatusOK, httpWriter)
}

func (suite *PrometheusTestSuite) TestListContainerMetrics() {
httpRequest, err := http.NewRequest("GET", "http://localhost:7890/v1/monitoring/containers/", nil)
suite.NoError(err)

httpWriter := httptest.NewRecorder()
suite.wc.Dispatch(httpWriter, httpRequest)
assertResponseCode(suite.T(), http.StatusOK, httpWriter)

httpRequest, err = http.NewRequest("GET", "http://localhost:7890/v1/monitoring/containers?node=.*&namespace=.*&pod=.*", nil)
suite.NoError(err)

httpWriter = httptest.NewRecorder()
suite.wc.Dispatch(httpWriter, httpRequest)
assertResponseCode(suite.T(), http.StatusOK, httpWriter)
}

func (suite *PrometheusTestSuite) TestGetContainerMetrics() {
namespace := "vortex"
pods, err := suite.sp.KubeCtl.GetPods(namespace)
suite.NoError(err)
podName := pods[0].Name
containerName := pods[0].Status.ContainerStatuses[0].Name

httpRequest, err := http.NewRequest("GET", "http://localhost:7890/v1/monitoring/pods/"+podName+"/"+containerName, nil)
httpRequest, err := http.NewRequest("GET", "http://localhost:7890/v1/monitoring/containers/"+containerName, nil)
suite.NoError(err)

httpWriter := httptest.NewRecorder()
Expand Down
15 changes: 8 additions & 7 deletions src/server/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,19 +162,20 @@ func newMonitoringService(sp *serviceprovider.Container) *restful.WebService {
webService.Path("/v1/monitoring").Consumes(restful.MIME_JSON, restful.MIME_JSON).Produces(restful.MIME_JSON, restful.MIME_JSON)
// node
webService.Route(webService.GET("/nodes").To(handler.RESTfulServiceHandler(sp, listNodeMetricsHandler)))
webService.Route(webService.GET("/nodes/{node}").To(handler.RESTfulServiceHandler(sp, getNodeMetricsHandler)))
webService.Route(webService.GET("/nodes/{node}/nics").To(handler.RESTfulServiceHandler(sp, listNodeNicsMetricsHandler)))
webService.Route(webService.GET("/nodes/{id}").To(handler.RESTfulServiceHandler(sp, getNodeMetricsHandler)))
webService.Route(webService.GET("/nodes/{id}/nics").To(handler.RESTfulServiceHandler(sp, listNodeNicsMetricsHandler)))
// pod
webService.Route(webService.GET("/pods").To(handler.RESTfulServiceHandler(sp, listPodMetricsHandler)))
webService.Route(webService.GET("/pods/{pod}").To(handler.RESTfulServiceHandler(sp, getPodMetricsHandler)))
//container
webService.Route(webService.GET("/pods/{pod}/{container}").To(handler.RESTfulServiceHandler(sp, getContainerMetricsHandler)))
webService.Route(webService.GET("/pods/{id}").To(handler.RESTfulServiceHandler(sp, getPodMetricsHandler)))
// container
webService.Route(webService.GET("/containers").To(handler.RESTfulServiceHandler(sp, listContainerMetricsHandler)))
webService.Route(webService.GET("/containers/{id}").To(handler.RESTfulServiceHandler(sp, getContainerMetricsHandler)))
// service
webService.Route(webService.GET("/services").To(handler.RESTfulServiceHandler(sp, listServiceMetricsHandler)))
webService.Route(webService.GET("/services/{service}").To(handler.RESTfulServiceHandler(sp, getServiceMetricsHandler)))
webService.Route(webService.GET("/services/{id}").To(handler.RESTfulServiceHandler(sp, getServiceMetricsHandler)))
// controller
webService.Route(webService.GET("/controllers").To(handler.RESTfulServiceHandler(sp, listControllerMetricsHandler)))
webService.Route(webService.GET("/controllers/{controller}").To(handler.RESTfulServiceHandler(sp, getControllerMetricsHandler)))
webService.Route(webService.GET("/controllers/{id}").To(handler.RESTfulServiceHandler(sp, getControllerMetricsHandler)))
return webService
}

Expand Down

0 comments on commit 50b64eb

Please sign in to comment.