diff --git a/Dockerfile b/Dockerfile index 307804063..41bb2927b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,22 +10,19 @@ # See the License for the specific language governing permissions and # limitations under the License. #======================================================================== - -FROM golang:latest +FROM golang ADD ./main.go /go/src/github.com/intelsdi-x/dbi-iafeature-discovery/ -ADD ./rdt-discovery/mon-discovery /go/bin/ -ADD ./rdt-discovery/l3-alloc-discovery /go/bin/ -ADD ./rdt-discovery/l2-alloc-discovery /go/bin/ +ADD ./glide.yaml /go/src/github.com/intelsdi-x/dbi-iafeature-discovery/ +ADD ./rdt-discovery /go/src/github.com/intelsdi-x/dbi-iafeature-discovery/rdt-discovery/ WORKDIR /go/src/github.com/intelsdi-x/dbi-iafeature-discovery RUN git clone https://github.com/01org/intel-cmt-cat.git RUN cd intel-cmt-cat/lib; make install - -RUN go get -d -v github.com/klauspost/cpuid -RUN go get -d -v k8s.io/kubernetes; exit 0 - +RUN cd rdt-discovery; make +RUN go get github.com/Masterminds/glide +RUN glide install RUN go install github.com/intelsdi-x/dbi-iafeature-discovery ENTRYPOINT /go/bin/dbi-iafeature-discovery diff --git a/README.md b/README.md index cffb97953..907527ec3 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ * [System Requirements](#system-requirements) * [Usage](#usage) - [Building from source](#building-from-source) +- [Targeting Nodes with Specific Features](#targeting-nodes-with-specific-features) - [License](#license) ## Overview @@ -48,7 +49,7 @@ The published node labels encode a few pieces of information: _Note: only features that are available on a given node are labeled, so the only label value published is the string `"true"`. This feature discovery code -will not add a label with the falue `"false"` for features that are not +will not add a label with the value `"false"` for features that are not present._ ``` @@ -115,9 +116,41 @@ docker push To use your published image from the step above instead of the `intelsdi/nodelabels` image, edit line 40 in the file -`[featurelabeling-job.json.template](featurelabeling-job.json.template)` to +`[dbi-iafeature-discovery-job.json.template](dbi-iafeature-discoverz-job.json.template)` to the new location (`/`). +## Targeting Nodes with Specific Features + +Nodes with specific features can be targeted using the `nodeSelector` field. The following example shows +how to target the Intel RDT L3 cache allocation (RDTL3CA) feature. + +```json +{ + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "labels": { + "env": "test" + }, + "name": "golang-test" + }, + "spec": { + "containers": [ + { + "image": "golang", + "name": "go1", + } + ], + "nodeSelector": { + ""node.alpha.intel.com/v0.1.0-cpu-RDTL3CA": "true" + } + } +} +``` + +For more details on targeting nodes, see [node selection][node-sel]. + + ## License This is open source software released under the [Apache 2.0 License](LICENSE). @@ -129,3 +162,4 @@ This is open source software released under the [Apache 2.0 License](LICENSE). [gcc-down]: https://gcc.gnu.org/ [kubectl-setup]: https://coreos.com/kubernetes/docs/latest/configure-kubectl.html [balaji-github]: https://github.com/balajismaniam +[node-sel]: http://kubernetes.io/docs/user-guide/node-selection/ diff --git a/featurelabeling-job.json.template b/dbi-iafeature-discovery-job.json.template similarity index 94% rename from featurelabeling-job.json.template rename to dbi-iafeature-discovery-job.json.template index 9d87e3453..c7251106e 100644 --- a/featurelabeling-job.json.template +++ b/dbi-iafeature-discovery-job.json.template @@ -3,9 +3,9 @@ "kind": "Job", "metadata": { "labels": { - "app": "dbi-nodelabel" + "app": "dbi-iafeature-discovery" }, - "name": "dbi-nodelabel" + "name": "dbi-iafeature-discovery" }, "spec": { "completions": COMPLETION_COUNT, diff --git a/glide.yaml b/glide.yaml new file mode 100644 index 000000000..17339c41c --- /dev/null +++ b/glide.yaml @@ -0,0 +1,8 @@ +package: github.com/intelsdi-x/dbi-iafeature-discovery +import: +- package: github.com/klauspost/cpuid + version: v1.0 +- package: k8s.io/kubernetes + version: v1.3.0 + subpackages: + - pkg/client/unversioned diff --git a/label-nodes.sh b/label-nodes.sh index 9f004d284..3e5787c66 100755 --- a/label-nodes.sh +++ b/label-nodes.sh @@ -1,9 +1,12 @@ -#!/bin/bash - +#!/usr/bin/env bash +# Get the node count in the Kubernetes cluster NumNodes=$(kubectl get nodes | grep -i ready | wc -l) -sed -e "s/COMPLETION_COUNT/$NumNodes/" -e "s/PARALLELISM_COUNT/$NumNodes/" featurelabeling-job.json.template > featurelabeling-job.json - -kubectl create -f featurelabeling-job.json - - +# We set the .spec.completions and .spec.parallelism to the node count +# We request a specific hostPort in the job spec to limit the number of pods +# that run on a node to one. As a result, one pod runs on each node in parallel +# We set the POD_NAME and POD_NAMESPACE environemnt variables to the pod name +# and pod namespace. These enivornment variables are used by the feature +# discovery software to get the Kubernetes pod and node object. +sed -e "s/COMPLETION_COUNT/$NumNodes/" -e "s/PARALLELISM_COUNT/$NumNodes/" dbi-iafeature-discovery-job.json.template > dbi-iafeature-discovery-job.json +kubectl create -f dbi-iafeature-discovery-job.json diff --git a/main.go b/main.go index b7f48b2cc..2e55745d8 100644 --- a/main.go +++ b/main.go @@ -22,74 +22,91 @@ import ( client "k8s.io/kubernetes/pkg/client/unversioned" ) +const ( + version = "0.1.0" +) + func main() { - //Setting-up K8S client + // Setting-up a logger file + fd, err := os.OpenFile("dbi-iafeature-discovery.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + log.Fatalf("Can't Open File for Logging: %v", err) + } + defer fd.Close() + log.SetOutput(fd) + + // Setting-up K8S client cli, err := client.NewInCluster() if err != nil { - log.Fatalf("Can't Get K8s Client:%v", err) + log.Fatalf("Can't Get K8s Client: %v", err) } - //Get the cpu features as strings - features := cpuid.CPU.Features.Strings() - - //Get the pod name and namespace from the env variables + // Get the pod name and namespace from the env variables podName := os.Getenv("POD_NAME") podns := os.Getenv("POD_NAMESPACE") + log.Printf("Pod Name ENV Variable: %s\n", podName) + log.Printf("Pod Namespace ENV Variable: %s\n", podns) - //Get the pod object using the pod name and namespace + // Get the pod object using the pod name and namespace pod, err := cli.Pods(podns).Get(podName) if err != nil { - log.Fatalf("Can't Get Pod:%v", err) + log.Fatalf("Can't Get Pod: %v", err) } - //Get the node object using the pod name and namespace + // Get the node object using the pod name and namespace node, err := cli.Nodes().Get(pod.Spec.NodeName) if err != nil { - log.Fatalf("Can't Get Node:%v", err) + log.Fatalf("Can't Get Node: %v", err) } - //Add each of the cpu feature as the node label + // Get the cpu features as strings + features := cpuid.CPU.Features.Strings() + log.Printf("CPU Features Detected from cpuid: %s\n", features) + // Add each of the cpu feature as the node label for _, feature := range features { - node.Labels["scheduler.alpha.intel.com/"+feature] = "true" + node.Labels["node.alpha.intel.com/v"+version+"-cpu-"+feature] = "true" } - //If supported, add CMT, MBM and CAT features as a node label - cmd := "/go/bin/mon-discovery" + // If supported, add CMT, MBM and CAT features as a node label + cmd := "/go/src/github.com/intelsdi-x/dbi-iafeature-discovery/rdt-discovery/mon-discovery" out, err := exec.Command("bash", "-c", cmd).Output() if err != nil { - log.Fatalf("Can't Dectect Support for RDT Monitoring:%v", err) + log.Fatalf("Can't Dectect Support for RDT Monitoring: %v", err) } outString := string(out[:]) if outString == "DETECTED" { - node.Labels["scheduler.alpha.intel.com/RDTMON"] = "true" + node.Labels["node.alpha.intel.com/v"+version+"-cpu-RDTMON"] = "true" } + log.Printf("RDT Monitoring Detected\n") - cmd = "/go/bin/l3-alloc-discovery" + cmd = "/go/src/github.com/intelsdi-x/dbi-iafeature-discovery/rdt-discovery/l3-alloc-discovery" out, err = exec.Command("bash", "-c", cmd).Output() if err != nil { - log.Fatalf("Can't Dectect Support for RDT L3 Allocation:%v", err) + log.Fatalf("Can't Dectect Support for RDT L3 Allocation: %v", err) } outString = string(out[:]) if outString == "DETECTED" { - node.Labels["scheduler.alpha.intel.com/RDTL3CA"] = "true" + node.Labels["node.alpha.intel.com/v"+version+"-cpu-RDTL3CA"] = "true" } + log.Printf("RDT L3 Cache Allocation Detected\n") - cmd = "/go/bin/l2-alloc-discovery" + cmd = "/go/src/github.com/intelsdi-x/dbi-iafeature-discovery/rdt-discovery/l2-alloc-discovery" out, err = exec.Command("bash", "-c", cmd).Output() if err != nil { - log.Fatalf("Can't Dectect Support for RDT L2 Allocation:%v", err) + log.Fatalf("Can't Dectect Support for RDT L2 Allocation: %v", err) } outString = string(out[:]) if outString == "DETECTED" { - node.Labels["scheduler.alpha.intel.com/RDTL2CA"] = "true" + node.Labels["node.alpha.intel.com/v"+version+"-cpu-RDTL2CA"] = "true" } + log.Printf("RDT L2 Cache Allocation Detected\n") - //Update the node with the node labels + // Update the node with the node labels _, err = cli.Nodes().Update(node) if err != nil { - log.Fatalf("Can't Update Node:%v", err) + log.Fatalf("Can't Update Node: %v", err) } } diff --git a/rdt-discovery/Makefile b/rdt-discovery/Makefile index 431163367..5ecd97ee7 100644 --- a/rdt-discovery/Makefile +++ b/rdt-discovery/Makefile @@ -1,13 +1,11 @@ CC=gcc LIBDIR=/usr/local/lib -INCDIR=$(HOME)/intel-cmt-cat/lib/ +INCDIR=/go/src/github.com/intelsdi-x/dbi-iafeature-discovery/intel-cmt-cat/lib/ LDFLAGS=-L$(LIBDIR) LDLIBS=-lpqos - CFLAGS=-I$(INCDIR) - default: $(MAKE) all all: