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

Promote Pod Hostname & Subdomain to fields (were annotations) #24362

Merged
merged 1 commit into from
Apr 29, 2016
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
8 changes: 8 additions & 0 deletions api/swagger-spec/apps_v1alpha1.json
Original file line number Diff line number Diff line change
Expand Up @@ -1160,6 +1160,14 @@
"$ref": "v1.LocalObjectReference"
},
"description": "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: http://releases.k8s.io/HEAD/docs/user-guide/images.md#specifying-imagepullsecrets-on-a-pod"
},
"hostname": {
"type": "string",
"description": "Specifies the hostname of the Pod If not specified, the pod's hostname will be set to a system-defined value."
},
"subdomain": {
"type": "string",
"description": "If specified, the fully qualified Pod hostname will be \"\u003chostname\u003e.\u003csubdomain\u003e.\u003cpod namespace\u003e.svc.\u003ccluster domain\u003e\". If not specified, the pod will not have a domainname at all."
}
}
},
Expand Down
8 changes: 8 additions & 0 deletions api/swagger-spec/batch_v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,14 @@
"$ref": "v1.LocalObjectReference"
},
"description": "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: http://releases.k8s.io/HEAD/docs/user-guide/images.md#specifying-imagepullsecrets-on-a-pod"
},
"hostname": {
"type": "string",
"description": "Specifies the hostname of the Pod If not specified, the pod's hostname will be set to a system-defined value."
},
"subdomain": {
"type": "string",
"description": "If specified, the fully qualified Pod hostname will be \"\u003chostname\u003e.\u003csubdomain\u003e.\u003cpod namespace\u003e.svc.\u003ccluster domain\u003e\". If not specified, the pod will not have a domainname at all."
}
}
},
Expand Down
8 changes: 8 additions & 0 deletions api/swagger-spec/extensions_v1beta1.json
Original file line number Diff line number Diff line change
Expand Up @@ -6699,6 +6699,14 @@
"$ref": "v1.LocalObjectReference"
},
"description": "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: http://releases.k8s.io/HEAD/docs/user-guide/images.md#specifying-imagepullsecrets-on-a-pod"
},
"hostname": {
"type": "string",
"description": "Specifies the hostname of the Pod If not specified, the pod's hostname will be set to a system-defined value."
},
"subdomain": {
"type": "string",
"description": "If specified, the fully qualified Pod hostname will be \"\u003chostname\u003e.\u003csubdomain\u003e.\u003cpod namespace\u003e.svc.\u003ccluster domain\u003e\". If not specified, the pod will not have a domainname at all."
}
}
},
Expand Down
12 changes: 12 additions & 0 deletions api/swagger-spec/v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -15501,6 +15501,10 @@
"type": "string",
"description": "The IP of this endpoint. May not be loopback (127.0.0.0/8), link-local (169.254.0.0/16), or link-local multicast ((224.0.0.0/24). IPv6 is also accepted but not fully supported on all platforms. Also, certain kubernetes components, like kube-proxy, are not IPv6 ready."
},
"hostname": {
"type": "string",
"description": "The Hostname of this endpoint"
},
"targetRef": {
"$ref": "v1.ObjectReference",
"description": "Reference to object providing the endpoint."
Expand Down Expand Up @@ -16820,6 +16824,14 @@
"$ref": "v1.LocalObjectReference"
},
"description": "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: http://releases.k8s.io/HEAD/docs/user-guide/images.md#specifying-imagepullsecrets-on-a-pod"
},
"hostname": {
"type": "string",
"description": "Specifies the hostname of the Pod If not specified, the pod's hostname will be set to a system-defined value."
},
"subdomain": {
"type": "string",
"description": "If specified, the fully qualified Pod hostname will be \"\u003chostname\u003e.\u003csubdomain\u003e.\u003cpod namespace\u003e.svc.\u003ccluster domain\u003e\". If not specified, the pod will not have a domainname at all."
}
}
},
Expand Down
35 changes: 33 additions & 2 deletions cluster/addons/dns/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,24 +60,55 @@ When enabled, pods are assigned a DNS A record in the form of `pod-ip-address.my
For example, a pod with ip `1.2.3.4` in the namespace `default` with a dns name of `cluster.local` would have an entry: `1-2-3-4.default.pod.cluster.local`.


####A Records and hostname Based on Pod Annotations - A Beta Feature in Kubernetes v1.2
####A Records and hostname based on Pod's hostname and subdomain fields
Currently when a pod is created, its hostname is the Pod's `metadata.name` value.

With v1.2, users can specify a Pod annotation, `pod.beta.kubernetes.io/hostname`, to specify what the Pod's hostname should be.
If the annotation is specified, the annotation value takes precendence over the Pod's name, to be the hostname of the pod.
For example, given a Pod with annotation `pod.beta.kubernetes.io/hostname: my-pod-name`, the Pod will have its hostname set to "my-pod-name".

With v1.3, the PodSpec has a `hostname` field, which can be used to specify the Pod's hostname. This field value takes precedence over the
`pod.beta.kubernetes.io/hostname` annotation value.

v1.2 introduces a beta feature where the user can specify a Pod annotation, `pod.beta.kubernetes.io/subdomain`, to specify what the Pod's subdomain should be.
If the annotation is specified, the fully qualified Pod hostname will be "<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>".
For example, given a Pod with the hostname annotation set to "foo", and the subdomain annotation set to "bar", in namespace "my-namespace", the pod will set its own FQDN as "foo.bar.my-namespace.svc.cluster.local"

With v1.3, the PodSpec has a `subdomain` field, which can be used to specify the Pod's subdomain. This field value takes precedence over the
`pod.beta.kubernetes.io/subdomain` annotation value.

Example:

```yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
hostname: busybox-1
subdomain: default
containers:
- image: busybox
command:
- sleep
- "3600"
name: busybox
```

If there exists a headless service in the same namespace as the pod and with the same name as the subdomain, the cluster's KubeDNS Server will also return an A record for the Pod's fully qualified hostname.
Given a Pod with the hostname annotation set to "foo" and the subdomain annotation set to "bar", and a headless Service named "bar" in the same namespace, the pod will see it's own FQDN as "foo.bar.my-namespace.svc.cluster.local". DNS will serve an A record at that name, pointing to the Pod's IP.
Given a Pod with the hostname set to "foo" and the subdomain set to "bar", and a headless Service named "bar" in the same namespace, the pod will see it's own FQDN as "foo.bar.my-namespace.svc.cluster.local". DNS will serve an A record at that name, pointing to the Pod's IP.

With v1.2, the Endpoints object also has a new annotation `endpoints.beta.kubernetes.io/hostnames-map`. Its value is the json representation of map[string(IP)][endpoints.HostRecord], for example: '{"10.245.1.6":{HostName: "my-webserver"}}'.
If the Endpoints are for a headless service, then A records will be created with the format <hostname>.<service name>.<pod namespace>.svc.<cluster domain>
For the example json, if endpoints are for a headless service named "bar", and one of the endpoints has IP "10.245.1.6", then a A record will be created with the name "my-webserver.bar.my-namespace.svc.cluster.local" and the A record lookup would return "10.245.1.6".
This endpoints annotation generally does not need to be specified by end-users, but can used by the internal service controller to deliver the aforementioned feature.

With v1.3, The Endpoints object can specify the `hostname` for any endpoint, along with its IP. The hostname field takes precedence over the hostname value
that might have been specified via the `endpoints.beta.kubernetes.io/hostnames-map` annotation.

With v1.3, the following annotations are deprecated: `pod.beta.kubernetes.io/hostname`, `pod.beta.kubernetes.io/subdomain`, `endpoints.beta.kubernetes.io/hostnames-map`

## How do I find the DNS server?
The DNS server itself runs as a Kubernetes Service. This gives it a stable IP
address. When you run the SkyDNS service, you want to assign a static IP to use for
Expand Down
51 changes: 37 additions & 14 deletions cluster/addons/dns/kube2sky/kube2sky.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,28 +161,27 @@ func getSkyMsg(ip string, port int) *skymsg.Service {
}

func (ks *kube2sky) generateRecordsForHeadlessService(subdomain string, e *kapi.Endpoints, svc *kapi.Service) error {
glog.V(4).Infof("Endpoints Annotations: %v", e.Annotations)
// TODO: remove this after v1.4 is released and the old annotations are EOL
podHostnames, err := getPodHostnamesFromAnnotation(e.Annotations)
if err != nil {
return err
}
for idx := range e.Subsets {
for subIdx := range e.Subsets[idx].Addresses {
endpointIP := e.Subsets[idx].Addresses[subIdx].IP
address := &e.Subsets[idx].Addresses[subIdx]
endpointIP := address.IP
b, err := json.Marshal(getSkyMsg(endpointIP, 0))
if err != nil {
return err
}
recordValue := string(b)
recordLabel := getHash(recordValue)
if serializedPodHostnames := e.Annotations[endpoints.PodHostnamesAnnotation]; len(serializedPodHostnames) > 0 {
podHostnames := map[string]endpoints.HostRecord{}
err := json.Unmarshal([]byte(serializedPodHostnames), &podHostnames)
if err != nil {
return err
}
if hostRecord, exists := podHostnames[string(endpointIP)]; exists {
if validation.IsDNS1123Label(hostRecord.HostName) {
recordLabel = hostRecord.HostName
}
}
var recordLabel string
if hostLabel, exists := getHostname(address, podHostnames); exists {
recordLabel = hostLabel
} else {
recordLabel = getHash(recordValue)
}

recordKey := buildDNSNameString(subdomain, recordLabel)

glog.V(2).Infof("Setting DNS record: %v -> %q\n", recordKey, recordValue)
Expand All @@ -205,6 +204,30 @@ func (ks *kube2sky) generateRecordsForHeadlessService(subdomain string, e *kapi.
return nil
}

func getHostname(address *kapi.EndpointAddress, podHostnames map[string]endpoints.HostRecord) (string, bool) {
if len(address.Hostname) > 0 {
return address.Hostname, true
}
if hostRecord, exists := podHostnames[address.IP]; exists && validation.IsDNS1123Label(hostRecord.HostName) {
return hostRecord.HostName, true
}
return "", false
}

func getPodHostnamesFromAnnotation(annotations map[string]string) (map[string]endpoints.HostRecord, error) {
hostnames := map[string]endpoints.HostRecord{}

if annotations != nil {
if serializedHostnames, exists := annotations[endpoints.PodHostnamesAnnotation]; exists && len(serializedHostnames) > 0 {
err := json.Unmarshal([]byte(serializedHostnames), &hostnames)
if err != nil {
return nil, err
}
}
}
return hostnames, nil
}

func (ks *kube2sky) getServiceFromEndpoints(e *kapi.Endpoints) (*kapi.Service, error) {
key, err := kcache.MetaNamespaceKeyFunc(e)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cluster/addons/dns/skydns-rc.yaml.in
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ spec:
- name: etcd-storage
mountPath: /var/etcd/data
- name: kube2sky
image: gcr.io/google_containers/kube2sky:1.14
image: gcr.io/google_containers/kube2sky-amd64:1.15
resources:
# TODO: Set memory limits when we've profiled the container for large
# clusters, then set request = limit to keep this container in
Expand Down
2 changes: 1 addition & 1 deletion docs/api-reference/autoscaling/v1/definitions.html
Original file line number Diff line number Diff line change
Expand Up @@ -1244,7 +1244,7 @@ <h3 id="_any">any</h3>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-04-15 01:05:48 UTC
Last updated 2016-04-27 19:28:56 UTC
</div>
</div>
</body>
Expand Down
2 changes: 1 addition & 1 deletion docs/api-reference/autoscaling/v1/operations.html
Original file line number Diff line number Diff line change
Expand Up @@ -2122,7 +2122,7 @@ <h4 id="_tags_13">Tags</h4>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-04-22 03:24:34 UTC
Last updated 2016-04-27 19:28:56 UTC
</div>
</div>
</body>
Expand Down
16 changes: 15 additions & 1 deletion docs/api-reference/batch/v1/definitions.html
Original file line number Diff line number Diff line change
Expand Up @@ -3544,6 +3544,20 @@ <h3 id="_v1_podspec">v1.PodSpec</h3>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_localobjectreference">v1.LocalObjectReference</a> array</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">hostname</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specifies the hostname of the Pod If not specified, the pod&#8217;s hostname will be set to a system-defined value.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">subdomain</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If specified, the fully qualified Pod hostname will be "&lt;hostname&gt;.&lt;subdomain&gt;.&lt;pod namespace&gt;.svc.&lt;cluster domain&gt;". If not specified, the pod will not have a domainname at all.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>

Expand Down Expand Up @@ -3882,7 +3896,7 @@ <h3 id="_any">any</h3>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-04-15 09:27:17 UTC
Last updated 2016-04-27 19:28:50 UTC
</div>
</div>
</body>
Expand Down
2 changes: 1 addition & 1 deletion docs/api-reference/batch/v1/operations.html
Original file line number Diff line number Diff line change
Expand Up @@ -2122,7 +2122,7 @@ <h4 id="_tags_13">Tags</h4>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-04-22 03:24:25 UTC
Last updated 2016-04-27 19:28:50 UTC
</div>
</div>
</body>
Expand Down
16 changes: 15 additions & 1 deletion docs/api-reference/extensions/v1beta1/definitions.html
Original file line number Diff line number Diff line change
Expand Up @@ -3403,6 +3403,20 @@ <h3 id="_v1_podspec">v1.PodSpec</h3>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_localobjectreference">v1.LocalObjectReference</a> array</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">hostname</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specifies the hostname of the Pod If not specified, the pod&#8217;s hostname will be set to a system-defined value.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">subdomain</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If specified, the fully qualified Pod hostname will be "&lt;hostname&gt;.&lt;subdomain&gt;.&lt;pod namespace&gt;.svc.&lt;cluster domain&gt;". If not specified, the pod will not have a domainname at all.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>

Expand Down Expand Up @@ -5872,7 +5886,7 @@ <h3 id="_any">any</h3>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-04-15 09:26:56 UTC
Last updated 2016-04-27 19:28:44 UTC
</div>
</div>
</body>
Expand Down
2 changes: 1 addition & 1 deletion docs/api-reference/extensions/v1beta1/operations.html
Original file line number Diff line number Diff line change
Expand Up @@ -13309,7 +13309,7 @@ <h4 id="_tags_94">Tags</h4>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-04-22 03:24:17 UTC
Last updated 2016-04-27 19:28:44 UTC
</div>
</div>
</body>
Expand Down
23 changes: 22 additions & 1 deletion docs/api-reference/v1/definitions.html
Original file line number Diff line number Diff line change
Expand Up @@ -4145,6 +4145,20 @@ <h3 id="_v1_podspec">v1.PodSpec</h3>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_localobjectreference">v1.LocalObjectReference</a> array</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">hostname</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specifies the hostname of the Pod If not specified, the pod&#8217;s hostname will be set to a system-defined value.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">subdomain</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If specified, the fully qualified Pod hostname will be "&lt;hostname&gt;.&lt;subdomain&gt;.&lt;pod namespace&gt;.svc.&lt;cluster domain&gt;". If not specified, the pod will not have a domainname at all.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>

Expand Down Expand Up @@ -7687,6 +7701,13 @@ <h3 id="_v1_endpointaddress">v1.EndpointAddress</h3>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">hostname</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The Hostname of this endpoint</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">targetRef</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Reference to object providing the endpoint.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
Expand Down Expand Up @@ -7742,7 +7763,7 @@ <h3 id="_any">any</h3>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-04-21 02:45:03 UTC
Last updated 2016-04-27 19:28:36 UTC
</div>
</div>
</body>
Expand Down
2 changes: 1 addition & 1 deletion docs/api-reference/v1/operations.html
Original file line number Diff line number Diff line change
Expand Up @@ -30700,7 +30700,7 @@ <h4 id="_tags_230">Tags</h4>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-04-22 03:24:07 UTC
Last updated 2016-04-27 19:28:36 UTC
</div>
</div>
</body>
Expand Down
3 changes: 3 additions & 0 deletions pkg/api/deep_copy_generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,7 @@ func DeepCopy_api_EmptyDirVolumeSource(in EmptyDirVolumeSource, out *EmptyDirVol

func DeepCopy_api_EndpointAddress(in EndpointAddress, out *EndpointAddress, c *conversion.Cloner) error {
out.IP = in.IP
out.Hostname = in.Hostname
if in.TargetRef != nil {
in, out := in.TargetRef, &out.TargetRef
*out = new(ObjectReference)
Expand Down Expand Up @@ -2158,6 +2159,8 @@ func DeepCopy_api_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error
} else {
out.ImagePullSecrets = nil
}
out.Hostname = in.Hostname
out.Subdomain = in.Subdomain
return nil
}

Expand Down
2 changes: 2 additions & 0 deletions pkg/api/endpoints/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ import (
)

const (
// TODO: to be deleted after v1.3 is released
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also TODO the HostRecord struct

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

// Its value is the json representation of map[string(IP)][HostRecord]
// example: '{"10.245.1.6":{"HostName":"my-webserver"}}'
PodHostnamesAnnotation = "endpoints.beta.kubernetes.io/hostnames-map"
)

// TODO: to be deleted after v1.3 is released
type HostRecord struct {
HostName string
}
Expand Down
Loading