Multi-Cluster Slice: BookInfo Deployment
Introduction
BookInfo is a sample application from Istio that is composed of four separate microservices: productpage, details, reviews, and ratings. In this topic, we will use the BookInfo application to demonstrate inter-slice communication.
Objective
This tutorial is designed to aid you in improving your understanding of deploying applications.
Prerequisites
Before you begin, ensure the following prerequisites are met:
- You have a KubeSlice configuration with two or more clusters registered. For more information, see Install KubeSlice.
- You have Istio installed in all registered worker clusters. For more information, see Install Istio.
- Before creating a slice, create the
bookinfo
namespace in all the participating worker clusters. Use the following command to create thebookinfo
namespace:kubectl create ns bookinfo
- Use the following command to inject the istio label to the
bookinfo
namespace:kubectl label namespace bookinfo istio-injection=enabled
- You have the slice created across the worker clusters. For more information, see creating a slice.
Create the BookInfo Deployment YAML Files
Using the templates below, create the configuration YAML files to deploy the BookInfo application.
These instructions will guide you through deploying the productpage service to a cluster we will
refer to as the productpage cluster
. The other services and service exports will
be deployed to a cluster referred to here as the services cluster
.
Product Page
Create the productpage.yaml
file using the below template.
All the fields in the template remain the same except for the <slice name>
. Replace the <slice name>
with the name of your slice.
##################################################################################################
# Productpage Service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: productpage
labels:
app: productpage
service: productpage
spec:
type: NodePort
ports:
- port: 9080
name: http
selector:
app: productpage
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-productpage
labels:
account: productpage
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: productpage-v1
labels:
app: productpage
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: productpage
version: v1
template:
metadata:
labels:
app: productpage
version: v1
spec:
serviceAccountName: bookinfo-productpage
containers:
- name: productpage
image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
securityContext:
runAsUser: 1000
env:
- name: REVIEWS_HOSTNAME
value: reviews.bookinfo.svc.slice.local
- name: DETAILS_HOSTNAME
value: details.bookinfo.svc.slice.local
- name: netshoot
image: nicolaka/netshoot
imagePullPolicy: IfNotPresent
command: ["/bin/sleep", "3650d"]
securityContext:
capabilities:
add: ["NET_ADMIN"]
allowPrivilegeEscalation: true
privileged: true
volumes:
- name: tmp
emptyDir: {}
Details
Create the details.yaml
file using the below template.
All the fields in the template remain the same except for the <slice name>
. Replace the <slice name>
with the name of your slice.
##################################################################################################
# Details Service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: details
labels:
app: details
service: details
spec:
ports:
- port: 9080
name: http
selector:
app: details
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-details
labels:
account: details
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: details-v1
labels:
app: details
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: details
version: v1
template:
metadata:
labels:
app: details
version: v1
spec:
serviceAccountName: bookinfo-details
containers:
- name: details
image: docker.io/istio/examples-bookinfo-details-v1:1.16.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
- name: netshoot
image: nicolaka/netshoot
imagePullPolicy: IfNotPresent
command: ["/bin/sleep", "3650d"]
securityContext:
capabilities:
add: ["NET_ADMIN"]
allowPrivilegeEscalation: true
privileged: true
Ratings
Create the ratings.yaml
file using the below template.
All the fields in the template remain the same except for the <slice name>
. Replace the <slice name>
with the name of your slice.
##################################################################################################
# Ratings Service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: ratings
labels:
app: ratings
service: ratings
spec:
ports:
- port: 9080
name: http
selector:
app: ratings
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-ratings
labels:
account: ratings
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ratings-v1
labels:
app: ratings
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: ratings
version: v1
template:
metadata:
labels:
app: ratings
version: v1
spec:
serviceAccountName: bookinfo-ratings
containers:
- name: ratings
image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
- name: netshoot
image: nicolaka/netshoot
imagePullPolicy: IfNotPresent
command: ["/bin/sleep", "3650d"]
securityContext:
capabilities:
add: ["NET_ADMIN"]
allowPrivilegeEscalation: true
privileged: true
Reviews
Create the reviews.yaml
file using the below template.
All the fields in the template remain the same except for the <slice name>
. Replace the <slice name>
with the name of your slice.
##################################################################################################
# Reviews Service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: reviews
labels:
app: reviews
service: reviews
spec:
ports:
- port: 9080
name: http
selector:
app: reviews
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-reviews
labels:
account: reviews
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v3
labels:
app: reviews
version: v3
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v3
template:
metadata:
labels:
app: reviews
version: v3
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v3:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
- name: netshoot
image: nicolaka/netshoot
imagePullPolicy: IfNotPresent
command: ["/bin/sleep", "3650d"]
securityContext:
capabilities:
add: ["NET_ADMIN"]
allowPrivilegeEscalation: true
privileged: true
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
ServiceExports
Create the serviceexports.yaml
file using the below template.
All the fields in the template remain the same except for <slice name>
instances. Replace
the <slice name>
with the name of your slice.
##################################################################################
# Details ServiceExport
##################################################################################
apiVersion: networking.kubeslice.io/v1beta1
kind: ServiceExport
metadata:
name: details
spec:
slice: <slice name> #Replace Slice Name
selector:
matchLabels:
app: details
ingressEnabled: false
ports:
- name: http
containerPort: 9080
protocol: TCP
---
##################################################################################
# Reviews ServiceExport
##################################################################################
apiVersion: networking.kubeslice.io/v1beta1
kind: ServiceExport
metadata:
name: reviews
spec:
slice: <slice name> #Replace Slice Name
selector:
matchLabels:
app: reviews
ingressEnabled: false
ports:
- name: http
containerPort: 9080
protocol: TCP
Deploy to the Productpage Cluster
To deploy the productpage:
-
Switch the context to the cluster you will be deploying the productpage using the following command:
kubectx <services cluster>
-
Apply the
productpage.yaml
file using the following command:kubectl apply -f productpage.yaml -n bookinfo
Expected Output:
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created -
Check if the deployed productpage pod is running on the cluster using the following command:
kubectl get pods -n bookinfo
Expected Output
NAME READY STATUS RESTARTS AGE
productpage-v1-5cc46fc6dc-drd8b 4/4 Running 0 26h
Deploy to the Service Cluster
Use the following command to ensure we are targeting the cluster we deploy reviews, details, and ratings to:
kubectx <services cluster>
Using the following commands, apply the details.yaml, ratings.yaml, reviews.yaml, and serviceexports.yaml files.
Use the following command to apply the details.yaml
file.
kubectl apply -f details.yaml -n bookinfo
Expected Output
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
Use the following command to apply the ratings.yaml
file:
kubectl apply -f ratings.yaml -n bookinfo
Expected Output
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
Use the following command to apply the reviews.yaml
file:
kubectl apply -f reviews.yaml -n bookinfo
Expected Output
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v3 created
Use the following command to verify if the deployed pods are running on the cluster:
kubectl get pods -n bookinfo
Expected Output
NAME READY STATUS RESTARTS AGE
details-v1-557b474454-fbfhh 4/4 Running 0 26h
ratings-v1-5846f848bb-4dwtz 4/4 Running 0 26h
reviews-v3-64cf7654f4-cfqz8 4/4 Running 0 26h
Use the following command to apply serviceexports.yaml
file:
kubectl apply -f serviceexports.yaml -n bookinfo
Expected Output
serviceexport.networking.kubeslice.io/details created
serviceexport.networking.kubeslice.io/reviews created
Validate the Services
To validate the Details and Review services:
-
Switch the context to the
services
cluster.kubectx <services cluster>
-
Use the following command to verify the details and reviews services have been successfully exported to the KubeSlice configuration:
kubectl get serviceexport -n bookinfo
Expected Output
NAME SLICE INGRESS SERVICEPORT(S) PORT(S) ENDPOINTS STATUS
details white true 9080/TCP 1 READY
reviews white true 9080/TCP 1 READY
Validate the Productpage on the Cloud Cluster
To validate the Productpage service:
-
Switch the context to the
productpage
cluster.kubectx <productpage cluster>
-
Using the following command, verify the details and reviews service imports are present in the cluster:
kubectl get serviceimport -n bookinfo
Expected Output
NAME SLICE PORT(S) ENDPOINTS STATUS
details white 9080/TCP 1 READY
reviews white 9080/TCP 1 READY -
Use the following command to check the exposed port for the
productpage
service.kubectl get services -n bookinfo
Expected Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.0.116.23 <none> 9080/TCP 2d2h
productpage NodePort 10.0.20.209 <none> 9080:31194/TCP 2d2h
reviews ClusterIP 10.0.146.220 <none> 9080/TCP 2d2hinfoUse the exposed port for the
productpage
service to visit the BookInfo webpage. -
To view the deployed BookInfo product page, we need the external IP address of an application node and the exposed port we just retrieved.
infoTake note of the external IP address of one of the application nodes to use it later.
Use the following command to get your node details:
kubectl get nodes -o wide
Expected Output (your output will differ, here we are just focused on the external IP address).
kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE
KERNEL-VERSION CONTAINER-RUNTIME
gke-preprod-knative--preprod-knative--aba5a0cc-9jrq Ready <none> 27h v1.20.15-gke.3600 10.6.0.4 35.231.181.81 Container-Optimized OS from Google 5.4.170+ containerd://1.4.8
gke-preprod-knative--preprod-knative--aba5a0cc-xj3j Ready <none> 27h v1.20.15-gke.3600 10.6.0.5 35.243.229.81 Container-Optimized OS from Google 5.4.170+ containerd://1.4.8
gke-preprod-knative--preprod-knative--d19d3a9f-c32x Ready <none> 28h v1.20.15-gke.3600 10.6.0.3 104.196.200.27 Container-Optimized OS from Google 5.4.170+ containerd://1.4.8 -
Combine the external IP address the command returns with the port you retrieved in the last step in the format below. Visit the page in a browser to view your multi-cluster BookInfo deployment.
http://<external ip>:<port>/productpage
Example
You have successfully deployed the BookInfo application on a KubeSlice configuration containing at least two clusters.
Uninstall BookInfo
To uninstall BookInfo from your KubeSlice configuration, the instructions in uninstall KubeSlice.