spring-cloud-kubernetes icon indicating copy to clipboard operation
spring-cloud-kubernetes copied to clipboard

Add support for ExternalName service type

Open ArtyomGabeev opened this issue 5 years ago • 4 comments

https://github.com/spring-cloud/spring-cloud-kubernetes/issues/489

ArtyomGabeev avatar Jan 08 '20 13:01 ArtyomGabeev

Having a service:

apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.service.example.com

We should be able to resolve service call http://my-service/doCall into http://my.service.example.com/doCall

Notes: Because there is not information about secure/port, I left them false/0.

So it's up to client to specify schema http vs https, e.g: https://my-service/doCall should become https://my.service.example.com/doCall

Regrading port, I've checked LB Utils and ports will be 80/443.

ArtyomGabeev avatar Jan 08 '20 13:01 ArtyomGabeev

I've achieved that by changing the KubernetesServicesServerList.

        @Override
	public List<Server> getUpdatedListOfServers() {
		final List<Server> result = new ArrayList<>();
		final Service service = StringUtils.isNotBlank(this.namespace) ?
				this.client.services().inNamespace(this.namespace).withName(this.serviceId).get() :
				this.client.services().withName(this.serviceId).get();

		if ( service != null ) {
			if ( LOG.isDebugEnabled() ) {
				LOG.debug("Found Service[" + service.getMetadata().getName() + "]");
			}

			final String host;
			//is it a external service?
			if ( service.getSpec().getExternalName() != null ) {
				host = service.getSpec().getExternalName();
			}
			//else, it will use the internal domain
			else {
				host = this.concatServiceFQDN(service);
			}

			if ( service.getSpec().getPorts().isEmpty() ) {
				result.add(new Server(host, 80));
			}
			else if ( service.getSpec().getPorts().size() == 1 ) {
				result.add(new Server(host, service.getSpec().getPorts().get(0).getPort()));
			}
			else {
				for ( ServicePort servicePort : service.getSpec().getPorts() ) {
					if ( Utils.isNotNullOrEmpty(this.portName) || this.portName.endsWith(servicePort.getName()) ) {
						result.add(new Server(host, servicePort.getPort()));
					}
				}
			}
		}

		if ( result.isEmpty() ) {
			LOG.warn(String.format("Did not find any service in ribbon in namespace [%s] for name [%s] and portName [%s]", this.namespace, this.serviceId, this.portName));
		}
		return result;
	}

digows avatar Jan 09 '20 13:01 digows

KubernetesServicesServerList is used by Ribbon, which is in maintenance mode.

Proposed changes should work both for spring cloud load balancer as well.

ArtyomGabeev avatar Jan 14 '20 09:01 ArtyomGabeev

Hey, just wondering if anybody could/would comment on if there is intention to merge this at some point? Just curious as we have a scenario where we really need ExternalName services to work with Ribbon as well.

mindcrime avatar Jul 22 '20 14:07 mindcrime

@ryanjbaxter this can be closed now. thank you.

wind57 avatar Mar 09 '23 08:03 wind57