To reach an application from the internet, expose it with a Kubernetes service of type LoadBalancer. The service gets its external IP from the cluster’s LB IP Pool: the public service IPs you attach to the cluster in MyAccount, and any private LB IPs you reserve for traffic inside the VPC. MetalLB, which runs in the cluster, gives each LoadBalancer service one IP of its own from the pool, so attach one IP for each LoadBalancer service you run.
Before you begin
Section titled “Before you begin”- Your cluster reads Running.
- kubectl is connected to the cluster. See Connect to a cluster with kubectl.
- You have an application running in the cluster. The examples expose a Deployment named
hellothat runs the NGINX web server. To create it, runkubectl create deployment hello --image=nginx --replicas=2. - For a public service IP, you have room under your account’s reserved-IP limit and enough infra credits. A public service IP counts toward the limit. See Reserve an IP.
Attach a public service IP to the pool
Section titled “Attach a public service IP to the pool”- In MyAccount, under Compute, click Kubernetes. In the cluster’s row actions, click Add LB IP, which opens the cluster on its LB IP Pool tab. Or open the cluster and click the LB IP Pool tab.
- If the tab says Currently no reserved Service IP is available, you hold no public service IP yet. Click Click here to reserve one. With too few infra credits, Low Infra Credits opens with a link to buy more.
- If the tab says Currently no Service IP attached, click Click here. Attach Public IP opens.
- Under Select IP, choose a reserved IP that is not attached to anything else.
- Click Attach IP.
The IP is listed under Service IP on the LB IP Pool tab. For each further LoadBalancer service, attach another public service IP. A service without the MetalLB annotation takes any free IP in the pool, private LB IPs included; to be sure a service gets a public address, name the public service IP in its annotation, as in Give a service a private LB IP.
Create the LoadBalancer service
Section titled “Create the LoadBalancer service”Write the service as a manifest. This example sends traffic on port 80 to port 80 of the pods of the
hello Deployment, which carry the label app: hello. For your own application, change the name,
the label, and the ports:
apiVersion: v1kind: Servicemetadata: name: hellospec: type: LoadBalancer selector: app: hello ports: - protocol: TCP port: 80 targetPort: 80Save it as hello-service.yaml, apply it, and watch the service:
kubectl apply -f hello-service.yamlkubectl get service hello --watchkubectl prints a new line each time the service changes. It shows <pending> first, then the IP
from the pool:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEhello LoadBalancer <cluster-ip> <pending> 80:<port>/TCP 2shello LoadBalancer <cluster-ip> <external-ip> 80:<port>/TCP 5sCheck the external IP
Section titled “Check the external IP”When EXTERNAL-IP changes from <pending> to one of the IPs on the LB IP Pool tab, press
Ctrl+C. Your application answers on that address, on the service’s port:
curl http://<external-ip>Here <external-ip> is the address in EXTERNAL-IP. If the address stays on <pending>, see
A LoadBalancer service stays on pending.
Stop using a public service IP
Section titled “Stop using a public service IP”On the LB IP Pool tab, click Detach IP next to the IP. Detach Public IP asks you to confirm; click Detach IP.
A detached IP stays reserved in your account. Public service IPs are billed from when you reserve them until you release them, including after the cluster that used them is deleted. To stop the charge, release it; see Delete a reserved IP. For current prices, see E2E’s pricing page.
(Optional) Limit who can reach the service
Section titled “(Optional) Limit who can reach the service”Security groups control traffic to the nodes’ own IPs. A LoadBalancer service on a public service IP is reachable on every port it exposes, so to limit who reaches it, list the address ranges it accepts under the service’s source ranges, as in this example:
apiVersion: v1kind: Servicemetadata: name: hellospec: type: LoadBalancer loadBalancerSourceRanges: - 203.0.113.0/24 selector: app: hello ports: - protocol: TCP port: 80 targetPort: 80Replace 203.0.113.0/24 with your own ranges, one per line, and apply the file again. Requests from
the listed ranges reach the service; requests from anywhere else get no answer.
(Optional) Give a service a private LB IP
Section titled “(Optional) Give a service a private LB IP”For an application that only machines inside your VPC call, such as an internal API that other nodes in your VPC use, give its service a private LB IP. Private LB IPs are free, and reachable only inside the VPC.
-
On the LB IP Pool tab, under Private LB IP Pool, click Reserve Private IP. It takes the next free address in the cluster’s VPC, or in its subnet, and adds it to the pool. E2E also adds a security group for that IP to the cluster; see Manage a cluster’s security groups.
-
To give a service that address, name it in the service’s MetalLB annotation, as in this example. Replace
<private-lb-ip>with the address you reserved:apiVersion: v1kind: Servicemetadata:name: hello-privateannotations:metallb.universe.tf/loadBalancerIPs: <private-lb-ip>spec:type: LoadBalancerselector:app: helloports:- protocol: TCPport: 80targetPort: 80 -
Save it as
hello-private.yaml, apply it, and check the service:kubectl apply -f hello-private.yamlkubectl get service hello-private
EXTERNAL-IP shows the private LB IP. From a node in the same VPC, run
curl http://<private-lb-ip>: it returns the NGINX welcome page. To make a node there, see
Create a node. The same annotation gives a service one
particular public service IP from the pool.
A cluster holds up to 4 private LB IPs; a fifth is refused with Maximum of 4 private LB IPs reached. To give one back, click Release IP next to it. A cluster’s private LB IPs are released when the cluster is deleted.
(Optional) Route several applications through one IP
Section titled “(Optional) Route several applications through one IP”Each LoadBalancer service takes one IP from the pool. To serve several applications from one address, run an ingress controller, which takes traffic coming into the cluster and routes it by host name. The controller has one LoadBalancer service, and your applications sit behind it as ClusterIP services, which are reachable only inside the cluster.
-
Free an IP for the controller. If every IP in the pool is in use, attach another public service IP, or make
helloa ClusterIP service first so its IP returns to the pool:kubectl delete service hellokubectl expose deployment hello --port=80 -
Install the NGINX Ingress Controller from the cluster’s Marketplace tab; see Install marketplace apps on a cluster. Its service takes any free IP from the pool, private LB IPs included. If the pool holds a free private LB IP, name your public service IP in the controller’s MetalLB annotation:
kubectl annotate service ingress-nginx-controller --namespace ingress-nginx metallb.universe.tf/loadBalancerIPs=<public-service-ip> -
Find the controller’s address, the
EXTERNAL-IPofingress-nginx-controller:kubectl get service ingress-nginx-controller --namespace ingress-nginx -
Write an Ingress that sends requests for one host name to the service. Replace
hello.example.comwith your own host name:apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: hellospec:ingressClassName: nginxrules:- host: hello.example.comhttp:paths:- path: /pathType: Prefixbackend:service:name: helloport:number: 80 -
Save it as
hello-ingress.yaml, apply it, and send a request with that host name:kubectl apply -f hello-ingress.yamlcurl -H "Host: hello.example.com" http://<ingress-ip>Here
<ingress-ip>is the controller’sEXTERNAL-IP. The NGINX welcome page is returned. Requests for any other host name get 404.
To add another application, add a rule with its host name and service. When the routing works, point
your domain’s DNS A record for each host name at <ingress-ip>. For TLS certificates on those host
names, install Cert-Manager from the same tab; see cert-manager
for how to request certificates. The Gateway API is a newer way
to route the same traffic. Its resources are not installed on a new cluster, so install its CRDs
first; see Getting started in the Gateway API docs.
Your application is reachable on its IP from the cluster’s LB IP Pool. To control traffic to the nodes themselves, see Manage a cluster’s security groups.