Add ExternalName to ServiceSpec

ExternalName allows kubedns to return CNAME records for external
services. No proxying is involved.

See original issue at
https://github.com/kubernetes/kubernetes/issues/13748

Feature tracking at
https://github.com/kubernetes/features/issues/33
pull/6/head
Rudi Chiarito 2016-08-19 09:09:14 -07:00
parent b6d4462f01
commit 88fdb96bfb
15 changed files with 23107 additions and 22831 deletions

View File

@ -19310,15 +19310,15 @@
},
"selector": {
"type": "object",
"description": "This service will route traffic to pods having labels matching this selector. Label keys and values that must match in order to receive traffic for this service. If not specified, endpoints must be manually specified and the system will not automatically manage them. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview"
"description": "Route service traffic to pods with label keys and values matching this selector. If empty or not present, the service is assumed to have an external process managing its endpoints, which Kubernetes will not modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if type is ExternalName. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview"
},
"clusterIP": {
"type": "string",
"description": "ClusterIP is usually assigned by the master and is the IP address of the service. If specified, it will be allocated to the service if it is unused or else creation of the service will fail. Valid values are None, empty string (\"\"), or a valid IP address. 'None' can be specified for a headless service when proxying is not required. Cannot be updated. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies"
"description": "clusterIP is the IP address of the service and is usually assigned randomly by the master. If an address is specified manually and is not in use by others, it will be allocated to the service; otherwise, creation of the service will fail. This field can not be changed through updates. Valid values are \"None\", empty string (\"\"), or a valid IP address. \"None\" can be specified for headless services when proxying is not required. Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if type is ExternalName. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies"
},
"type": {
"type": "string",
"description": "Type of exposed service. Must be ClusterIP, NodePort, or LoadBalancer. Defaults to ClusterIP. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#external-services"
"description": "type determines how the Service is exposed. Defaults to ClusterIP. Valid options are ExternalName, ClusterIP, NodePort, and LoadBalancer. \"ExternalName\" maps to the specified externalName. \"ClusterIP\" allocates a cluster-internal IP address for load-balancing to endpoints. Endpoints are determined by the selector or if that is not specified, by manual construction of an Endpoints object. If clusterIP is \"None\", no virtual IP is allocated and the endpoints are published as a set of endpoints rather than a stable IP. \"NodePort\" builds on ClusterIP and allocates a port on every node which routes to the clusterIP. \"LoadBalancer\" builds on NodePort and creates an external load-balancer (if supported in the current cloud) which routes to the clusterIP. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview"
},
"externalIPs": {
"type": "array",
@ -19348,6 +19348,10 @@
"type": "string"
},
"description": "If specified and supported by the platform, this will restrict traffic through the cloud-provider load-balancer will be restricted to the specified client IPs. This field will be ignored if the cloud-provider does not support the feature.\" More info: http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md"
},
"externalName": {
"type": "string",
"description": "externalName is the external reference that kubedns or equivalent will return as a CNAME record for this service. No proxying will be involved. Must be a valid DNS name and requires Type to be ExternalName."
}
}
},

View File

