2017-06-23 19:23:36 +00:00
---
2021-06-17 04:45:11 +00:00
title: "Example: Deploying PHP Guestbook application with Redis"
2018-02-18 20:13:37 +00:00
reviewers:
2017-08-19 00:19:11 +00:00
- ahmetb
2021-06-17 04:45:11 +00:00
- jimangel
2020-05-30 19:10:23 +00:00
content_type: tutorial
2018-05-15 22:29:27 +00:00
weight: 20
2019-02-21 16:24:20 +00:00
card:
name: tutorials
weight: 30
2021-06-17 04:45:11 +00:00
title: "Stateless Example: PHP Guestbook with Redis"
2020-08-03 19:50:11 +00:00
min-kubernetes-server-version: v1.14
2021-06-17 04:45:11 +00:00
source: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
2017-06-23 19:23:36 +00:00
---
2020-05-30 19:10:23 +00:00
<!-- overview -->
2021-06-18 02:43:51 +00:00
This tutorial shows you how to build and deploy a simple _(not production
ready)_, multi-tier web application using Kubernetes and
[Docker ](https://www.docker.com/ ). This example consists of the following
components:
2017-06-23 19:23:36 +00:00
2021-07-05 11:17:30 +00:00
* A single-instance [Redis ](https://www.redis.io/ ) to store guestbook entries
2017-08-07 22:56:20 +00:00
* Multiple web frontend instances
2017-06-23 19:23:36 +00:00
2020-05-30 19:10:23 +00:00
## {{% heading "objectives" %}}
2021-06-17 04:45:11 +00:00
* Start up a Redis leader.
* Start up two Redis followers.
2017-08-07 22:56:20 +00:00
* Start up the guestbook frontend.
* Expose and view the Frontend Service.
* Clean up.
2017-06-23 19:23:36 +00:00
2020-05-30 19:10:23 +00:00
## {{% heading "prerequisites" %}}
2018-07-17 06:00:38 +00:00
{{< include " task-tutorial-prereqs . md " > }}
2017-06-23 19:23:36 +00:00
2018-07-17 06:00:38 +00:00
{{< version-check > }}
2017-06-23 19:23:36 +00:00
2020-05-30 19:10:23 +00:00
<!-- lessoncontent -->
2017-06-23 19:23:36 +00:00
2021-06-17 04:45:11 +00:00
## Start up the Redis Database
2017-06-23 19:23:36 +00:00
2021-06-17 04:45:11 +00:00
The guestbook application uses Redis to store its data.
2017-06-23 19:23:36 +00:00
2021-06-17 04:45:11 +00:00
### Creating the Redis Deployment
2017-06-23 19:23:36 +00:00
2021-06-17 04:45:11 +00:00
The manifest file, included below, specifies a Deployment controller that runs a single replica Redis Pod.
2017-06-23 19:23:36 +00:00
2021-06-17 04:45:11 +00:00
{{< codenew file = "application/guestbook/redis-leader-deployment.yaml" > }}
2018-07-02 20:06:18 +00:00
2017-08-07 22:56:20 +00:00
1. Launch a terminal window in the directory you downloaded the manifest files.
2021-06-17 04:45:11 +00:00
1. Apply the Redis Deployment from the `redis-leader-deployment.yaml` file:
2018-07-02 20:06:18 +00:00
2021-06-18 02:43:51 +00:00
<!-- -
for local testing of the content via relative file path
kubectl apply -f ./content/en/examples/application/guestbook/redis-leader-deployment.yaml
-->
2021-04-01 03:42:41 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-deployment.yaml
```
2018-07-02 20:06:18 +00:00
2021-06-17 04:45:11 +00:00
1. Query the list of Pods to verify that the Redis Pod is running:
2018-07-02 20:06:18 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl get pods
```
2018-07-02 20:06:18 +00:00
2021-06-18 02:43:51 +00:00
The response should be similar to this:
2018-07-02 20:06:18 +00:00
2021-06-18 02:43:51 +00:00
```
NAME READY STATUS RESTARTS AGE
redis-leader-fb76b4755-xjr2n 1/1 Running 0 13s
```
2018-07-02 20:06:18 +00:00
2021-06-17 04:45:11 +00:00
1. Run the following command to view the logs from the Redis leader Pod:
2018-07-02 20:06:18 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl logs -f deployment/redis-leader
```
2018-07-02 20:06:18 +00:00
2021-06-17 04:45:11 +00:00
### Creating the Redis leader Service
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
The guestbook application needs to communicate to the Redis to write its data.
You need to apply a [Service ](/docs/concepts/services-networking/service/ ) to
proxy the traffic to the Redis Pod. A Service defines a policy to access the
Pods.
2017-06-23 19:23:36 +00:00
2021-06-17 04:45:11 +00:00
{{< codenew file = "application/guestbook/redis-leader-service.yaml" > }}
2018-07-02 20:06:18 +00:00
2021-06-17 04:45:11 +00:00
1. Apply the Redis Service from the following `redis-leader-service.yaml` file:
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
<!-- -
for local testing of the content via relative file path
kubectl apply -f ./content/en/examples/application/guestbook/redis-leader-service.yaml
-->
2021-04-01 03:42:41 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-service.yaml
```
2018-07-02 20:06:18 +00:00
2021-06-17 04:45:11 +00:00
1. Query the list of Services to verify that the Redis Service is running:
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl get service
```
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
The response should be similar to this:
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
```
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 < none > 443/TCP 1m
redis-leader ClusterIP 10.103.78.24 < none > 6379/TCP 16s
```
2018-07-02 20:06:18 +00:00
{{< note > }}
2021-06-18 02:43:51 +00:00
This manifest file creates a Service named `redis-leader` with a set of labels
that match the labels previously defined, so the Service routes network
traffic to the Redis Pod.
2018-07-02 20:06:18 +00:00
{{< / note > }}
2017-06-23 19:23:36 +00:00
2021-06-17 04:45:11 +00:00
### Set up Redis followers
2021-06-18 02:43:51 +00:00
Although the Redis leader is a single Pod, you can make it highly available
and meet traffic demands by adding a few Redis followers, or replicas.
2021-06-17 04:45:11 +00:00
{{< codenew file = "application/guestbook/redis-follower-deployment.yaml" > }}
2021-06-18 02:43:51 +00:00
1. Apply the Redis Deployment from the following `redis-follower-deployment.yaml` file:
2021-06-17 04:45:11 +00:00
2021-06-18 02:43:51 +00:00
<!-- -
for local testing of the content via relative file path
kubectl apply -f ./content/en/examples/application/guestbook/redis-follower-deployment.yaml
-->
2021-06-17 04:45:11 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-deployment.yaml
```
2021-06-17 04:45:11 +00:00
1. Verify that the two Redis follower replicas are running by querying the list of Pods:
2021-06-18 02:43:51 +00:00
```shell
kubectl get pods
```
2021-06-17 04:45:11 +00:00
2021-06-18 02:43:51 +00:00
The response should be similar to this:
2021-06-17 04:45:11 +00:00
2021-06-18 02:43:51 +00:00
```
NAME READY STATUS RESTARTS AGE
redis-follower-dddfbdcc9-82sfr 1/1 Running 0 37s
redis-follower-dddfbdcc9-qrt5k 1/1 Running 0 38s
redis-leader-fb76b4755-xjr2n 1/1 Running 0 11m
```
2021-06-17 04:45:11 +00:00
### Creating the Redis follower service
2021-06-18 02:43:51 +00:00
The guestbook application needs to communicate with the Redis followers to
read data. To make the Redis followers discoverable, you must set up another
[Service ](/docs/concepts/services-networking/service/ ).
2021-06-17 04:45:11 +00:00
{{< codenew file = "application/guestbook/redis-follower-service.yaml" > }}
1. Apply the Redis Service from the following `redis-follower-service.yaml` file:
2021-06-18 02:43:51 +00:00
<!-- -
for local testing of the content via relative file path
kubectl apply -f ./content/en/examples/application/guestbook/redis-follower-service.yaml
-->
2021-06-17 04:45:11 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-service.yaml
```
2021-06-17 04:45:11 +00:00
1. Query the list of Services to verify that the Redis Service is running:
2021-06-18 02:43:51 +00:00
```shell
kubectl get service
```
2021-06-17 04:45:11 +00:00
2021-06-18 02:43:51 +00:00
The response should be similar to this:
2021-06-17 04:45:11 +00:00
2021-06-18 02:43:51 +00:00
```
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 < none > 443/TCP 3d19h
redis-follower ClusterIP 10.110.162.42 < none > 6379/TCP 9s
redis-leader ClusterIP 10.103.78.24 < none > 6379/TCP 6m10s
```
2021-06-17 04:45:11 +00:00
{{< note > }}
2021-06-18 02:43:51 +00:00
This manifest file creates a Service named `redis-follower` with a set of
labels that match the labels previously defined, so the Service routes network
traffic to the Redis Pod.
2021-06-17 04:45:11 +00:00
{{< / note > }}
2017-06-23 19:23:36 +00:00
2017-08-07 22:56:20 +00:00
## Set up and Expose the Guestbook Frontend
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
Now that you have the Redis storage of your guestbook up and running, start
the guestbook web servers. Like the Redis followers, the frontend is deployed
using a Kubernetes Deployment.
2021-06-17 04:45:11 +00:00
2021-06-18 02:43:51 +00:00
The guestbook app uses a PHP frontend. It is configured to communicate with
either the Redis follower or leader Services, depending on whether the request
is a read or a write. The frontend exposes a JSON interface, and serves a
jQuery-Ajax-based UX.
2017-06-23 19:23:36 +00:00
2017-08-07 22:56:20 +00:00
### Creating the Guestbook Frontend Deployment
2017-06-23 19:23:36 +00:00
2018-07-02 20:06:18 +00:00
{{< codenew file = "application/guestbook/frontend-deployment.yaml" > }}
2017-06-23 19:23:36 +00:00
2018-07-02 20:06:18 +00:00
1. Apply the frontend Deployment from the `frontend-deployment.yaml` file:
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
<!-- -
for local testing of the content via relative file path
kubectl apply -f ./content/en/examples/application/guestbook/frontend-deployment.yaml
-->
2021-04-01 03:42:41 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml
```
2017-06-23 19:23:36 +00:00
2018-07-02 20:06:18 +00:00
1. Query the list of Pods to verify that the three frontend replicas are running:
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl get pods -l app=guestbook -l tier=frontend
```
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
The response should be similar to this:
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
```
NAME READY STATUS RESTARTS AGE
frontend-85595f5bf9-5tqhb 1/1 Running 0 47s
frontend-85595f5bf9-qbzwm 1/1 Running 0 47s
frontend-85595f5bf9-zchwc 1/1 Running 0 47s
```
2017-06-23 19:23:36 +00:00
2017-08-07 22:56:20 +00:00
### Creating the Frontend Service
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
The `Redis` Services you applied is only accessible within the Kubernetes
cluster because the default type for a Service is
[ClusterIP ](/docs/concepts/services-networking/service/#publishing-services-service-types ).
`ClusterIP` provides a single IP address for the set of Pods the Service is
pointing to. This IP address is accessible only within the cluster.
2017-08-07 22:56:20 +00:00
2021-06-18 02:43:51 +00:00
If you want guests to be able to access your guestbook, you must configure the
frontend Service to be externally visible, so a client can request the Service
from outside the Kubernetes cluster. However a Kubernetes user you can use
`kubectl port-forward` to access the service even though it uses a
`ClusterIP` .
2017-08-07 22:56:20 +00:00
2018-05-05 16:00:51 +00:00
{{< note > }}
2021-06-18 02:43:51 +00:00
Some cloud providers, like Google Compute Engine or Google Kubernetes Engine,
support external load balancers. If your cloud provider supports load
balancers and you want to use it, uncomment `type: LoadBalancer` .
2018-05-05 16:00:51 +00:00
{{< / note > }}
2017-08-07 22:56:20 +00:00
2018-07-02 20:06:18 +00:00
{{< codenew file = "application/guestbook/frontend-service.yaml" > }}
2017-08-07 22:56:20 +00:00
2018-07-02 20:06:18 +00:00
1. Apply the frontend Service from the `frontend-service.yaml` file:
2017-08-07 22:56:20 +00:00
2021-06-18 02:43:51 +00:00
<!-- -
for local testing of the content via relative file path
kubectl apply -f ./content/en/examples/application/guestbook/frontend-service.yaml
-->
2021-04-01 03:42:41 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-service.yaml
```
2017-08-07 22:56:20 +00:00
2018-07-02 20:06:18 +00:00
1. Query the list of Services to verify that the frontend Service is running:
2017-08-07 22:56:20 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl get services
```
2017-08-07 22:56:20 +00:00
2021-06-18 02:43:51 +00:00
The response should be similar to this:
2018-07-02 20:06:18 +00:00
2021-06-18 02:43:51 +00:00
```
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend ClusterIP 10.97.28.230 < none > 80/TCP 19s
kubernetes ClusterIP 10.96.0.1 < none > 443/TCP 3d19h
redis-follower ClusterIP 10.110.162.42 < none > 6379/TCP 5m48s
redis-leader ClusterIP 10.103.78.24 < none > 6379/TCP 11m
```
2017-08-07 22:56:20 +00:00
2020-08-03 19:50:11 +00:00
### Viewing the Frontend Service via `kubectl port-forward`
2017-08-07 22:56:20 +00:00
2020-08-03 19:50:11 +00:00
1. Run the following command to forward port `8080` on your local machine to port `80` on the service.
2017-08-07 22:56:20 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl port-forward svc/frontend 8080:80
```
2017-08-07 22:56:20 +00:00
2021-06-18 02:43:51 +00:00
The response should be similar to this:
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
```
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
```
2017-06-23 19:23:36 +00:00
2020-08-03 19:50:11 +00:00
1. load the page [http://localhost:8080 ](http://localhost:8080 ) in your browser to view your guestbook.
2017-06-23 19:23:36 +00:00
2017-08-07 22:56:20 +00:00
### Viewing the Frontend Service via `LoadBalancer`
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
If you deployed the `frontend-service.yaml` manifest with type: `LoadBalancer`
you need to find the IP address to view your Guestbook.
2017-06-23 19:23:36 +00:00
2017-08-07 22:56:20 +00:00
1. Run the following command to get the IP address for the frontend Service.
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl get service frontend
```
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
The response should be similar to this:
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
```
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.51.242.136 109.197.92.229 80:32372/TCP 1m
```
2017-06-23 19:23:36 +00:00
2018-07-02 20:06:18 +00:00
1. Copy the external IP address, and load the page in your browser to view your guestbook.
2017-06-23 19:23:36 +00:00
2021-06-17 04:45:11 +00:00
{{< note > }}
2021-06-18 02:43:51 +00:00
Try adding some guestbook entries by typing in a message, and clicking Submit.
The message you typed appears in the frontend. This message indicates that
data is successfully added to Redis through the Services you created earlier.
2021-06-17 04:45:11 +00:00
{{< / note > }}
2019-04-30 19:38:56 +00:00
## Scale the Web Frontend
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
You can scale up or down as needed because your servers are defined as a
Service that uses a Deployment controller.
2017-06-23 19:23:36 +00:00
2017-08-07 22:56:20 +00:00
1. Run the following command to scale up the number of frontend Pods:
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl scale deployment frontend --replicas=5
```
2017-06-23 19:23:36 +00:00
2018-07-02 20:06:18 +00:00
1. Query the list of Pods to verify the number of frontend Pods running:
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl get pods
```
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
The response should look similar to this:
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
```
NAME READY STATUS RESTARTS AGE
frontend-85595f5bf9-5df5m 1/1 Running 0 83s
frontend-85595f5bf9-7zmg5 1/1 Running 0 83s
frontend-85595f5bf9-cpskg 1/1 Running 0 15m
frontend-85595f5bf9-l2l54 1/1 Running 0 14m
frontend-85595f5bf9-l9c8z 1/1 Running 0 14m
redis-follower-dddfbdcc9-82sfr 1/1 Running 0 97m
redis-follower-dddfbdcc9-qrt5k 1/1 Running 0 97m
redis-leader-fb76b4755-xjr2n 1/1 Running 0 108m
```
2017-06-23 19:23:36 +00:00
2018-07-02 20:06:18 +00:00
1. Run the following command to scale down the number of frontend Pods:
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl scale deployment frontend --replicas=2
```
2017-06-23 19:23:36 +00:00
2018-07-02 20:06:18 +00:00
1. Query the list of Pods to verify the number of frontend Pods running:
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl get pods
```
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
The response should look similar to this:
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
```
NAME READY STATUS RESTARTS AGE
frontend-85595f5bf9-cpskg 1/1 Running 0 16m
frontend-85595f5bf9-l9c8z 1/1 Running 0 15m
redis-follower-dddfbdcc9-82sfr 1/1 Running 0 98m
redis-follower-dddfbdcc9-qrt5k 1/1 Running 0 98m
redis-leader-fb76b4755-xjr2n 1/1 Running 0 109m
```
2019-04-30 19:38:56 +00:00
2020-05-30 19:10:23 +00:00
## {{% heading "cleanup" %}}
2021-06-18 02:43:51 +00:00
Deleting the Deployments and Services also deletes any running Pods. Use
labels to delete multiple resources with one command.
2017-06-23 19:23:36 +00:00
2017-08-07 22:56:20 +00:00
1. Run the following commands to delete all Pods, Deployments, and Services.
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl delete deployment -l app=redis
kubectl delete service -l app=redis
kubectl delete deployment frontend
kubectl delete service frontend
```
2018-07-02 20:06:18 +00:00
2021-06-18 02:43:51 +00:00
The response should look similar to this:
2018-07-02 20:06:18 +00:00
2021-06-18 02:43:51 +00:00
```
deployment.apps "redis-follower" deleted
deployment.apps "redis-leader" deleted
deployment.apps "frontend" deleted
service "frontend" deleted
```
2019-04-30 19:38:56 +00:00
2018-07-02 20:06:18 +00:00
1. Query the list of Pods to verify that no Pods are running:
2017-06-23 19:23:36 +00:00
2021-06-18 02:43:51 +00:00
```shell
kubectl get pods
```
2018-07-02 20:06:18 +00:00
2021-06-18 02:43:51 +00:00
The response should look similar to this:
2018-07-02 20:06:18 +00:00
2021-06-18 02:43:51 +00:00
```
No resources found in default namespace.
```
2017-06-23 19:23:36 +00:00
2020-05-30 19:10:23 +00:00
## {{% heading "whatsnext" %}}
2017-08-19 00:19:11 +00:00
* Complete the [Kubernetes Basics ](/docs/tutorials/kubernetes-basics/ ) Interactive Tutorials
2019-04-30 19:38:56 +00:00
* Use Kubernetes to create a blog using [Persistent Volumes for MySQL and Wordpress ](/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/#visit-your-new-wordpress-blog )
2017-08-19 00:19:11 +00:00
* Read more about [connecting applications ](/docs/concepts/services-networking/connect-applications-service/ )
2021-06-18 02:43:51 +00:00
* Read more about [Managing Resources ](/docs/concepts/cluster-administration/manage-deployment/#using-labels-effectively )