BookInfo

Running BookInfo application with different policies.

The tutorial sets up Istio BookInfo application in different clusters. The tutorial demonstrates the use of AccessPolicy and PrivilegedAccessPolicy custom resources. The tutorial shows different load-balancing policies like: random, round-robin or static destination. For more details, see the policies documentation. This test creates three kind clusters:

  • Two Product-Page microservice (application frontend) and details microservice run on the first cluster.
  • The Reviews-V2 (display rating with black stars) and Rating microservices run on the second cluster.
  • The Reviews-V3 (display rating with red stars) and Rating microservices run on the third cluster.

System illustration:

drawing
  1. Install ClusterLink CLI on Linux or Mac using the installation script:

    curl -L https://github.com/clusterlink-net/clusterlink/releases/latest/download/clusterlink.sh | sh -
    
  2. Verify the installation:

    clusterlink --version
    

Initialize clusters

In this tutorial we set up a local environment using kind.

To setup three kind clusters:

  1. Install kind using kind installation guide.

  2. Create a directory for all the tutorial files:

    mkdir bookinfo-tutorial && cd bookinfo-tutorial
    
  3. create three kind clusters:

    kind create cluster --name=client
    kind create cluster --name=server1
    kind create cluster --name=server2
    

    Note

    kind uses the prefix kind, so the name of created clusters will be kind-client, kind-server1, and kind-server2.

Deploy BookInfo application

Install the BookInfo application on the clusters:

export BOOKINFO_FILES=https://raw.githubusercontent.com/clusterlink-net/clusterlink/main/demos/bookinfo/manifests
kubectl config use-context kind-client
kubectl apply -f $BOOKINFO_FILES/product/product.yaml
kubectl apply -f $BOOKINFO_FILES/product/product2.yaml
kubectl apply -f $BOOKINFO_FILES/product/details.yaml

kubectl config use-context kind-server1
kubectl apply -f $BOOKINFO_FILES/review/review-v2.yaml
kubectl apply -f $BOOKINFO_FILES/review/rating.yaml

kubectl config use-context kind-server2
kubectl apply -f $BOOKINFO_FILES/review/review-v3.yaml
kubectl apply -f $BOOKINFO_FILES/review/rating.yaml
  1. Create the fabric and peer certificates and deploy ClusterLink to the clusters:

    Client cluster:

    clusterlink create fabric
    
    kubectl config use-context kind-client
    clusterlink create peer-cert --name client
    clusterlink deploy peer --name client --ingress=NodePort --ingress-port=30443
    
    kubectl config use-context kind-server1
    clusterlink create peer-cert --name server1
    clusterlink deploy peer --name server1 --ingress=NodePort --ingress-port=30443
    
    kubectl config use-context kind-server2
    clusterlink create peer-cert --name server2
    clusterlink deploy peer --name server2 --ingress=NodePort --ingress-port=30443
    

    Note

    This tutorial uses NodePort to create an external access point for the kind clusters. By default deploy peer creates an ingress of type LoadBalancer, which is more suitable for Kubernetes clusters running in the cloud.

  2. Verify that ClusterLink control and data plane components are running:

    It may take a few seconds for the deployments to be successfully created.

    kubectl rollout status deployment cl-controlplane -n clusterlink-system
    kubectl rollout status deployment cl-dataplane -n clusterlink-system
    
Sample output
deployment "cl-controlplane" successfully rolled out
deployment "cl-dataplane" successfully rolled out

Enable cross-cluster access

In this step, we enable connectivity access for the BookInfo application by connecting the ProductPage service (client) to the reviews-v2 service (server1) and reviews-v3 (server2). We establish connections between the peers, export the reviews service on the server side, import the reviews service on the client side, and create a policy to allow the connection.

Note that the provided YAML configuration files refer to environment variables (defined below) that should be set when running the tutorial. The values are replaced in the YAMLs using envsubst utility.

Installing envsubst on macOS

In case envsubst does not exist, you can install it with:

brew install gettext
brew link --force gettext
kubectl config use-context kind-client
export SERVER1_IP=`docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' server1-control-plane`
curl -s $BOOKINFO_FILES/clusterlink/peer-server1.yaml | envsubst | kubectl apply -f -
export SERVER2_IP=`docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' server2-control-plane`
curl -s $BOOKINFO_FILES/clusterlink/peer-server2.yaml | envsubst | kubectl apply -f -
kubectl apply -f $BOOKINFO_FILES/clusterlink/import-reviews.yaml
kubectl apply -f $BOOKINFO_FILES/clusterlink/allow-policy.yaml