@ -8003,21 +8003,21 @@ The resulting set of endpoints can be viewed as:<br>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">selector</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">This service will route traffic to pods having labels matching this selector. Label keys and values that must match in order to receive traffic for this service. If not specified, endpoints must be manually specified and the system will not automatically manage them. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview">http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Route service traffic to pods with label keys and values matching this selector. If empty or not present, the service is assumed to have an external process managing its endpoints, which Kubernetes will not modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if type is ExternalName. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview">http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview</a></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">object</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">clusterIP</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">ClusterIP is usually assigned by the master and is the IP address of the service. If specified, it will be allocated to the service if it is unused or else creation of the service will fail. Valid values are None, empty string (""), or a valid IP address. <em>None</em> can be specified for a headless service when proxying is not required. Cannot be updated. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies">http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">clusterIP is the IP address of the service and is usually assigned randomly by the master. If an address is specified manually and is not in use by others, it will be allocated to the service; otherwise, creation of the service will fail. This field can not be changed through updates. Valid values are "None", empty string (""), or a valid IP address. "None" can be specified for headless services when proxying is not required. Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if type is ExternalName. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies">http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies</a></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">type</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Type of exposed service. Must be ClusterIP, NodePort, or LoadBalancer. Defaults to ClusterIP. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/services.md#external-services">http://releases.k8s.io/HEAD/docs/user-guide/services.md#external-services</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">type determines how the Service is exposed. Defaults to ClusterIP. Valid options are ExternalName, ClusterIP, NodePort, and LoadBalancer. "ExternalName" maps to the specified externalName. "ClusterIP" allocates a cluster-internal IP address for load-balancing to endpoints. Endpoints are determined by the selector or if that is not specified, by manual construction of an Endpoints object. If clusterIP is "None", no virtual IP is allocated and the endpoints are published as a set of endpoints rather than a stable IP. "NodePort" builds on ClusterIP and allocates a port on every node which routes to the clusterIP. "LoadBalancer" builds on NodePort and creates an external load-balancer (if supported in the current cloud) which routes to the clusterIP. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview">http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview</a></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>
@ -8057,6 +8057,13 @@ The resulting set of endpoints can be viewed as:<br>
<td class="tableblock halign-left valign-top"><p class="tableblock">string array</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">externalName</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">externalName is the external reference that kubedns or equivalent will return as a CNAME record for this service. No proxying will be involved. Must be a valid DNS name and requires Type to be ExternalName.</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>
@ -8278,7 +8285,7 @@ The resulting set of endpoints can be viewed as:<br>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-08-18 14:23:04 UTC
Last updated 2016-08-19 15:53:53 UTC
</div>
</div>
</body>

View File

