Skip to content

Commit

Permalink
Merge pull request #24362 from ArtfulCoder/hostname-field
Browse files Browse the repository at this point in the history
Automatic merge from submit-queue

Promote Pod Hostname & Subdomain to fields (were annotations)

Deprecating the podHostName, subdomain and PodHostnames annotations and created corresponding new fields for them on PodSpec and Endpoints types.

Annotation doc: #22564
Annotation code: #20688
  • Loading branch information
k8s-merge-robot committed Apr 29, 2016
2 parents b16fb60 + 8a3ed48 commit ad67363
Show file tree
Hide file tree
Showing 42 changed files with 979 additions and 343 deletions.
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
// 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

0 comments on commit ad67363

Please sign in to comment.