Deploy sample apps

You can install two sample apps in your demo setup: Bookinfo and httpbin. You might also install additional tools such as Keycloak as an OpenID Connect provider. These sample apps are used throughout the documentation to help test connectivity, such as in the policy guides.

Install Bookinfo

To test out microservice traffic management, deploy different versions of the Bookinfo sample app to both of the workload clusters. cluster-1 runs the app with versions 1 and 2 of the reviews service (reviews-v1 and reviews-v2), and cluster-2 runs version 3 of the reviews service (reviews-v3).

  1. Create the bookinfo namespace in each workload cluster.

    kubectl create ns bookinfo --context $REMOTE_CONTEXT1
    kubectl create ns bookinfo --context $REMOTE_CONTEXT2
    
  2. OpenShift clusters only: Create a NetworkAttachmentDefinition custom resource for the bookinfo project of each workload cluster, and elevate the permissions of the bookinfo service account to allow the Istio sidecars to make use of a user ID that is normally restricted by OpenShift. Use the commands in both tabs.

    
    cat <<EOF | oc --context $REMOTE_CONTEXT1 -n bookinfo create -f -
    apiVersion: "k8s.cni.cncf.io/v1"
    kind: NetworkAttachmentDefinition
    metadata:
      name: istio-cni
    EOF
    oc --context $REMOTE_CONTEXT1 adm policy add-scc-to-group anyuid system:serviceaccounts:bookinfo
    
    
    cat <<EOF | oc --context $REMOTE_CONTEXT2 -n bookinfo create -f -
    apiVersion: "k8s.cni.cncf.io/v1"
    kind: NetworkAttachmentDefinition
    metadata:
      name: istio-cni
    EOF
    oc --context $REMOTE_CONTEXT2 adm policy add-scc-to-group anyuid system:serviceaccounts:bookinfo
    

  3. Export the Istio version that your cluster runs as an environment variable, such as 1.16.2 in the following example. You can check your Istio version by running istioctl version --context $REMOTE_CONTEXT1.

    export ISTIO_VERSION=1.16.2
    
  4. Use the commands in both tabs to install Bookinfo with the reviews-v1 and reviews-v2 services in cluster-1, and the reviews-v3 service in cluster-2.

    
    # prepare the bookinfo namespace for Istio sidecar injection
    kubectl --context $REMOTE_CONTEXT1 label namespace bookinfo istio-injection=enabled
    # deploy bookinfo application components for all versions less than v3
    kubectl --context $REMOTE_CONTEXT1 -n bookinfo apply -f https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/bookinfo/platform/kube/bookinfo.yaml -l 'app,version notin (v3)'
    # deploy all bookinfo service accounts
    kubectl --context $REMOTE_CONTEXT1 -n bookinfo apply -f https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/bookinfo/platform/kube/bookinfo.yaml -l 'account'
    
    
    # prepare the bookinfo namespace for Istio sidecar injection
    kubectl --context $REMOTE_CONTEXT2 label namespace bookinfo istio-injection=enabled
    # deploy reviews and ratings services
    kubectl --context $REMOTE_CONTEXT2 -n bookinfo apply -f https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/bookinfo/platform/kube/bookinfo.yaml -l 'service in (reviews)'
    # deploy reviews-v3
    kubectl --context $REMOTE_CONTEXT2 -n bookinfo apply -f https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/bookinfo/platform/kube/bookinfo.yaml -l 'app in (reviews),version in (v3)'
    # deploy ratings
    kubectl --context $REMOTE_CONTEXT2 -n bookinfo apply -f https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/bookinfo/platform/kube/bookinfo.yaml -l 'app in (ratings)'
    # deploy reviews and ratings service accounts
    kubectl --context $REMOTE_CONTEXT2 -n bookinfo apply -f https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/bookinfo/platform/kube/bookinfo.yaml -l 'account in (reviews, ratings)'
    

  5. Verify that the Bookinfo pods are have a status of Running in each cluster. If not, try Troubleshooting.

    kubectl --context $REMOTE_CONTEXT1 get pods -n bookinfo
    kubectl --context $REMOTE_CONTEXT2 get pods -n bookinfo
    

Install httpbin

The httpbin sample app is a simple tool to test HTTP requests and responses. Unlike curl, you can see not only the response headers, but also the request headers. The following examples install httpbin as both an in-mesh, Istio-enabled service, and a separate app outside the service mesh to test external connectivity.

  1. Create an httpbin namespace.
    kubectl --context $REMOTE_CONTEXT1 create ns httpbin
    
  2. Create an httpbin app named in-mesh that is part of the Istio service mesh. The pod has the istio.io/rev label, so an Istio sidecar is injected.
    The example uses Istio 1.14. If you installed a different version of Istio, download the YAML file and update the istio.io/rev value.
    kubectl --context $REMOTE_CONTEXT1 -n httpbin apply -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/httpbin-in-mesh.yaml
    
  3. Create another httpbin app named not-in-mesh that is not part of the Istio service mesh.
    kubectl --context $REMOTE_CONTEXT1 -n httpbin apply -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/httpbin-not-in-mesh.yaml
    
  4. Verify that the httpbin apps are running.
    kubectl --context $REMOTE_CONTEXT1 -n httpbin get pods
    

