Exposing k8s service on GKE to other compute instances, but not to the external world

7/21/2019

I have created a deployment and a service on Google Kubernetes Engine. These are running on Cloud Compute instances.

I need to make my k8s application reachable from other Compute instances, but not from the outside world. That is because there are some legacy instances running outside the cluster and those cannot be migrated (yet, at least).

My understanding is that a Service makes the pod reachable from other cluster nodes, whereas an Ingress exposes the pod to the external traffic with an external IP.

What I need is something in the middle: I need to expose my pod outside the cluster, but only to other local Compute instances (in the same zone). I don't understand how I am supposed to do it.

-- rubik
google-cloud-platform
google-kubernetes-engine
kubernetes

1 Answer

7/21/2019

In Google Kubernetes Engine this is accomplished with a LoadBalancer type Service that is annotated to be an internal load balancer. The documentation for it is at https://cloud.google.com/kubernetes-engine/docs/how-to/internal-load-balancing.

Assuming you had a Deployment with label app: echo-pod that listened on port 080 and you wanted to expose it as port 80 to GCE instance the service would look something like:

apiVersion: v1
kind: Service
metadata:
  name: echo-internal
  annotations:
    cloud.google.com/load-balancer-type: "Internal"
  labels:
    app: echo-pod
spec:
  type: LoadBalancer
  selector:
    app: echo-pod
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP

It will take a moment to create the Service and internal load balancer. It will have an external IP once created:

$ kubectl get services
NAME              TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
echo-internal     LoadBalancer   10.4.11.165   10.128.0.35   80:31706/TCP   2m33s
kubernetes        ClusterIP      10.4.0.1      <none>        443/TCP        20m

The 10.128.0.35 IP is actually an internal IP address only accessible inside your VPC. From another GCE instance you can access it on the exposed port:

$ curl http://10.128.0.35


Hostname: echo-deployment-5f55bb9855-hxl7b

Note: You need to have the "Load balancing" add-on enabled when you provisioned your cluster. But it is enabled by default and should be working unless you explicitly disabled the "Enable HTTP load balancing" option at cluster creation.

-- Andy Shinn
Source: StackOverflow