Skip to content
86 changes: 42 additions & 44 deletions web/guestbook-go/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
## Guestbook Example

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 replicas, all for which we will create Kubernetes replication controllers, pods, and services.

If you are running a cluster in Google Container Engine (GKE), instead see the [Guestbook Example for Google Container Engine](https://cloud.google.com/container-engine/docs/tutorials/guestbook).

##### Table of Contents

* [Step Zero: Prerequisites](#step-zero)
Expand All @@ -24,22 +20,22 @@ This example assumes that you have a working cluster. See the [Getting Started G

### Step One: Create the Redis master pod<a id="step-one"></a>

Use the `examples/guestbook-go/redis-master-controller.yaml` file to create a [replication controller](https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/) and Redis master [pod](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/). 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-controller.yaml` file to create a [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) and Redis master [pod](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/). The pod runs a Redis key-value server in a container. Using a deployment is the preferred way to launch long-running pods, even for 1 replica, so that the pod benefits from the [self-healing] mechanism (https://kubernetes.io/docs/concepts/architecture/self-healing/) in Kubernetes (keeps the pods alive).

1. Use the [redis-master-controller.yaml](redis-master-controller.yaml) file to create the Redis master deployment in your Kubernetes cluster by running the `kubectl create -f` *`filename`* command:
1. Use the [redis-master-controller.yaml](redis-master-controller.yaml) file to create the Redis master deployment in your Kubernetes cluster by running the `kubectl apply -f` *`filename`* command:

```console
$ kubectl create -f guestbook-go/redis-master-controller.yaml
$ kubectl apply -f redis-master-controller.yaml

```

2. To verify that the redis-master controller is up, list the deployments you created in the cluster with the `kubectl get deployments` command(if you don't specify a `--namespace`, the `default` namespace will be used. The same below):

```console
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
redis-master 1/1 1 1 33m
...
NAME READY UP-TO-DATE AVAILABLE AGE
redis-master 1/1 1 1 26m
...
```

Result: The deployment then creates the single Redis master pod.
Expand Down Expand Up @@ -73,10 +69,10 @@ A Kubernetes [service](https://kubernetes.io/docs/concepts/services-networking/s

Services find the pods to load balance based on pod labels. The pod that you created in Step One 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.

1. Use the [redis-master-service.yaml](redis-master-service.yaml) file to create the service in your Kubernetes cluster by running the `kubectl create -f` *`filename`* command:
1. Use the [redis-master-service.yaml](redis-master-service.yaml) file to create the service in your Kubernetes cluster by running the `kubectl apply -f` *`filename`* command:

```console
$ kubectl create -f guestbook-go/redis-master-service.yaml
$ kubectl apply -f redis-master-service.yaml

```

Expand All @@ -94,28 +90,29 @@ Services find the pods to load balance based on pod labels. The pod that you cre

### Step Three: Create the Redis replica pods <a id="step-three"></a>

The Redis master we created earlier is a single pod (REPLICAS = 1), while the Redis read replicas we are creating here are 'replicated' pods. In Kubernetes, a replication controller is responsible for managing the multiple instances of a replicated pod.
The Redis master we created earlier is a single pod (REPLICAS = 1), while the Redis read replicas we are creating here are 'replicated' pods. In Kubernetes, a deployment is responsible for managing the multiple instances of a replicated pod.

1. Use the file [redis-replica-controller.yaml](redis-replica-controller.yaml) to create the replication controller by running the `kubectl create -f` *`filename`* command:
1. Use the file [redis-replica-controller.yaml](redis-replica-controller.yaml) to create the deployment by running the `kubectl apply -f` *`filename`* command:

```console
$ kubectl create -f guestbook-go/redis-replica-controller.yaml
$ kubectl apply -f redis-replica-controller.yaml

```

2. To verify that the redis-replica controller is running, run the `kubectl get rc` command:
2. To verify that the redis-replica controller is running, run the `kubectl get deployments` command:

```console
$ kubectl get rc
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
redis-replica redis-replica registry.k8s.io/redis-slave:v2 app=redis,role=replica 2
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
redis-master 1/1 1 1 28m
redis-replica 2/2 2 2 10m
...
```

Result: The replication controller creates and configures the Redis replica pods through the redis-master service (name:port pair, in our example that's `redis-master:6379`).
Result: The deployment creates and configures the Redis replica pods through the redis-master service (name:port pair, in our example that's `redis-master:6379`).

Example:
The Redis replicas get started by the replication controller with the following command:
The Redis replicas get started by the deployment with the following command:

```console
redis-server --replicaof redis-master 6379
Expand All @@ -138,10 +135,10 @@ The Redis master we created earlier is a single pod (REPLICAS = 1), while the Re

Just like the master, we want to have a service to proxy connections to the read replicas. In this case, in addition to discovery, the Redis replica service provides transparent load balancing to clients.

1. Use the [redis-replica-service.yaml](redis-replica-service.yaml) file to create the Redis replica service by running the `kubectl create -f` *`filename`* command:
1. Use the [redis-replica-service.yaml](redis-replica-service.yaml) file to create the Redis replica service by running the `kubectl apply -f` *`filename`* command:

```console
$ kubectl create -f guestbook-go/redis-replica-service.yaml
$ kubectl apply -f redis-replica-service.yaml

```

Expand All @@ -151,7 +148,7 @@ Just like the master, we want to have a service to proxy connections to the read
$ 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-replica 10.0.21.92 <none> 6379/TCP app-redis,role=replica 1h
redis-replica 10.0.21.92 <none> 6379/TCP app=redis,role=replica 1h
...
```

Expand All @@ -161,38 +158,39 @@ Tip: It is helpful to set labels on your services themselves--as we've done here

### Step Five: Create the guestbook pods <a id="step-five"></a>

This is a simple Go `net/http` ([negroni](https://github.com/codegangsta/negroni) based) server that is configured to talk to either the replica 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 replica pods, these pods are also managed by a replication controller.
This is a simple Go `net/http` ([negroni](https://github.com/codegangsta/negroni) based) server that is configured to talk to either the replica 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 replica pods, these pods are also managed by a deployment.

1. Use the [guestbook-controller.yaml](guestbook-controller.yaml) file to create the guestbook replication controller by running the `kubectl create -f` *`filename`* command:
1. Use the [guestbook-controller.yaml](guestbook-controller.yaml) file to create the guestbook deployment by running the `kubectl apply -f` *`filename`* command:

```console
$ kubectl create -f guestbook-go/guestbook-controller.yaml
$ kubectl apply -f guestbook-controller.yaml

```

Tip: If you want to modify the guestbook code open the `_src` of this example and read the README.md and the Makefile. If you have pushed your custom image be sure to update the `image` accordingly in the guestbook-controller.yaml.

2. To verify that the guestbook replication controller is running, run the `kubectl get rc` command:
2. To verify that the guestbook deployment is running, run the `kubectl get deployment` command:

```console
$ kubectl get rc
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
guestbook guestbook registry.k8s.io/guestbook:v3 app=guestbook 3
redis-replica redis-replica registry.k8s.io/redis-replica:v2 app=redis,role=replica 2
$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
guestbook 3/3 3 3 2m
redis-master 1/1 1 1 23m
redis-replica 2/2 2 2 6m
...
```

3. 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:

```console
$ 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-5b97bdb85f-vvk28 1/1 Running 0 23m
redis-replica-b6wj4 1/1 Running 0 6m
redis-replica-iai40 1/1 Running 0 6m
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-replica-b6wj4 1/1 Running 0 6m
redis-replica-iai40 1/1 Running 0 6m
...
```

Expand All @@ -202,10 +200,10 @@ This is a simple Go `net/http` ([negroni](https://github.com/codegangsta/negroni

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"`.

1. Use the [guestbook-service.yaml](guestbook-service.yaml) file to create the guestbook service by running the `kubectl create -f` *`filename`* command:
1. Use the [guestbook-service.yaml](guestbook-service.yaml) file to create the guestbook service by running the `kubectl apply -f` *`filename`* command:

```console
$ kubectl create -f guestbook-go/guestbook-service.yaml
$ kubectl apply -f guestbook-service.yaml
```


Expand All @@ -216,7 +214,7 @@ Just like the others, we create a service to group the guestbook pods but this t
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-replica 10.0.21.92 <none> 6379/TCP app-redis,role=replica 1h
redis-replica 10.0.21.92 <none> 6379/TCP app=redis,role=replica 1h
...
```

Expand Down Expand Up @@ -246,15 +244,15 @@ You can now play with the guestbook that you just created by opening it in a bro

### Step Eight: Cleanup <a id="step-eight"></a>

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.
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 deployments and services.

Delete all the resources by running the following `kubectl delete -f` *`filename`* command:

```console
$ kubectl delete -f guestbook-go
guestbook-controller
guestbook
redid-master-controller
redis-master-controller
redis-master
redis-replica-controller
redis-replica
Expand Down
7 changes: 4 additions & 3 deletions web/guestbook-go/guestbook-controller.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
kind: ReplicationController
apiVersion: v1
kind: Deployment
apiVersion: apps/v1
metadata:
name: guestbook
labels:
app: guestbook
spec:
replicas: 3
selector:
app: guestbook
matchLabels:
app: guestbook
template:
metadata:
labels:
Expand Down
9 changes: 5 additions & 4 deletions web/guestbook-go/redis-replica-controller.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
kind: ReplicationController
apiVersion: v1
kind: Deployment
apiVersion: apps/v1
metadata:
name: redis-replica
labels:
Expand All @@ -8,8 +8,9 @@ metadata:
spec:
replicas: 2
selector:
app: redis
role: replica
matchLabels:
app: redis
role: replica
template:
metadata:
labels:
Expand Down