Install Keycloak

You might want to test how to restrict access to your applications to authenticated users, such as with external auth or JWT policies. You can install Keycloak in your cluster as an OpenID Connect (OIDC) provider.

The following steps install Keycloak in your cluster, and configure two user credentials as follows.

Install and configure Keycloak:

  1. Create a namespace for your Keycloak deployment.

    kubectl --context ${MGMT_CONTEXT} create namespace keycloak
    
  2. Create the Keycloak deployment.

    kubectl --context ${MGMT_CONTEXT} -n keycloak apply -f https://raw.githubusercontent.com/solo-io/workshops/gloo-mesh-demo/gloo-mesh-2-0/data/steps/deploy-keycloak/keycloak.yaml
    
  3. Wait for the Keycloak rollout to finish.

    kubectl --context ${MGMT_CONTEXT} -n keycloak rollout status deploy/keycloak
    
  4. Set the Keycloak endpoint details from the load balancer service.

    export ENDPOINT_KEYCLOAK=$(kubectl --context ${MGMT_CONTEXT} -n keycloak get service keycloak -o jsonpath='{.status.loadBalancer.ingress[0].*}'):8080
    export HOST_KEYCLOAK=$(echo ${ENDPOINT_KEYCLOAK} | cut -d: -f1)
    export PORT_KEYCLOAK=$(echo ${ENDPOINT_KEYCLOAK} | cut -d: -f2)
    export KEYCLOAK_URL=http://${ENDPOINT_KEYCLOAK}/auth
    echo $KEYCLOAK_URL
    
  5. Set the Keycloak admin token. If you see a parsing error, try running the curl command by itself. You might notice that your network is blocking the requests, which might require updating the security settings so that the request can be processed.

    export KEYCLOAK_TOKEN=$(curl -d "client_id=admin-cli" -d "username=admin" -d "password=admin" -d "grant_type=password" "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" | jq -r .access_token)
    echo $KEYCLOAK_TOKEN
    
  6. Use the admin token to configure Keycloak with the two users for testing purposes. If you get a 401 Unauthorized error, run the previous command and try again.

    # Create initial token to register the client
    read -r client token <<<$(curl -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X POST -H "Content-Type: application/json" -d '{"expiration": 0, "count": 1}' $KEYCLOAK_URL/admin/realms/master/clients-initial-access | jq -r '[.id, .token] | @tsv')
    export KEYCLOAK_CLIENT=${client}
    
    # Register the client
    read -r id secret <<<$(curl -X POST -d "{ \"clientId\": \"${KEYCLOAK_CLIENT}\" }" -H "Content-Type:application/json" -H "Authorization: bearer ${token}" ${KEYCLOAK_URL}/realms/master/clients-registrations/default| jq -r '[.id, .secret] | @tsv')
    export KEYCLOAK_SECRET=${secret}
    
    # Add allowed redirect URIs
    curl -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X PUT -H "Content-Type: application/json" -d '{"serviceAccountsEnabled": true, "directAccessGrantsEnabled": true, "authorizationServicesEnabled": true, "redirectUris": ["'https://${ENDPOINT_HTTPS_GW_CLUSTER1}'/callback"]}' $KEYCLOAK_URL/admin/realms/master/clients/${id}
    
    # Add the group attribute in the JWT token returned by Keycloak
    curl -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X POST -H "Content-Type: application/json" -d '{"name": "group", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-attribute-mapper", "config": {"claim.name": "group", "jsonType.label": "String", "user.attribute": "group", "id.token.claim": "true", "access.token.claim": "true"}}' $KEYCLOAK_URL/admin/realms/master/clients/${id}/protocol-mappers/models
    
    # Create first user
    curl -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X POST -H "Content-Type: application/json" -d '{"username": "user1", "email": "user1@example.com", "enabled": true, "attributes": {"group": "users"}, "credentials": [{"type": "password", "value": "password", "temporary": false}]}' $KEYCLOAK_URL/admin/realms/master/users
    
    # Create second user
    curl -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X POST -H "Content-Type: application/json" -d '{"username": "user2", "email": "user2@solo.io", "enabled": true, "attributes": {"group": "users"}, "credentials": [{"type": "password", "value": "password", "temporary": false}]}' $KEYCLOAK_URL/admin/realms/master/users