Give an app a public address by attaching reserved IPs to your cluster’s LB IP pool. Each Service of type LoadBalancer in the cluster then takes one of those addresses. To serve many sites from a single address instead, put an ingress controller in front of them. It routes each request to the right site by its hostname; see Set up an ingress controller with HTTPS.
Before you begin
Section titled “Before you begin”- A cluster in the Worker Joining, Worker Joined, or Ready state, and its kubeconfig
set up for
kubectl. See Connect to a Kubernetes cluster. - At least one public reserved IP in the same project and region, with Status Available. See Reserve an IP. A reserved IP is billed every month from when you reserve it until you delete it, whether it is attached or detached. For the rate, see E2E’s pricing page.
- Permission to update Kubernetes and to create reserved IPs in the project. To detach an address later, you need permission to update Kubernetes and to delete reserved IPs.
Choose how to expose a Service
Section titled “Choose how to expose a Service”Kubernetes has three Service types, and each one is reachable from a different place:
| Type | Reachable from | Use it for |
|---|---|---|
| ClusterIP | Inside the cluster only | Internal APIs, databases, and anything other pods call. This is the default. |
| NodePort | Networks that can route to the nodes’ addresses in your VPC | Quick tests. It is rarely the right entry point for production. |
| LoadBalancer | A public reserved IP that you attached to the cluster | Public entry points, alone or behind an ingress controller |
ClusterIP
Section titled “ClusterIP”A ClusterIP Service gets a stable internal address and a DNS name. It is reachable from inside the cluster only.
apiVersion: v1kind: Servicemetadata: name: apispec: type: ClusterIP selector: app: api ports: - port: 80 targetPort: 8080Other pods reach it as api in the same namespace, and as api.<namespace>.svc.cluster.local from other namespaces.
To test it from inside the cluster, and to reach it from your computer while it stays private, run:
kubectl get svc apikubectl run -it --rm curl --image=curlimages/curl --restart=Never -- curl -s http://apikubectl port-forward svc/api 8080:80NodePort
Section titled “NodePort”A NodePort Service opens the same port, from 30000 to 32767, on every node and forwards it to the Service.
apiVersion: v1kind: Servicemetadata: name: apispec: type: NodePort selector: app: api ports: - port: 80 targetPort: 8080 nodePort: 30080It answers at <node-ip>:30080, where <node-ip> is a node’s address in your VPC. Only networks
that can route to the nodes’ VPC addresses can reach it. For production, use a LoadBalancer Service
instead. The NodePort port is high and unusual, and each client sends its traffic to the one node it
addresses. A
node can also be removed when its pool is resized.
Attach reserved IPs to the cluster
Section titled “Attach reserved IPs to the cluster”A new cluster’s LB IP pool is empty, and a LoadBalancer Service waits until it has an address to take. The pool takes public reserved IPs only.
- In Kubernetes, select the cluster’s name to open Kubernetes Cluster Details, and select the LB IP Pool tab. The addresses already in the pool are under Attached IPs.
- Select Add Reserve IP. You can do this once the cluster reaches Worker Joining.
- Under Reserve IPs, choose one or more of the project’s Available reserved IPs. If there is none, select Click here to reserve a new one.
- Select Add Reserve IP.
The addresses join the pool under Attached IPs.
You can also attach an address from the Reserve IP page: choose Kubernetes Cluster in Attach IP. See Attach a reserved IP.
Create a LoadBalancer Service
Section titled “Create a LoadBalancer Service”With at least one free address in the pool, create a Service of type LoadBalancer. Save this as
service.yaml, with your own app’s label under selector and the port your app listens on as the
target port:
apiVersion: v1kind: Servicemetadata: name: webspec: type: LoadBalancer selector: app: web ports: - port: 80 targetPort: 8080Apply it and watch it take an address:
kubectl apply -f service.yamlkubectl get svc web -wEXTERNAL-IP changes from <pending> to one of the addresses you attached. Check that the app
answers on it, where <external-ip> is that address:
curl http://<external-ip>Each LoadBalancer Service takes its own address from the pool. When every attached address is
already taken, a new Service stays at <pending> until you attach another IP or delete a Service
that holds one.
Free an address
Section titled “Free an address”Deleting a LoadBalancer Service frees its address for another Service in the same cluster. To give the address back to the project, detach it from the pool:
-
Find any Service that still uses the address, where
<ip-address>is the address:kubectl get svc --all-namespaces -o wide | grep <ip-address> -
Delete that Service. TIR refuses to detach an address while a Service still uses it, and the refusal names the Service.
-
On the LB IP Pool tab, select Detach IP next to the address, and confirm in Detach Reserve IP.
The address goes back to the project’s reserved IPs, ready for another cluster or resource, and keeps its monthly charge until you delete it. See Delete a reserved IP.
Your app now answers on a public address of its own. Once you run more than one or two public
sites, set up an ingress controller so
that they share one address and get HTTPS. For an address that stays at <pending> or will not
detach, see
Troubleshooting TIR Kubernetes.