Configuring domain names with static IP addresses

This tutorial demonstrates how to use Google Kubernetes Engine (GKE) to expose your web application to the internet on a static external IP address and configure a domain name to point to your application.

This tutorial assumes you own a registered domain name, such as example.com. You can register a domain name through Google Domains or another domain registrar of your choice if you do not have one.

Objectives

This tutorial demonstrates the following steps:

  • Reserve a static external IP address for your application
  • Configure either Service or Ingress resources to use the static IP
  • Update DNS records of your domain name to point to your application

Before you begin

Take the following steps to enable the Kubernetes Engine API:
  1. Visit the Kubernetes Engine page in the Google Cloud Console.
  2. Create or select a project.
  3. Wait for the API and related services to be enabled. This can take several minutes.
  4. Make sure that billing is enabled for your Cloud project. Learn how to confirm that billing is enabled for your project.

Install the following command-line tools used in this tutorial:

  • gcloud is used to create and delete Kubernetes Engine clusters. gcloud is included in the Google Cloud SDK.
  • kubectl is used to manage Kubernetes, the cluster orchestration system used by Kubernetes Engine. You can install kubectl using gcloud:
    gcloud components install kubectl

Clone the sample code from GitHub:

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/hello-app/manifests

Set defaults for the gcloud command-line tool

To save time typing your project ID and Compute Engine zone options in the gcloud command-line tool, you can set the defaults:
gcloud config set project project-id
gcloud config set compute/zone compute-zone

Create a cluster

Create a container cluster named domain-test to deploy your web application:

gcloud container clusters create domain-test

Deploying your web application

The following manifest describes a Deployment that runs a sample web application container image:

# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloweb
  labels:
    app: hello
spec:
  selector:
    matchLabels:
      app: hello
      tier: web
  template:
    metadata:
      labels:
        app: hello
        tier: web
    spec:
      containers:
      - name: hello-app
        image: gcr.io/google-samples/hello-app:1.0
        ports:
        - containerPort: 8080

Run the following command to create the Deployment:

kubectl apply -f helloweb-deployment.yaml

Exposing your application

You can expose your application on GKE using either of the following methods:

To learn more about the pros and cons of each method, refer to the Setting up HTTP(S) Load Balancing with Ingress.

Use a Service

To ensure that your application has a static public IP address, you must reserve a static IP address.

If you choose to expose your application using a Service, you must create a regional IP address. Global IP addresses only work with Ingress resource type, as explained in the next section.

To use a Service, create a static IP address named helloweb-ip in the region us-central1:

gcloud

gcloud compute addresses create helloweb-ip --region us-central1

To find the static IP address you created, run the following command:

gcloud compute addresses describe helloweb-ip --region us-central1
Output:
address: 203.0.113.32
...

Config Connector

Note: This step requires Config Connector. Follow the installation instructions to install Config Connector on your cluster.

apiVersion: compute.cnrm.cloud.google.com/v1beta1
kind: ComputeAddress
metadata:
  name: helloweb-ip
spec:
  location: us-central1
To deploy this manifest, download it to your machine as compute-address-regional.yaml, and run:
kubectl apply -f compute-address-regional.yaml
To find the static IP address, run the following command:
kubectl get computeaddress helloweb-ip -o jsonpath='{.spec.address}'

The following manifest describes a Service of type LoadBalancer, which creates a network load balancer to expose Pods with a public IP.

Replace YOUR.IP.ADDRESS.HERE with the static IP address:

# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: v1
kind: Service
metadata:
  name: helloweb
  labels:
    app: hello
spec:
  selector:
    app: hello
    tier: web
  ports:
  - port: 80
    targetPort: 8080
  type: LoadBalancer
  loadBalancerIP: "YOUR.IP.ADDRESS.HERE"

Then, create the Service:

kubectl apply -f helloweb-service-static-ip.yaml

To see the reserved IP address associated with the load balancer:

kubectl get service
Output:
NAME               CLUSTER-IP      EXTERNAL-IP      PORT(S)          AGE
helloweb           10.31.254.176   203.0.113.32     80:30690/TCP     54s

Use an Ingress