kubectl config use-context kind-server1
export CLIENT_IP=`docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' client-control-plane`
curl -s $BOOKINFO_FILES/clusterlink/peer-client.yaml | envsubst | kubectl apply -f -
kubectl apply -f $BOOKINFO_FILES/clusterlink/export-reviews.yaml
kubectl apply -f $BOOKINFO_FILES/clusterlink/allow-policy.yaml

kubectl config use-context kind-server2
export CLIENT_IP=`docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' client-control-plane`
curl -s $BOOKINFO_FILES/clusterlink/peer-client.yaml | envsubst | kubectl apply -f -
kubectl apply -f $BOOKINFO_FILES/clusterlink/export-reviews.yaml
kubectl apply -f $BOOKINFO_FILES/clusterlink/allow-policy.yaml

BookInfo test

To run the BookInfo application use a Firefox web browser to connect the ProductPage microservice:

kubectl config use-context kind-client
firefox http://$CLIENT_IP:30001/productpage
firefox http://$CLIENT_IP:30002/productpage

Note

By default, a round-robin policy is set.

Apply privileged access policy

In the previous steps, an unprivileged access policy was set to allow connectivity. To enforce high-priority policy use the PrivilegedAccessPolicy CRD. In this example, we enforce that the ProductPage service can access only reviews-v3 from server2, and deny all services from server1:

kubectl config use-context kind-client
kubectl apply -f $BOOKINFO_FILES/clusterlink/deny-server1-policy.yaml
echo "
apiVersion: clusterlink.net/v1alpha1
kind: PrivilegedAccessPolicy
metadata:
  name: deny-from-server1
spec:
  action: deny
  from:
    - workloadSelector: {}
  to:
    - workloadSelector: {
      matchLabels: {
                    clusterlink/metadata.gatewayName: server1
                }
    }
" | kubectl apply -f -

To remove the privileged access policy use the following command:

kubectl delete -f $BOOKINFO_FILES/clusterlink/deny-server1-policy.yaml
echo "
apiVersion: clusterlink.net/v1alpha1
kind: PrivilegedAccessPolicy
metadata:
  name: deny-from-server1
spec:
  action: deny
  from:
    - workloadSelector: {}
  to:
    - workloadSelector: {
      matchLabels: {
                    clusterlink/metadata.gatewayName: server1
                }
    }
" | kubectl delete -f -

For more details regarding policy configuration, see policies documentation.

Apply random load-balancing policy

To apply a random load-balancing policy on connection to reviews import:

kubectl config use-context kind-client
kubectl apply -f $BOOKINFO_FILES/clusterlink/import-reviews-lb-random.yaml
echo "
apiVersion: clusterlink.net/v1alpha1
kind: Import
metadata:
  name: reviews
  namespace: default
spec:
  port:       9080
  sources:
    - exportName:       reviews
      exportNamespace:  default
      peer:             server1
    - exportName:       reviews
      exportNamespace:  default
      peer:             server2
  lbScheme: random

" | kubectl apply -f -

Apply static load balancing policy

To apply a static policy that selects the first peer in the sources array and uses the other peer for failover cases, use the following:

kubectl config use-context kind-client
kubectl apply -f $BOOKINFO_FILES/clusterlink/import-reviews-lb-static.yaml
echo "
apiVersion: clusterlink.net/v1alpha1
kind: Import
metadata:
  name: reviews
  namespace: default
spec:
  port:       9080
  sources:
    - exportName:       reviews
      exportNamespace:  default
      peer:             server1
    - exportName:       reviews
      exportNamespace:  default
      peer:             server2
  lbScheme: static

" | kubectl apply -f -

Apply round-robin load-balancing policy

To apply a round-robin load-balancing policy (which is used by default) to the connection to reviews import:

kubectl config use-context kind-client
kubectl apply -f $BOOKINFO_FILES/clusterlink/import-reviews.yaml
echo "
apiVersion: clusterlink.net/v1alpha1
kind: Import
metadata:
  name: reviews
  namespace: default
spec:
  port:       9080
  sources:
    - exportName:       reviews
      exportNamespace:  default
      peer:             server1
    - exportName:       reviews
      exportNamespace:  default
      peer:             server2
  lbScheme: round-robin

" | kubectl apply -f -

Cleanup

  1. Delete the kind clusters:

    kind delete cluster --name=client
    kind delete cluster --name=server1
    kind delete cluster --name=server2
    
  2. Remove the tutorial directory:

    cd .. && rm -rf bookinfo-tutorial
    
  3. Unset the environment variables:

    unset BOOKINFO_FILES CLIENT_IP SERVER1_IP SERVER2_IP