Change:
From a user: I'm trying to expose multiple services on the same port in a GKE Kubernetes 0.8.1 cluster. My question is similar to this SO post but it is not solved by 0.5.x+ I've deployed a service (hellogo) with an external load balancer which works correctly. Deploying another service (pynote) which is extremely similar fails { "apiVersion": "v1beta1", "kind": "Service", "id": "pynote-service", "selector": { "name": "pynote" }, "containerPort": 8080, "protocol": "TCP", "port": 80, "createExternalLoadBalancer": true } gcloud preview container services --cluster athena --zone $ZONE create --config-file pynote- ERROR: F0124 19:42:27. ] service "pynote-service" is invalid: service "pynote-service" cannot be updated: port: 80 is already in use If I delete the other service and start pynote first, the service and load balancer are setup correctly, but the other service cannot be deployed with the same error. I believe the current proxying design is that service routing occurs via proxies on every node which are part of the target pool. Every service gets its own IP. Putting up two external services on port 80 on GKE should allocate two load balancers, each with a fixed IP address. This design does not preclude exposing services on the same port as each service is accessed through a separate external IP. Furthermore, Kubernetes itself runs a service (kubernetes-ro) on port 80 which coexists with my first service nicely. At the very least, the message is misleading. There is no requirement that the services deployed on a cluster use unique ports. In the source, it becomes apparent that its the external load balancer creation that causes the command to fail. Indeed, I can deploy pynote with createExternalLoadBalancer to false. Happily coexisting: hellogo-service <nonename=hellogo 10.143.249.126 80 pynote-service <nonename=pynote 10.143.254.255 80 I've tried to define my own target pool called pynote-service, selecting all the cluster node instances and created a network load balancer with a forwarding rule on port 80 to the target pool. Despite the fact that it corresponds to the one created automatically for hellogo-service, it does not seem to resolve to the running pynote pod. This feels like I'm missing something small, but I've been blocked on this. Perhaps I'll only ever run one lonely web service...
I believe there's a bug in the service validation logic, left over from when you actually might have a conflict...

Discussion:
allErrs = append(allErrs, ValidateLabels(service.Labels, "labels")...) allErrs = append(allErrs, ValidateLabels(service.Annotations, "annotations")...) <del> if service.Spec.CreateExternalLoadBalancer { services, err := lister.ListServices(ctx) if err != nil { allErrs = append(allErrs, errs.NewInternalError(err)) } else { for i := range services.Items { if services.Items[i].Name != service.Name && services.Items[i].Spec.CreateExternalLoadBalancer && services.Items[i].Spec.Port == service.Spec.Port { allErrs = append(allErrs, errs.NewConflict("service", service.Name, fmt.Errorf("port: %d is already in use", service.Spec.Port))) break } } } } </del> if service.Spec.SessionAffinity == "" { service.Spec.SessionAffinity = api.AffinityTypeNone } else if !supportedSessionAffinityType.Has(string(service.Spec.SessionAffinity)) {

numErrs: 0, }, { <del> name: "invalid port in use", </del> <ins> name: "external port in use", </ins> svc: api.Service{ ObjectMeta: api.ObjectMeta{Name: "abc123", Namespace: api.NamespaceDefault}, Spec: api.ServiceSpec{

}, }, }, <del> numErrs: 1, </del> <ins> numErrs: 0, </ins> }, { name: "same port in use, but not external",