This example shows how to build a simple multi-tier web application using Kubernetes and Docker. The application consists of a web front end, Redis master for storage, and replicated set of Redis slaves, all for which we will create Kubernetes deployments, pods, and services.
There are two versions of this application. Version 1 (in the v1
directory)
is the simple application itself, while version 2 (in the v2
directory)
extends the application by adding additional features that leverage the Watson
Tone Analyzer service. It is recommended that if you are new to this example
then you look at just the v1
version of the application. Other IBM demos
will make use of the v2
version, such as
Istio101.
Please see the corresponding README.md
files in each directory for more
information.
- As you read the correspoding
README.md
files, you will seekubectl
commands that describes deployed resources. The output of these commands can be slightly vary depending on the version of your kubectl. - The guestbook applications uses Kubernetes service type
LoadBalancer
to expose the service onto an external IP address. If you are usingMinikube
, keep in mind that no real external load balancer is created. You can still access the service with the node port that is assigned to load balancer onMinikube
.
This example shows how to build a simple multi-tier web application using Kubernetes and Docker. The application consists of a web front end, Redis master for storage, and replicated set of Redis slaves, all for which we will create Kubernetes replication controllers, pods, and services.
- Prerequisites
- Create the Redis master pod
- Create the Redis master service
- Create the Redis slave pods
- Create the Redis slave service
- Create the guestbook pods
- Create the guestbook service
- View the guestbook
- Cleanup
This example assumes that you have a working cluster. See the Getting Started Guides for details about creating a cluster.
Tip: View all the kubectl
commands, including their options and descriptions in the kubectl CLI reference.
All of the commands specified should be run from this directory.
Use the redis-master-deployment.yaml
file to create a deployment and Redis master pod. The pod runs a Redis key-value server in a container. Using a replication controller is the preferred way to launch long-running pods, even for 1 replica, so that the pod benefits from the self-healing mechanism in Kubernetes (keeps the pods alive).
-
Use the redis-master-deployment.yaml file to create the Redis master replication controller in your Kubernetes cluster by running the
kubectl create -f
filename
command:$ kubectl create -f redis-master-deployment.yaml replicationcontrollers/redis-master
-
To verify that the redis-master controller is up, list the replication controllers you created in the cluster with the
kubectl get rc
command(if you don't specify a--namespace
, thedefault
namespace will be used. The same below):$ kubectl get rc CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS redis-master redis-master gurpartap/redis app=redis,role=master 1 ...
Result: The replication controller then creates the single Redis master pod.
-
To verify that the redis-master pod is running, list the pods you created in cluster with the
kubectl get pods
command:$ kubectl get pods NAME READY STATUS RESTARTS AGE redis-master-xx4uv 1/1 Running 0 1m ...
Result: You'll see a single Redis master pod and the machine where the pod is running after the pod gets placed (may take up to thirty seconds).
A Kubernetes service is a named load balancer that proxies traffic to one or more pods. The services in a Kubernetes cluster are discoverable inside other pods via environment variables or DNS.
Services find the pods to load balance based on pod labels. The pod that you created in previous step has the label app=redis
and role=master
. The selector field of the service determines which pods will receive the traffic sent to the service.
-
Use the redis-master-service.yaml file to create the service in your Kubernetes cluster by running the
kubectl create -f
filename
command:$ kubectl create -f redis-master-service.yaml services/redis-master
-
To verify that the redis-master service is up, list the services you created in the cluster with the
kubectl get services
command:$ kubectl get services NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE redis-master 10.0.136.3 <none> 6379/TCP app=redis,role=master 1h ...
Result: All new pods will see the
redis-master
service running on the host ($REDIS_MASTER_SERVICE_HOST
environment variable) at port 6379, or running onredis-master:6379
. After the service is created, the service proxy on each node is configured to set up a proxy on the specified port (in our example, that's port 6379).
The Redis master we created earlier is a single pod (REPLICAS = 1), while the Redis read slaves we are creating here are 'replicated' pods. In Kubernetes, a replication controller is responsible for managing the multiple instances of a replicated pod.
-
Use the file redis-slave-deployment.yaml to create the replication controller by running the
kubectl create -f
filename
command:$ kubectl create -f redis-slave-deployment.yaml replicationcontrollers/redis-slave
-
To verify that the redis-slave controller is running, run the
kubectl get rc
command:$ kubectl get rc CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS redis-master redis-master redis app=redis,role=master 1 redis-slave redis-slave kubernetes/redis-slave:v2 app=redis,role=slave 2 ...
Result: The replication controller creates and configures the Redis slave pods through the redis-master service (name:port pair, in our example that's
redis-master:6379
).Example: The Redis slaves get started by the replication controller with the following command:
redis-server --slaveof redis-master 6379
-
To verify that the Redis master and slaves pods are running, run the
kubectl get pods
command:$ kubectl get pods NAME READY STATUS RESTARTS AGE redis-master-xx4uv 1/1 Running 0 18m redis-slave-b6wj4 1/1 Running 0 1m redis-slave-iai40 1/1 Running 0 1m ...
Result: You see the single Redis master and two Redis slave pods.
Just like the master, we want to have a service to proxy connections to the read slaves. In this case, in addition to discovery, the Redis slave service provides transparent load balancing to clients.
-
Use the redis-slave-service.yaml file to create the Redis slave service by running the
kubectl create -f
filename
command:$ kubectl create -f redis-slave-service.yaml services/redis-slave
-
To verify that the redis-slave service is up, list the services you created in the cluster with the
kubectl get services
command:$ kubectl get services NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE redis-master 10.0.136.3 <none> 6379/TCP app=redis,role=master 1h redis-slave 10.0.21.92 <none> 6379/TCP app-redis,role=slave 1h ...
Result: The service is created with labels
app=redis
androle=slave
to identify that the pods are running the Redis slaves.
Tip: It is helpful to set labels on your services themselves--as we've done here--to make it easy to locate them later.
This is a simple Go net/http
(negroni based) server that is configured to talk to either the slave or master services depending on whether the request is a read or a write. The pods we are creating expose a simple JSON interface and serves a jQuery-Ajax based UI. Like the Redis read slaves, these pods are also managed by a replication controller.
-
Use the guestbook-deployment.yaml file to create the guestbook deployment by running the
kubectl create -f
filename
command:$ kubectl create -f guestbook-deployment.yaml replicationcontrollers/guestbook
Tip: If you want to modify the guestbook code it can be found in the guestbook
directory, along with its Makefile. If you have pushed your custom image be sure to update the image
property accordingly in the guestbook-deployment.yaml.
-
To verify that the guestbook replication controller is running, run the
kubectl get rc
command:$ kubectl get rc CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS guestbook guestbook ibmcom/guestbook:v2 app=guestbook 3 redis-master redis-master redis app=redis,role=master 1 redis-slave redis-slave kubernetes/redis-slave:v2 app=redis,role=slave 2 ...
-
To verify that the guestbook pods are running (it might take up to thirty seconds to create the pods), list the pods you created in cluster with the
kubectl get pods
command:$ kubectl get pods NAME READY STATUS RESTARTS AGE guestbook-3crgn 1/1 Running 0 2m guestbook-gv7i6 1/1 Running 0 2m guestbook-x405a 1/1 Running 0 2m redis-master-xx4uv 1/1 Running 0 23m redis-slave-b6wj4 1/1 Running 0 6m redis-slave-iai40 1/1 Running 0 6m ...
Result: You see a single Redis master, two Redis slaves, and three guestbook pods.
Just like the others, we create a service to group the guestbook pods but this time, to make the guestbook front end externally visible, we specify "type": "LoadBalancer"
.
-
Use the guestbook-service.yaml file to create the guestbook service by running the
kubectl create -f
filename
command:$ kubectl create -f guestbook-service.yaml
-
To verify that the guestbook service is up, list the services you created in the cluster with the
kubectl get services
command:$ kubectl get services NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE guestbook 10.0.217.218 146.148.81.8 3000/TCP app=guestbook 1h redis-master 10.0.136.3 <none> 6379/TCP app=redis,role=master 1h redis-slave 10.0.21.92 <none> 6379/TCP app-redis,role=slave 1h ...
Result: The service is created with label
app=guestbook
.
You can now play with the guestbook that you just created by opening it in a browser (it might take a few moments for the guestbook to come up).
-
Local Host: If you are running Kubernetes locally, to view the guestbook, navigate to
http://localhost:3000
in your browser. -
Remote Host:
-
To view the guestbook on a remote host, locate the external IP of the load balancer in the IP column of the
kubectl get services
output. In our example, the internal IP address is10.0.217.218
and the external IP address is146.148.81.8
(Note: you might need to scroll to see the IP column). -
Append port
3000
to the IP address (for examplehttp://146.148.81.8:3000
), and then navigate to that address in your browser.
Result: The guestbook displays in your browser:
-
After you're done playing with the guestbook, you can cleanup by deleting the guestbook service and removing the associated resources that were created, including load balancers, forwarding rules, target pools, and Kubernetes replication controllers and services.
Delete all the resources by running the following kubectl delete -f .
command:
$ kubectl delete -f .
replicationcontroller "guestbook" deleted
service "guestbook" deleted
replicationcontroller "redis-master" deleted
service "redis-master" deleted
replicationcontroller "redis-slave" deleted
service "redis-slave" deleted
Tip: To tear down your Kubernetes cluster, follow the corresponding instructions in the version of the Getting Started Guides that you previously used to create your cluster.