Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] VX-280: GetContainer API should require pod name #282

Merged
merged 3 commits into from
Aug 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 28 additions & 59 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,17 @@
- [List Pods](#list-pods)
- [Get Pod](#get-pod)
- [Delete Pod](#delete-pod)
- [Deployment](#deploy)
- [Create Deployment](#create-deploy)
- [List Deployments](#list-deploys)
- [Get Deployment](#get-deploy)
- [Delete Deployment](#delete-deploy)
- [Deployment](#deployment)
- [Create Deployment](#create-deployment)
- [List Deployments](#list-deployments)
- [Get Deployment](#get-deployment)
- [Delete Deployment](#delete-deployment)
- [Resouce Monitoring](#resouce-monitoring)
- [List Nodes](#list-nodes)
- [Get Node](#get-node)
- [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 @@ -620,7 +619,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.
12. envVars: the environment variables for containers and it's map (string to stirng) form.
11. envVars: the environment variables for containers and it's map (string to stirng) form.

Example:

Expand Down Expand Up @@ -964,7 +963,8 @@ Response Data:
"createAt": 1532573834,
"status": "Ready",
"os": "Ubuntu 16.04.4 LTS",
"kernelVersion": "4.4.0-128-generic",
"kernelVersion": "4.4.0-133-generic",
"dockerVersion": "17.6.2",
"kubeproxyVersion": "v1.11.0",
"kubernetesVersion": "v1.11.0",
"labels": {
Expand All @@ -974,15 +974,18 @@ Response Data:
}
},
"resource": {
"cpuRequests": 1.05,
"cpuLimits": 0.6,
"memoryRequests": 283115520,
"memoryLimits": 3009413000,
"cpuRequests": 1.3,
"cpuLimits": 0,
"memoryRequests": 146800640,
"memoryLimits": 356515840,
"memoryTotalHugepages": 1024,
"memoryFreeHugepages": 512,
"memoryHugepagesSize": 2097152,
"allocatableCPU": 2,
"allocatableMemory": 1891131400,
"allocatableMemory": 2948079600,
"allocatablePods": 110,
"capacityCPU": 2,
"capacityMemory": 4143472600,
"capacityMemory": 5200421000,
"capacityPods": 110
},
"nics": {
Expand Down Expand Up @@ -1216,38 +1219,8 @@ 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/container/{id}**
**Get /v1/monitoring/pods/{pod}/{container}**

Example:
```
Expand All @@ -1258,22 +1231,18 @@ Response Data:
``` json
{
"detail": {
"containerName": "prometheus",
"createAt": 0,
"pod": "prometheus-7f759794cb-52t54",
"namespace": "vortex",
"containerName": "test1",
"createAt": 1535361241,
"status": "running",
"restartTime": 4,
"pod": "atest",
"namespace": "default",
"node": "vortex-dev",
"image": "prom/prometheus:v2.2.1",
"image": "busybox:latest",
"command": [
"/bin/prometheus"
],
"vNic": ""
},
"status": {
"status": "running",
"waitingReason": "",
"terminatedReason": "",
"restartTime": 0
"sleep",
"3600"
]
},
"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 @@ -308,15 +308,15 @@ func GetPod(sp *serviceprovider.Container, id string) (entity.PodMetrics, error)
}

// GetContainer will get container
func GetContainer(sp *serviceprovider.Container, id string) (entity.ContainerMetrics, error) {
func GetContainer(sp *serviceprovider.Container, podId string, containerId 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": id}
expression.QueryLabels = map[string]string{"container": containerId, "pod": podId}

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

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

str = basicExpr(expression.Metrics)
str = queryExpr(str, expression.QueryLabels)
Expand All @@ -366,7 +366,7 @@ func GetContainer(sp *serviceprovider.Container, id string) (entity.ContainerMet

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

str = basicExpr(expression.Metrics)
str = queryExpr(str, expression.QueryLabels)
Expand Down Expand Up @@ -410,7 +410,7 @@ func GetContainer(sp *serviceprovider.Container, id string) (entity.ContainerMet
}

for _, obj := range pod.Spec.Containers {
if obj.Name == id {
if obj.Name == containerId {
container.Detail.Command = obj.Command
break
}
Expand All @@ -422,7 +422,7 @@ func GetContainer(sp *serviceprovider.Container, id string) (entity.ContainerMet

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

str = basicExpr(expression.Metrics)
str = queryExpr(str, expression.QueryLabels)
Expand All @@ -438,7 +438,7 @@ func GetContainer(sp *serviceprovider.Container, id string) (entity.ContainerMet

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

str = basicExpr(expression.Metrics)
str = queryExpr(str, expression.QueryLabels)
Expand Down
3 changes: 2 additions & 1 deletion src/prometheuscontroller/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,10 @@ 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, containerName)
container, err := GetContainer(suite.sp, podName, containerName)
suite.NoError(err)
suite.Equal(containerName, container.Detail.ContainerName)
}
Expand Down
52 changes: 8 additions & 44 deletions src/server/handler_prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import (

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

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

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

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

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

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

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

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

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

node, err := pc.GetNode(sp, id)
if err != nil {
Expand All @@ -73,43 +74,6 @@ 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 @@ -230,7 +194,7 @@ func listNodeMetricsHandler(ctx *web.Context) {

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

nicList, err := pc.ListNodeNICs(sp, id)
if err != nil {
Expand Down
19 changes: 2 additions & 17 deletions src/server/handler_prometheus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,29 +106,14 @@ 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/containers/"+containerName, nil)
httpRequest, err := http.NewRequest("GET", "http://localhost:7890/v1/monitoring/pods/"+podName+"/"+containerName, nil)
suite.NoError(err)

httpWriter := httptest.NewRecorder()
Expand Down
15 changes: 7 additions & 8 deletions src/server/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,19 +154,18 @@ 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/{id}").To(handler.RESTfulServiceHandler(sp, getNodeMetricsHandler)))
webService.Route(webService.GET("/nodes/{id}/nics").To(handler.RESTfulServiceHandler(sp, listNodeNicsMetricsHandler)))
webService.Route(webService.GET("/nodes/{node}").To(handler.RESTfulServiceHandler(sp, getNodeMetricsHandler)))
webService.Route(webService.GET("/nodes/{node}/nics").To(handler.RESTfulServiceHandler(sp, listNodeNicsMetricsHandler)))
// pod
webService.Route(webService.GET("/pods").To(handler.RESTfulServiceHandler(sp, listPodMetricsHandler)))
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)))
webService.Route(webService.GET("/pods/{pod}").To(handler.RESTfulServiceHandler(sp, getPodMetricsHandler)))
//container
webService.Route(webService.GET("/pods/{pod}/{container}").To(handler.RESTfulServiceHandler(sp, getContainerMetricsHandler)))
// service
webService.Route(webService.GET("/services").To(handler.RESTfulServiceHandler(sp, listServiceMetricsHandler)))
webService.Route(webService.GET("/services/{id}").To(handler.RESTfulServiceHandler(sp, getServiceMetricsHandler)))
webService.Route(webService.GET("/services/{service}").To(handler.RESTfulServiceHandler(sp, getServiceMetricsHandler)))
// controller
webService.Route(webService.GET("/controllers").To(handler.RESTfulServiceHandler(sp, listControllerMetricsHandler)))
webService.Route(webService.GET("/controllers/{id}").To(handler.RESTfulServiceHandler(sp, getControllerMetricsHandler)))
webService.Route(webService.GET("/controllers/{controller}").To(handler.RESTfulServiceHandler(sp, getControllerMetricsHandler)))
return webService
}