Merge pull request #1835 from fabric8io/k8s-sd-pod-disco-hostname

Kubernetes SD: Add node name and host IP to pod discovery
This commit is contained in:
Fabian Reinartz 2016-07-26 15:18:42 -07:00 committed by GitHub
commit 67b7535471
4 changed files with 28 additions and 0 deletions

View file

@ -62,6 +62,10 @@ const (
podLabelPrefix = metaLabelPrefix + "pod_label_"
// podAnnotationPrefix is the prefix for prom label names corresponding to k8s annotations for a target pod
podAnnotationPrefix = metaLabelPrefix + "pod_annotation_"
// podNodeLabel is the name for the label containing the name of the node that a pod is scheduled on to
podNodeNameLabel = metaLabelPrefix + "pod_node_name"
// podHostIPLabel is the name for the label containing the IP of the node that a pod is scheduled on to
podHostIPLabel = metaLabelPrefix + "pod_host_ip"
sourceServicePrefix = "services"
// serviceNamespaceLabel is the name for the label containing a target's service namespace.

View file

@ -117,9 +117,11 @@ func pod(name string, containers []Container) *Pod {
Status: "True",
},
},
HostIP: "2.2.2.2",
},
PodSpec: PodSpec{
Containers: c,
NodeName: "test-node",
},
}
}
@ -147,6 +149,12 @@ func TestUpdatePodTargets(t *testing.T) {
t.Fatalf("expected 0 targets, received %d", len(result))
}
// Return no targets for a pod that has no HostIP
result = updatePodTargets(&Pod{PodStatus: PodStatus{PodIP: "1.1.1.1", Phase: "Running"}}, true)
if len(result) > 0 {
t.Fatalf("expected 0 targets, received %d", len(result))
}
// A pod with all valid containers should return one target per container with allContainers=true
result = updatePodTargets(pod("easy", []Container{container("a", portsA), container("b", portsB)}), true)
if len(result) != 2 {
@ -167,6 +175,12 @@ func TestUpdatePodTargets(t *testing.T) {
if result[1][podContainerPortMapPrefix+"https"] != "443" {
t.Fatalf("expected result[1][podContainerPortMapPrefix + 'https'] to be '443', but was %s", result[1][podContainerPortMapPrefix+"https"])
}
if result[0][podNodeNameLabel] != "test-node" {
t.Fatalf("expected result[0] podNodeNameLabel 'test-node', received '%s'", result[0][podNodeNameLabel])
}
if result[0][podHostIPLabel] != "2.2.2.2" {
t.Fatalf("expected result[0] podHostIPLabel '2.2.2.2', received '%s'", result[0][podHostIPLabel])
}
// A pod with all valid containers should return one target with allContainers=false, and it should be the alphabetically first container
result = updatePodTargets(pod("easy", []Container{container("a", portsA), container("b", portsB)}), false)

View file

@ -255,6 +255,12 @@ func updatePodTargets(pod *Pod, allContainers bool) []model.LabelSet {
return targets
}
// Should never hit this (running pods should always have this set), but better to be defensive.
if pod.PodStatus.HostIP == "" {
log.Debugf("skipping pod %s -- PodStatus.HostIP is empty", pod.ObjectMeta.Name)
return targets
}
ready := "unknown"
for _, cond := range pod.PodStatus.Conditions {
if strings.ToLower(cond.Type) == "ready" {
@ -293,6 +299,8 @@ func updatePodTargets(pod *Pod, allContainers bool) []model.LabelSet {
podContainerNameLabel: model.LabelValue(container.Name),
podContainerPortNameLabel: model.LabelValue(tcpPorts[0].Name),
podReadyLabel: model.LabelValue(ready),
podNodeNameLabel: model.LabelValue(pod.PodSpec.NodeName),
podHostIPLabel: model.LabelValue(pod.PodStatus.HostIP),
}
for _, port := range tcpPorts {

View file

@ -285,10 +285,12 @@ type PodStatus struct {
Phase string `json:"phase" description:"Current condition of the pod. More info: http://kubernetes.io/v1.1/docs/user-guide/pod-states.html#pod-phase"`
PodIP string `json:"podIP" description:"IP address allocated to the pod. Routable at least within the cluster. Empty if not yet allocated."`
Conditions []PodCondition `json:"conditions" description:"Current service state of pod."`
HostIP string `json:"hostIP,omitempty" description:"IP address of the host to which the pod is assigned. Empty if not yet scheduled."`
}
type PodSpec struct {
Containers []Container `json:"containers" description:"list of containers, see http://kubernetes.io/v1.1/docs/api-reference/v1/definitions.html#_v1_container"`
NodeName string `json:"nodeName,omitempty" description:"NodeName is a request to schedule this pod onto a specific node. If it is non-empty, the scheduler simply schedules this pod onto that node, assuming that it fits resource requirements."`
}
type PodCondition struct {