Deploying a Load-Balanced HTTP Application Using Go
Understand how to handle the NGINX deployment of a load-balanced HTTP application with Go.
We'll cover the following...
- The code
- Creating a ClientSet
- Creating a namespace
- Deploying the application into the namespace
- Creating the NGINX deployment
- Waiting for ready replicas to match desired replicas
- Creating a service to load-balance
- Creating an ingress to expose our application on a local host port
- Streaming pod logs for the NGINX application
Now that we understand a bit more about the Kubernetes API and the resources exposed by the API, we can move away from kubectl
toward using Go.
In this lesson, we will use Go to do many of the same things we did in the previous section using kubectl
. We will authenticate using our default context and create a namespace. However, we will not stop there. We will deploy a load-balanced HTTP application to our cluster and watch the logs stream to STDOUT
as we make requests to the service.
Click the “Run” button below to start this demo:
module github.com/Go-for-DevOps/chapter/14/workloads go 1.17 require ( github.com/Azure/go-autorest/autorest/to v0.4.0 k8s.io/api v0.23.4 k8s.io/apimachinery v0.23.4 k8s.io/client-go v0.23.4 ) require ( github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.2.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-cmp v0.5.5 // indirect github.com/google/gofuzz v1.1.0 // indirect github.com/googleapis/gnostic v0.5.5 // indirect github.com/imdario/mergo v0.3.5 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.27.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect k8s.io/klog/v2 v2.30.0 // indirect k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect k8s.io/utils v0.0.0-20211116205334-6203023598ed // indirect sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect sigs.k8s.io/yaml v1.2.0 // indirect )
Enter these commands in the terminal above:
kind create cluster --name workloads --config kind-config.yamlkubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yamlkubectl wait --namespace ingress-nginx \--for=condition=ready pod \--selector=app.kubernetes.io/component=controller \--timeout=90s
Wait a few moments for the last command to finish running. Then, continue with these commands:
cd /usercode/Go-for-DevOps/chapter/14/workloads/go run .
The preceding commands will create a KinD
cluster named workloads
and use a config
file that will enable host network ingress for the cluster. We will use ingress to expose the service running in the cluster. The command then deploys the NGINX ingress controller and waits for it to be ready. Finally, we run our Go program to deploy our application. After the service has been deployed and is running, open a browser with the URL beneath the Run button. We should see the following when we browse there:
We should see the request logs stream to STDOUT
. They should look like the following:
10.244.0.7 - - [07/Mar/2022:02:34:59 +0000] "GET /hello HTTP/1.1" 200 7252 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.3 Safari/605.1.15" "172.22.0.1"
If we refresh the page, we should see the server name change, indicating that the requests are load-balancing across the two pod replicas in the deployment. Press “Ctrl + C” to terminate the Go program.
To tear down the cluster, run the following command:
kind delete cluster --name workloads
The preceding command will delete the kind
cluster named workloads
. Next, let's explore this Go application to understand what just happened.
The code
Let's dive right into the code and see what is happening in this Go ...