This section continues from the previous section - make sure you do the tutorial in sequence.
There are primarily 2 ways to expose a Kubernetes Service on the public internet:
Type
Protocol
Locality
When to use?
TCP/UDP
Regional
Non-HTTP requests, or no need for a global load balancer. Connection to the Load Balancer is routed by public Internet to region of the load balancer.
HTTP(s)
Global
HTTP requests. GCP's L7 Load Balancer is a global load balancer - a single IP address can automatically route traffic to the nearest region within the GCP network.
External Network Load Balancer
Service YAML
To create an external network load balancer, simply change Kubernetes Service's type from clusterip to loadbalancer. Modify the k8s/service.yaml:
k8s/service.yaml
apiVersion:v1kind:Servicemetadata:name:helloworldlabels:app:helloworldannotations:cloud.google.com/neg:'{"exposed_ports": {"8080":{}}}'spec:ports: - name:8080-8080port:8080protocol:TCPtargetPort:8080selector:app:helloworld# Use LoadBalancer type instead of ClusterIPtype:LoadBalancer
Deploy
Use kubectl command line to deploy the YAML file:
kubectlapply-fk8s/service.yaml
To verify the application is deployed, run :
kubectlgetsvchelloworld
You should see that the Service has a Cluster IP address, but also the External IP address with the initial value of <pending>. This is because, behind the scenes, Kubernetes Engine is provisioning a Google Cloud Network Load Balancer.
Continuously check the External IP address, until an IP address is assigned. Once the IP Address is assigned, you can connect to the External IP address, and it'll be load balanced to the helloworld service backend pods.
Update the k8s/service.yaml to pin the Load Balancer IP address:
k8s/service.yaml
apiVersion:v1kind:Servicemetadata:name:helloworldlabels:app:helloworldspec:ports: - name:8080-8080port:8080protocol:TCPtargetPort:8080selector:app:helloworldtype:LoadBalancer# Replace the value with the IP address you reservedloadBalancerIP:RESERVED_IP_ADDRESS
External HTTP Load Balancer
You can configure an external HTTP load balancer using Kubernetes Ingress. In order for the HTTP Load Balancer to find the backends, it's recommended to use container-native load balancing on Google Cloud.
Service YAML
In the k8s/service.yaml, use the cloud.google.com/neg annotation to enable Network Endpoint Group (NEG) in order to use container-native load balancing:
k8s/service.yaml
apiVersion:v1kind:Servicemetadata:name:helloworldlabels:app:helloworld# Add the NEG annotation to enable Network Endpoint Group# in order to use container-native load balancingannotations:cloud.google.com/neg:'{"ingress": true}'spec:ports: - name:8080-8080port:8080protocol:TCPtargetPort:8080selector:app:helloworldtype:ClusterIP
Ingress YAML
Create a Kubernetes Ingress configuration that will create the HTTP Load Balancer. Create a k8s/ingress.yaml:
Use kubectl command line to deploy the YAML files:
# Delete the existing service because it may contain a node port:kubectldelete-fk8s/service.yaml# Redeploy the servicekubectlapply-fk8s/service.yaml# Deploy the ingresskubectlapply-fk8s/ingress.yaml
To verify the Ingress is deployed:
kubectlgetingresshelloworld
You should see that the Ingress has an IP address provisioned:
NAMEHOSTSADDRESSPORTSAGEhelloworld*...8081s
Many Google Cloud components are being configured behind the scenes to enable global load balancing. It'll take a few minutes before the address is accessible. Use kubectl describe to see the current status:
By default, the Ingress IP address is ephemeral - it'll change if you ever delete and recreate the Ingress. You can associate the Ingress with a static IP address instead.
Continuously check the IP address to be updated. It'll take several minutes for the IP address to update:
kubectlgetingresshelloworld
SSL Certificate
In order to use a SSL certificate to serve HTTPs traffic, you must use a real fully qualified domain name and configure it to point to the IP address. If you don't have a real domain, then you can use xip.io.
You can provision the External HTTP(s) Load Balancer using Ingress with a Managed Certificate, or you can provide your own Self-Managed Certificate.
Managed Certificate
Google Cloud can automatically provision a certificate for your domain name when using the External HTTP(s) Load Balancer.
Create a new k8s/certificate.yaml:
EXTERNAL_IP=$(kubectlgetingresshelloworld-ojsonpath="{.status.loadBalancer.ingress[0].ip}")DOMAIN="${EXTERNAL_IP}.xip.io"cat<<EOF>k8s/certificate.yamlapiVersion: networking.gke.io/v1kind: ManagedCertificatemetadata: name: helloworld-certificatespec: domains: # Replace the value with your domain name - ${DOMAIN}EOF
k8s/certificate.yaml
apiVersion:networking.gke.io/v1kind:ManagedCertificatemetadata:name:helloworld-certificatespec:domains:# Replace the value with your domain name - YOUR_DOMAIN_NAME
In k8s/ingress.yaml, use the networking.gke.io/managed-certificates annotation to associate the certificate:
k8s/ingress.yaml
apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:helloworldannotations:kubernetes.io/ingress.global-static-ip-name:"helloworld-ingress-ip"# Associate the ingress with the certificate namenetworking.gke.io/managed-certificates:"helloworld-certificate"spec:rules: - http:paths: - path:/*backend:service:name:helloworldpost:number:8080
Update the Ingress to refer to the secret for TLS certificate/key pair:
k8s/ingress.yaml
apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:helloworldannotations:kubernetes.io/ingress.global-static-ip-name:"helloworld-ingress-ip"spec:# Associate with the TLS certificate/key pair by the secret nametls: - secretName:helloworld-tlsrules: - http:paths: - path:/*backend:service:name:helloworldpost:number:8080