If you choose to expose your application using an Ingress, which creates an HTTP(S) Load Balancer, you must reserve a global static IP address. Regional IP addresses do not work with Ingress.

To learn more about how to use Ingress to expose your applications to the internet, refer to the Setting up HTTP(S) Load Balancing with Ingress tutorial.

To create a global static IP address named helloweb-ip:

gcloud

gcloud compute addresses create helloweb-ip --global

To find the static IP address you created:

gcloud compute addresses describe helloweb-ip --global
Output:
address: 203.0.113.32
...

Config Connector

Note: This step requires Config Connector. Follow the installation instructions to install Config Connector on your cluster.

apiVersion: compute.cnrm.cloud.google.com/v1beta1
kind: ComputeAddress
metadata:
  name: helloweb-ip
spec:
  location: global
To deploy this manifest, download it to your machine as compute-address-global.yaml, and run:
kubectl apply -f compute-address-global.yaml

The following manifest describes an Ingress that exposes a web application on a static IP with two resources:

  • A Service with type:NodePort
  • An Ingress configured with the service name and static IP annotation
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: helloweb
  annotations:
    kubernetes.io/ingress.global-static-ip-name: helloweb-ip
  labels:
    app: hello
spec:
  backend:
    serviceName: helloweb-backend
    servicePort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: helloweb-backend
  labels:
    app: hello
spec:
  type: NodePort
  selector:
    app: hello
    tier: web
  ports:
  - port: 8080
    targetPort: 8080

The kubernetes.io/ingress.global-static-ip-name annotation specifies the name of the global IP address resource to be associated with the HTTP(S) Load Balancer.

Apply the resource to the cluster:

kubectl apply -f helloweb-ingress-static-ip.yaml
Output:
ingress "helloweb" created
service "helloweb-backend" created

To see the reserve IP address associated with the load balancer:

kubectl get ingress
Output:
NAME       HOSTS     ADDRESS          PORTS     AGE
helloweb   *         203.0.113.32     80        4m

Visiting your reserved static IP address

To verify that the load balancer is configured correctly, you can either use a web browser to visit the IP address or use curl:

curl http://203.0.113.32/
Output:
Hello, world!
Hostname: helloweb-3766687455-8lvqv

Configuring your domain name records

To have browsers querying your domain name, such as example.com, or subdomain name, such as blog.example.com, point to the static IP address you reserved, you must update the DNS (Domain Name Server) records of your domain name.

You must create an A (Address) type DNS record for your domain or subdomain name and have its value configured with the reserved IP address

DNS records of your domain are managed by your nameserver. Your nameserver might be the "registrar" where you registered your domain, a DNS service such as Cloud DNS, or another third-party provider.

  • If your nameserver is Cloud DNS: Follow Cloud DNS Quickstart guide to configure DNS A record for your domain name with the reserved IP address of your application.

  • If your nameserver is another provider: Refer to your DNS service's documentation on setting DNS A records to configure your domain name. If you choose to use Cloud DNS instead, refer to Migrating to Cloud DNS.

Visiting your domain name

To verify that your domain name's DNS A records resolve to the IP address you reserved, visit your domain name.

To make a DNS query for your domain name's A record, run the host command:

host example.com
Output:
example.com has address 203.0.113.32

At this point, you can point your web browser to your domain name and visit your website!

Cleaning up

To avoid incurring charges to your Google Cloud Platform account for the resources used in this tutorial:

  1. Delete the load balancing resources:

    kubectl delete ingress,service -l app=hello

  2. Release the reserved static IP. After the load balancer is deleted, the unused but reserved IP address is no longer free of charge and is billed per unused IP address pricing. Run the following commands to release the static IP resource:

    • If you used a Service:

      gcloud compute addresses delete helloweb-ip --region us-central1
    • If you used an Ingress:

      gcloud compute addresses delete helloweb-ip --global
  3. Delete the sample application:

    kubectl delete -f helloweb-deployment.yaml

  4. Wait until the load balancer is deleted by watching the output of the following command. The output should not show a forwarding rule that contains "helloweb" in its name:

    gcloud compute forwarding-rules list

  5. Delete the container cluster:

    gcloud container clusters delete domain-test

What's next