@ -222,6 +222,10 @@ func IsServiceIPSet(service *Service) bool {
// this function aims to check if the service's cluster IP is requested or not
func IsServiceIPRequested(service *Service) bool {
// ExternalName services are CNAME aliases to external ones. Ignore the IP.
if service.Spec.Type == ServiceTypeExternalName {
return false
}
return service.Spec.ClusterIP == ""
}

File diff suppressed because it is too large Load Diff

View File

@ -1761,6 +1761,11 @@ const (
// external load balancer (if the cloud provider supports it), in addition
// to 'NodePort' type.
ServiceTypeLoadBalancer ServiceType = "LoadBalancer"
// ServiceTypeExternalName means a service consists of only a reference to
// an external name that kubedns or equivalent will return as a CNAME
// record, with no exposing or proxying of any pods involved.
ServiceTypeExternalName ServiceType = "ExternalName"
)
// ServiceStatus represents the current status of a service
@ -1791,24 +1796,49 @@ type LoadBalancerIngress struct {
// ServiceSpec describes the attributes that a user creates on a service
type ServiceSpec struct {
// Type determines how the service will be exposed. Valid options: ClusterIP, NodePort, LoadBalancer
// Type determines how the Service is exposed. Defaults to ClusterIP. Valid
// options are ExternalName, ClusterIP, NodePort, and LoadBalancer.
// "ExternalName" maps to the specified externalName.
// "ClusterIP" allocates a cluster-internal IP address for load-balancing to
// endpoints. Endpoints are determined by the selector or if that is not
// specified, by manual construction of an Endpoints object. If clusterIP is
// "None", no virtual IP is allocated and the endpoints are published as a
// set of endpoints rather than a stable IP.
// "NodePort" builds on ClusterIP and allocates a port on every node which
// routes to the clusterIP.
// "LoadBalancer" builds on NodePort and creates an
// external load-balancer (if supported in the current cloud) which routes
// to the clusterIP.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview
Type ServiceType `json:"type,omitempty"`
// Required: The list of ports that are exposed by this service.
Ports []ServicePort `json:"ports"`
// This service will route traffic to pods having labels matching this selector. If empty or not present,
// the service is assumed to have endpoints set by an external process and Kubernetes will not modify
// those endpoints.
// Route service traffic to pods with label keys and values matching this
// selector. If empty or not present, the service is assumed to have an
// external process managing its endpoints, which Kubernetes will not
// modify. Only applies to types ClusterIP, NodePort, and LoadBalancer.
// Ignored if type is ExternalName.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview
Selector map[string]string `json:"selector"`
// ClusterIP is usually assigned by the master. If specified by the user
// we will try to respect it or else fail the request. This field can
// not be changed by updates.
// Valid values are None, empty string (""), or a valid IP address
// None can be specified for headless services when proxying is not required
// ClusterIP is the IP address of the service and is usually assigned
// randomly by the master. If an address is specified manually and is not in
// use by others, it will be allocated to the service; otherwise, creation
// of the service will fail. This field can not be changed through updates.
// Valid values are "None", empty string (""), or a valid IP address. "None"
// can be specified for headless services when proxying is not required.
// Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if
// type is ExternalName.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies
ClusterIP string `json:"clusterIP,omitempty"`
// ExternalName is the external reference that kubedns or equivalent will
// return as a CNAME record for this service. No proxying will be involved.
// Must be a valid DNS name and requires Type to be ExternalName.
ExternalName string
// ExternalIPs are used by external load balancers, or can be set by
// users to handle external traffic that arrives at a node.
ExternalIPs []string `json:"externalIPs,omitempty"`

File diff suppressed because it is too large Load Diff

View File

@ -2779,24 +2779,39 @@ message ServiceSpec {
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies
repeated ServicePort ports = 1;
// This service will route traffic to pods having labels matching this selector.
// Label keys and values that must match in order to receive traffic for this service.
// If not specified, endpoints must be manually specified and the system will not automatically manage them.
// Route service traffic to pods with label keys and values matching this
// selector. If empty or not present, the service is assumed to have an
// external process managing its endpoints, which Kubernetes will not
// modify. Only applies to types ClusterIP, NodePort, and LoadBalancer.
// Ignored if type is ExternalName.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview
map<string, string> selector = 2;
// ClusterIP is usually assigned by the master and is the IP address of the service.
// If specified, it will be allocated to the service if it is unused
// or else creation of the service will fail.
// Valid values are None, empty string (""), or a valid IP address.
// 'None' can be specified for a headless service when proxying is not required.
// Cannot be updated.
// clusterIP is the IP address of the service and is usually assigned
// randomly by the master. If an address is specified manually and is not in
// use by others, it will be allocated to the service; otherwise, creation
// of the service will fail. This field can not be changed through updates.
// Valid values are "None", empty string (""), or a valid IP address. "None"
// can be specified for headless services when proxying is not required.
// Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if
// type is ExternalName.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies
optional string clusterIP = 3;
// Type of exposed service. Must be ClusterIP, NodePort, or LoadBalancer.
// Defaults to ClusterIP.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#external-services
// type determines how the Service is exposed. Defaults to ClusterIP. Valid
// options are ExternalName, ClusterIP, NodePort, and LoadBalancer.
// "ExternalName" maps to the specified externalName.
// "ClusterIP" allocates a cluster-internal IP address for load-balancing to
// endpoints. Endpoints are determined by the selector or if that is not
// specified, by manual construction of an Endpoints object. If clusterIP is
// "None", no virtual IP is allocated and the endpoints are published as a
// set of endpoints rather than a stable IP.
// "NodePort" builds on ClusterIP and allocates a port on every node which
// routes to the clusterIP.
// "LoadBalancer" builds on NodePort and creates an
// external load-balancer (if supported in the current cloud) which routes
// to the clusterIP.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview
optional string type = 4;
// externalIPs is a list of IP addresses for which nodes in the cluster
@ -2835,6 +2850,11 @@ message ServiceSpec {
// cloud-provider does not support the feature."
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md
repeated string loadBalancerSourceRanges = 9;
// externalName is the external reference that kubedns or equivalent will
// return as a CNAME record for this service. No proxying will be involved.
// Must be a valid DNS name and requires Type to be ExternalName.
optional string externalName = 10;
}
// ServiceStatus represents the current status of a service.

File diff suppressed because it is too large Load Diff

View File

@ -2066,6 +2066,11 @@ const (
// external load balancer (if the cloud provider supports it), in addition
// to 'NodePort' type.
ServiceTypeLoadBalancer ServiceType = "LoadBalancer"
// ServiceTypeExternalName means a service consists of only a reference to
// an external name that kubedns or equivalent will return as a CNAME
// record, with no exposing or proxying of any pods involved.
ServiceTypeExternalName ServiceType = "ExternalName"
)
// ServiceStatus represents the current status of a service.
@ -2100,24 +2105,39 @@ type ServiceSpec struct {
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies
Ports []ServicePort `json:"ports" patchStrategy:"merge" patchMergeKey:"port" protobuf:"bytes,1,rep,name=ports"`
// This service will route traffic to pods having labels matching this selector.
// Label keys and values that must match in order to receive traffic for this service.
// If not specified, endpoints must be manually specified and the system will not automatically manage them.
// Route service traffic to pods with label keys and values matching this
// selector. If empty or not present, the service is assumed to have an
// external process managing its endpoints, which Kubernetes will not
// modify. Only applies to types ClusterIP, NodePort, and LoadBalancer.
// Ignored if type is ExternalName.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview
Selector map[string]string `json:"selector,omitempty" protobuf:"bytes,2,rep,name=selector"`
// ClusterIP is usually assigned by the master and is the IP address of the service.
// If specified, it will be allocated to the service if it is unused
// or else creation of the service will fail.
// Valid values are None, empty string (""), or a valid IP address.
// 'None' can be specified for a headless service when proxying is not required.
// Cannot be updated.
// clusterIP is the IP address of the service and is usually assigned
// randomly by the master. If an address is specified manually and is not in
// use by others, it will be allocated to the service; otherwise, creation
// of the service will fail. This field can not be changed through updates.
// Valid values are "None", empty string (""), or a valid IP address. "None"
// can be specified for headless services when proxying is not required.
// Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if
// type is ExternalName.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies
ClusterIP string `json:"clusterIP,omitempty" protobuf:"bytes,3,opt,name=clusterIP"`
// Type of exposed service. Must be ClusterIP, NodePort, or LoadBalancer.
// Defaults to ClusterIP.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#external-services
// type determines how the Service is exposed. Defaults to ClusterIP. Valid
// options are ExternalName, ClusterIP, NodePort, and LoadBalancer.
// "ExternalName" maps to the specified externalName.
// "ClusterIP" allocates a cluster-internal IP address for load-balancing to
// endpoints. Endpoints are determined by the selector or if that is not
// specified, by manual construction of an Endpoints object. If clusterIP is
// "None", no virtual IP is allocated and the endpoints are published as a
// set of endpoints rather than a stable IP.
// "NodePort" builds on ClusterIP and allocates a port on every node which
// routes to the clusterIP.
// "LoadBalancer" builds on NodePort and creates an
// external load-balancer (if supported in the current cloud) which routes
// to the clusterIP.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview
Type ServiceType `json:"type,omitempty" protobuf:"bytes,4,opt,name=type,casttype=ServiceType"`
// externalIPs is a list of IP addresses for which nodes in the cluster
@ -2156,6 +2176,11 @@ type ServiceSpec struct {
// cloud-provider does not support the feature."
// More info: http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md
LoadBalancerSourceRanges []string `json:"loadBalancerSourceRanges,omitempty" protobuf:"bytes,9,opt,name=loadBalancerSourceRanges"`
// externalName is the external reference that kubedns or equivalent will
// return as a CNAME record for this service. No proxying will be involved.
// Must be a valid DNS name and requires Type to be ExternalName.
ExternalName string `json:"externalName,omitempty" protobuf:"bytes,10,opt,name=externalName"`
}
// ServicePort contains information on service's port.

View File

@ -1665,14 +1665,15 @@ func (ServiceProxyOptions) SwaggerDoc() map[string]string {
var map_ServiceSpec = map[string]string{
"": "ServiceSpec describes the attributes that a user creates on a service.",
"ports": "The list of ports that are exposed by this service. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies",
"selector": "This service will route traffic to pods having labels matching this selector. Label keys and values that must match in order to receive traffic for this service. If not specified, endpoints must be manually specified and the system will not automatically manage them. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview",
"clusterIP": "ClusterIP is usually assigned by the master and is the IP address of the service. If specified, it will be allocated to the service if it is unused or else creation of the service will fail. Valid values are None, empty string (\"\"), or a valid IP address. 'None' can be specified for a headless service when proxying is not required. Cannot be updated. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies",
"type": "Type of exposed service. Must be ClusterIP, NodePort, or LoadBalancer. Defaults to ClusterIP. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#external-services",
"selector": "Route service traffic to pods with label keys and values matching this selector. If empty or not present, the service is assumed to have an external process managing its endpoints, which Kubernetes will not modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if type is ExternalName. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview",
"clusterIP": "clusterIP is the IP address of the service and is usually assigned randomly by the master. If an address is specified manually and is not in use by others, it will be allocated to the service; otherwise, creation of the service will fail. This field can not be changed through updates. Valid values are \"None\", empty string (\"\"), or a valid IP address. \"None\" can be specified for headless services when proxying is not required. Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if type is ExternalName. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies",
"type": "type determines how the Service is exposed. Defaults to ClusterIP. Valid options are ExternalName, ClusterIP, NodePort, and LoadBalancer. \"ExternalName\" maps to the specified externalName. \"ClusterIP\" allocates a cluster-internal IP address for load-balancing to endpoints. Endpoints are determined by the selector or if that is not specified, by manual construction of an Endpoints object. If clusterIP is \"None\", no virtual IP is allocated and the endpoints are published as a set of endpoints rather than a stable IP. \"NodePort\" builds on ClusterIP and allocates a port on every node which routes to the clusterIP. \"LoadBalancer\" builds on NodePort and creates an external load-balancer (if supported in the current cloud) which routes to the clusterIP. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview",
"externalIPs": "externalIPs is a list of IP addresses for which nodes in the cluster will also accept traffic for this service. These IPs are not managed by Kubernetes. The user is responsible for ensuring that traffic arrives at a node with this IP. A common example is external load-balancers that are not part of the Kubernetes system. A previous form of this functionality exists as the deprecatedPublicIPs field. When using this field, callers should also clear the deprecatedPublicIPs field.",
"deprecatedPublicIPs": "deprecatedPublicIPs is deprecated and replaced by the externalIPs field with almost the exact same semantics. This field is retained in the v1 API for compatibility until at least 8/20/2016. It will be removed from any new API revisions. If both deprecatedPublicIPs *and* externalIPs are set, deprecatedPublicIPs is used.",
"sessionAffinity": "Supports \"ClientIP\" and \"None\". Used to maintain session affinity. Enable client IP based session affinity. Must be ClientIP or None. Defaults to None. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies",
"loadBalancerIP": "Only applies to Service Type: LoadBalancer LoadBalancer will get created with the IP specified in this field. This feature depends on whether the underlying cloud-provider supports specifying the loadBalancerIP when a load balancer is created. This field will be ignored if the cloud-provider does not support the feature.",
"loadBalancerSourceRanges": "If specified and supported by the platform, this will restrict traffic through the cloud-provider load-balancer will be restricted to the specified client IPs. This field will be ignored if the cloud-provider does not support the feature.\" More info: http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md",
"externalName": "externalName is the external reference that kubedns or equivalent will return as a CNAME record for this service. No proxying will be involved. Must be a valid DNS name and requires Type to be ExternalName.",
}
func (ServiceSpec) SwaggerDoc() map[string]string {

View File

@ -6443,6 +6443,7 @@ func autoConvert_v1_ServiceSpec_To_api_ServiceSpec(in *ServiceSpec, out *api.Ser
out.SessionAffinity = api.ServiceAffinity(in.SessionAffinity)
out.LoadBalancerIP = in.LoadBalancerIP
out.LoadBalancerSourceRanges = in.LoadBalancerSourceRanges
out.ExternalName = in.ExternalName
return nil
}
@ -6461,6 +6462,7 @@ func autoConvert_api_ServiceSpec_To_v1_ServiceSpec(in *api.ServiceSpec, out *Ser
}
out.Selector = in.Selector
out.ClusterIP = in.ClusterIP
out.ExternalName = in.ExternalName
out.ExternalIPs = in.ExternalIPs
out.LoadBalancerIP = in.LoadBalancerIP
out.SessionAffinity = ServiceAffinity(in.SessionAffinity)

View File

@ -3387,6 +3387,7 @@ func DeepCopy_v1_ServiceSpec(in interface{}, out interface{}, c *conversion.Clon
} else {
out.LoadBalancerSourceRanges = nil
}
out.ExternalName = in.ExternalName
return nil
}
}

View File

@ -101,6 +101,15 @@ func ValidateDNS1123Label(value string, fldPath *field.Path) field.ErrorList {
return allErrs
}
// ValidateDNS1123Subdomain validates that a name is a proper DNS subdomain.
func ValidateDNS1123Subdomain(value string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
for _, msg := range validation.IsDNS1123Subdomain(value) {
allErrs = append(allErrs, field.Invalid(fldPath, value, msg))
}
return allErrs
}
func ValidatePodSpecificAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if annotations[api.AffinityAnnotationKey] != "" {
@ -2190,17 +2199,19 @@ func ValidatePodTemplateUpdate(newPod, oldPod *api.PodTemplate) field.ErrorList
var supportedSessionAffinityType = sets.NewString(string(api.ServiceAffinityClientIP), string(api.ServiceAffinityNone))
var supportedServiceType = sets.NewString(string(api.ServiceTypeClusterIP), string(api.ServiceTypeNodePort),
string(api.ServiceTypeLoadBalancer))
string(api.ServiceTypeLoadBalancer), string(api.ServiceTypeExternalName))
// ValidateService tests if required fields in the service are set.
func ValidateService(service *api.Service) field.ErrorList {
allErrs := ValidateObjectMeta(&service.ObjectMeta, true, ValidateServiceName, field.NewPath("metadata"))
specPath := field.NewPath("spec")
if len(service.Spec.Ports) == 0 && service.Spec.ClusterIP != api.ClusterIPNone {
isHeadlessService := service.Spec.ClusterIP == api.ClusterIPNone
if len(service.Spec.Ports) == 0 && !isHeadlessService && service.Spec.Type != api.ServiceTypeExternalName {
allErrs = append(allErrs, field.Required(specPath.Child("ports"), ""))
}
if service.Spec.Type == api.ServiceTypeLoadBalancer {
switch service.Spec.Type {
case api.ServiceTypeLoadBalancer:
for ix := range service.Spec.Ports {
port := &service.Spec.Ports[ix]
// This is a workaround for broken cloud environments that
@ -2211,9 +2222,17 @@ func ValidateService(service *api.Service) field.ErrorList {
allErrs = append(allErrs, field.Invalid(portPath, port.Port, "may not expose port 10250 externally since it is used by kubelet"))
}
}
case api.ServiceTypeExternalName:
if service.Spec.ClusterIP != "" {
allErrs = append(allErrs, field.Invalid(specPath.Child("clusterIP"), service.Spec.ClusterIP, "must be empty for ExternalName services"))
}
if len(service.Spec.ExternalName) > 0 {
allErrs = append(allErrs, ValidateDNS1123Subdomain(service.Spec.ExternalName, specPath.Child("externalName"))...)
} else {
allErrs = append(allErrs, field.Required(specPath.Child("externalName"), ""))
}
}
isHeadlessService := service.Spec.ClusterIP == api.ClusterIPNone
allPortNames := sets.String{}
portsPath := specPath.Child("ports")
for i := range service.Spec.Ports {

View File

@ -4982,6 +4982,42 @@ func TestValidateService(t *testing.T) {
},
numErrs: 1,
},
{
name: "valid ExternalName",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeExternalName
s.Spec.ClusterIP = ""
s.Spec.ExternalName = "foo.bar.example.com"
},
numErrs: 0,
},
{
name: "invalid ExternalName clusterIP (valid IP)",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeExternalName
s.Spec.ClusterIP = "1.2.3.4"
s.Spec.ExternalName = "foo.bar.example.com"
},
numErrs: 1,
},
{
name: "invalid ExternalName clusterIP (None)",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeExternalName
s.Spec.ClusterIP = "None"
s.Spec.ExternalName = "foo.bar.example.com"
},
numErrs: 1,
},
{
name: "invalid ExternalName (not a DNS name)",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeExternalName
s.Spec.ClusterIP = ""
s.Spec.ExternalName = "-123"
},
numErrs: 1,
},
}
for _, tc := range testCases {

View File

@ -3406,6 +3406,7 @@ func DeepCopy_api_ServiceSpec(in interface{}, out interface{}, c *conversion.Clo
out.Selector = nil
}
out.ClusterIP = in.ClusterIP
out.ExternalName = in.ExternalName
if in.ExternalIPs != nil {
in, out := &in.ExternalIPs, &out.ExternalIPs
*out = make([]string, len(*in))