Update on Dec 12th, 2022: this blog article is now on Medium.

Since the version 0.4.2, Online Boutique has its own Helm chart, in the GitHub repository or in the public Artifact Registry repository: us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique.

The intent is to simplify the way the Online Boutique users deploy it, especially when they want to deploy it in more advanced scenarios: with NetworkPolicies, with the Cymbal branding, without the frontend app exposed publicly, with ServiceAccounts, etc.

Let’s see this in action throughout this blog article, from the default setup to more complex scenarios where we want a secure Online Boutique deployed in a Service Mesh. Finally, we will see how you can deploy this Helm chart via Config Sync, in a GitOps way.

Deploy the default Online Boutique

Create a GKE cluster:

PROJECT_ID=FIXME-WITH-YOUR-PROJECT-ID
CLUSTER=onlineboutique-with-helm
ZONE=northamerica-northeast1-a
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='get(projectNumber)')
gcloud services enable container.googleapis.com
gcloud container clusters create ${CLUSTER} \
    --zone ${ZONE} \
    --machine-type=e2-standard-4 \
    --workload-pool ${PROJECT_ID}.svc.id.goog \
    --enable-dataplane-v2 \
    --labels mesh_id=proj-$PROJECT_NUMBER

Deploy the Online Boutique via its Helm chart:

ONLINEBOUTIQUE_NAMESPACE=onlineboutique
helm upgrade onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique \
    --install \
    --create-namespace \
    -n ${ONLINEBOUTIQUE_NAMESPACE}

If you wait a little bit, when the Pods are deployed, you can access the Online Boutique website by clicking on this URL:

echo -n "http://" && kubectl get svc frontend-external -n ${ONLINEBOUTIQUE_NAMESPACE} -o json | jq -r '.status.loadBalancer.ingress[0].ip'

Congrats! You just deployed the default setup of Online Boutique via its Helm chart!

Secure Online Boutique with NetworkPolicies

Let’s now add more security with this default Online Boutique setup, by adding predefined fine granular NetworkPolicies, one per app:

helm upgrade onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique \
    --install \
    --create-namespace \
    -n ${ONLINEBOUTIQUE_NAMESPACE} \
    --set networkPolicies.create=true

If you run the following command you could see the NetworkPolicies deployed:

kubectl get networkpolicies -n ${ONLINEBOUTIQUE_NAMESPACE}

Output similar to:

NAME                    POD-SELECTOR                AGE
adservice               app=adservice               4m42s
cartservice             app=cartservice             4m42s
checkoutservice         app=checkoutservice         4m42s
currencyservice         app=currencyservice         4m42s
deny-all                <none>                      4m42s
emailservice            app=emailservice            4m42s
frontend                app=frontend                4m42s
loadgenerator           app=loadgenerator           4m42s
paymentservice          app=paymentservice          4m42s
productcatalogservice   app=productcatalogservice   4m42s
recommendationservice   app=recommendationservice   4m42s
redis-cart              app=redis-cart              4m42s
shippingservice         app=shippingservice         4m42s

You can verify that you can still access the Online Boutique website by clicking on this URL:

echo -n "http://" && kubectl get svc frontend-external -n ${ONLINEBOUTIQUE_NAMESPACE} -o json | jq -r '.status.loadBalancer.ingress[0].ip'

By registering your GKE clsuter in a fleet, you can even see in the Google Cloud Console that your Security posture just got improved:

gcloud services enable gkehub.googleapis.com

gcloud container fleet memberships register ${CLUSTER} \
    --gke-cluster ${ZONE}/${CLUSTER} \
    --enable-workload-identity

Then, by navigating to the Anthos > Security page in your Google Cloud Console, you can see that Kubernetes network policy is enabled in the Online Boutique namespace: Online Boutique&rsquo;s Network Policies on Anthos Security page

Deploy Online Boutique in a Service Mesh

Let’s now deploy Online Boutique in an Anthos Service Mesh enabled on your GKE cluster.

First, let’s enable Anthos Service Mesh on the GKE cluster:

gcloud services enable mesh.googleapis.com

gcloud container fleet mesh enable

gcloud container fleet mesh update \
    --management automatic \
    --memberships ${CLUSTER}

Wait for the managed Anthos Service Mesh to be successfully enabled on your GKE cluster (code: REVISION_READY and state: ACTIVE):

gcloud container fleet mesh describe

In order to have Online Boutique in this Service Mesh, we need to label its Namespace:

kubectl label namespace ${ONLINEBOUTIQUE_NAMESPACE} istio-injection=enabled

Let’s force the injection of the Istio’s sidecar proxies on the Online Boutique’s Deployments:

kubectl rollout restart deployments \
    -n ${ONLINEBOUTIQUE_NAMESPACE}

If you wait a little bit, when the Pods are deployed, you can access the Online Boutique website by clicking on this URL:

echo -n "http://" && kubectl get svc frontend-external -n ${ONLINEBOUTIQUE_NAMESPACE} -o json | jq -r '.status.loadBalancer.ingress[0].ip'

Then, by navigating to the Anthos > Service Mesh page in your Google Cloud Console, you can see the associated Topology: Online Boutique on the ASM Topology page

Congrats! You just deployed Online Boutique in your Service Mesh via its Helm chart!

To follow an Istio’s best practice we could even deploy fine granular Sidecars, one per app, in order to optimize the resource utilization per app’s sidecar proxy:

helm upgrade onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique \
    --install \
    --create-namespace \
    -n ${ONLINEBOUTIQUE_NAMESPACE} \
    --set networkPolicies.create=true \
    --set sidecars.create=true

If you run the following command you could see the Sidecars deployed:

kubectl get sidecars -n ${ONLINEBOUTIQUE_NAMESPACE}

Output similar to:

NAME                    AGE
adservice               36h
cartservice             36h
checkoutservice         36h
currencyservice         36h
emailservice            36h
frontend                36h
loadgenerator           36h
paymentservice          36h
productcatalogservice   36h
recommendationservice   36h
redis-cart              36h
shippingservice         36h

Secure Online Boutique with AuthorizationPolicies

Let’s now add more security to Online Boutique in the Service Mesh setup, by adding predefined fine granular AuthorizationPolicies, one per app:

helm upgrade onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique \
    --install \
    --create-namespace \
    -n ${ONLINEBOUTIQUE_NAMESPACE} \
    --set networkPolicies.create=true \
    --set sidecars.create=true \
    --set serviceAccounts.create=true \
    --set authorizationPolicies.create=true

If you run the following command you could see the AuthorizationPolicies deployed:

kubectl get authorizationpolicies -n ${ONLINEBOUTIQUE_NAMESPACE}

Output similar to:

NAME                    AGE
adservice               22m
cartservice             22m
checkoutservice         22m
currencyservice         22m
deny-all                12m
emailservice            22m
frontend                22m
paymentservice          22m
productcatalogservice   22m
recommendationservice   22m
redis-cart              22m
shippingservice         22m

Note: in order to define these fine granular AuthorizationPolicies we needed to create one ServiceAccount per app too, instead of using the default ServiceAccount for all the apps.

You can verify that you can still access the Online Boutique website by clicking on this URL:

echo -n "http://" && kubectl get svc frontend-external -n ${ONLINEBOUTIQUE_NAMESPACE} -o json | jq -r '.status.loadBalancer.ingress[0].ip'

By navigating to the Anthos > Security page in your Google Cloud Console, you can see that Service access control is enabled in the Online Boutique namespace: Online Boutique&rsquo;s AuthorizationPolicies on Anthos Security page

Deploy Online Boutique behind an Istio’s ingress gateway

To follow Istio’s best practice, let’s protect our Online Boutique’s apps behind and Istio’s Ingress Gateway.

Let’s deploy an Istio’s Ingress Gateway:

INGRESS_NAMESPACE=asm-ingress
kubectl create namespace ${INGRESS_NAMESPACE}
kubectl label namespace ${INGRESS_NAMESPACE} istio-injection=enabled
kubectl label namespace ${INGRESS_NAMESPACE} name=${INGRESS_NAMESPACE}
kubectl apply -f https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples/raw/main/docs/ingress-gateway-asm-manifests/base/deployment-service.yaml -n ${INGRESS_NAMESPACE}
kubectl apply -f https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples/raw/main/docs/ingress-gateway-asm-manifests/base/gateway.yaml -n ${INGRESS_NAMESPACE}
kubectl apply -f https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples/raw/main/docs/ingress-gateway-asm-manifests/with-authorization-policies/authorizationpolicy.yaml -n ${INGRESS_NAMESPACE}

Now, let’s update the Online Boutique deployment in order to have the frontend app behind the Ingress Gateway:

helm upgrade onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique \
    --install \
    --create-namespace \
    -n ${ONLINEBOUTIQUE_NAMESPACE} \
    --set networkPolicies.create=true \
    --set sidecars.create=true \
    --set serviceAccounts.create=true \
    --set authorizationPolicies.create=true \
    --set frontend.externalService=false \
    --set frontend.virtualService.create=true \
    --set frontend.virtualService.gateway.name=asm-ingressgateway \
    --set frontend.virtualService.gateway.namespace=${INGRESS_NAMESPACE} \
    --set frontend.virtualService.gateway.labelKey=asm \
    --set frontend.virtualService.gateway.labelValue=ingressgateway

If you wait a little bit, when the Pods are deployed, you can access the Online Boutique website via the Ingress Gateway now, by clicking on this URL:

echo -n "http://" && kubectl get svc asm-ingressgateway -n ${INGRESS_NAMESPACE} -o json | jq -r '.status.loadBalancer.ingress[0].ip'

By navigating to the Anthos > Service Mesh page in your Google Cloud Console, you can see the associated Topology now containing the Ingress Gateway: Online Boutique on ASM Topology page with Ingress Gateway

By navigating to the Anthos > Security page in your Google Cloud Console, you can see that Service access control is enabled in the Ingress Gateway namespace too: Online Boutique AuthorizationPolicies with Ingress Gateway

One last thing, not related to Online Boutique per say, but here is a quick win to add more security within your Service Mesh, by adding STRICT mTLS for the communication between your apps in the Servie Mesh:

cat << EOF | kubectl apply -f -
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: istio-system
spec:
  mtls:
    mode: STRICT
EOF

By navigating to the Anthos > Security page in your Google Cloud Console, you can see that mTLS status is enabled in your Service Mesh: Online Boutique with STRICT mTLS

Deploy Online Boutique via Config Sync, in a GitOps way

Config Sync is a GitOps tool that you could leverage in your GKE cluster, which supports Helm chart to sync from an Helm registry to your GKE cluster, let’s see how you can accomplish this.

First, enable Config Sync on your GKE cluster:

gcloud beta container fleet config-management enable

cat <<EOF > acm-config.yaml
applySpecVersion: 1
spec:
  configSync:
    enabled: true
EOF
gcloud beta container fleet config-management apply \
    --membership ${CLUSTER} \
    --config acm-config.yaml

Wait for Config Sync to be successfully enabled on your GKE cluster (Status as NOT_CONFIGURED):

gcloud beta container fleet config-management status

Then, deploy the RootSync configuration to sync this Helm chart in your GKE cluster:

cat << EOF | kubectl apply -f -
apiVersion: configsync.gke.io/v1beta1
kind: RootSync
metadata:
  name: root-sync-helm
  namespace: config-management-system
spec:
  spec:
  sourceFormat: unstructured
  sourceType: helm
  helm:
    repo: oci://us-docker.pkg.dev/online-boutique-ci/charts
    chart: onlineboutique
    releaseName: onlineboutique
    namespace: onlineboutique
    auth: none
    values:
      networkPolicies:
        create: true
      sidecars:
        create: true
      serviceAccounts:
        create: true
      authorizationPolicies:
        create: true
      frontend:
        externalService: false
        virtualService:
          create: true
          gateway:
            name: asm-ingressgateway
            namespace: ${INGRESS_NAMESPACE}
            labelKey: asm
            labelValue: ingressgateway
EOF

By running the following command, you can see all the 73 resources synced from the Online Boutique Helm chart by Config Sync:

nomos status --contexts $(kubectl config current-context)

Output similar to:

<root>:root-sync-helm   oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique:latest   
  SYNCED                  onlineboutique:                                                           
  Managed resources:
     NAMESPACE        NAME                                                          STATUS    SOURCEHASH
     onlineboutique   authorizationpolicy.security.istio.io/adservice               Current   onlineb
     onlineboutique   authorizationpolicy.security.istio.io/cartservice             Current   onlineb
     onlineboutique   authorizationpolicy.security.istio.io/checkoutservice         Current   onlineb
     onlineboutique   authorizationpolicy.security.istio.io/currencyservice         Current   onlineb
     onlineboutique   authorizationpolicy.security.istio.io/deny-all                Current   onlineb
     onlineboutique   authorizationpolicy.security.istio.io/emailservice            Current   onlineb
     onlineboutique   authorizationpolicy.security.istio.io/frontend                Current   onlineb
     onlineboutique   authorizationpolicy.security.istio.io/paymentservice          Current   onlineb
     onlineboutique   authorizationpolicy.security.istio.io/productcatalogservice   Current   onlineb
     onlineboutique   authorizationpolicy.security.istio.io/recommendationservice   Current   onlineb
     onlineboutique   authorizationpolicy.security.istio.io/redis-cart              Current   onlineb
     onlineboutique   authorizationpolicy.security.istio.io/shippingservice         Current   onlineb
     onlineboutique   deployment.apps/adservice                                     Current   onlineb
     onlineboutique   deployment.apps/cartservice                                   Current   onlineb
     onlineboutique   deployment.apps/checkoutservice                               Current   onlineb
     onlineboutique   deployment.apps/currencyservice                               Current   onlineb
     onlineboutique   deployment.apps/emailservice                                  Current   onlineb
     onlineboutique   deployment.apps/frontend                                      Current   onlineb
     onlineboutique   deployment.apps/loadgenerator                                 Current   onlineb
     onlineboutique   deployment.apps/paymentservice                                Current   onlineb
     onlineboutique   deployment.apps/productcatalogservice                         Current   onlineb
     onlineboutique   deployment.apps/recommendationservice                         Current   onlineb
     onlineboutique   deployment.apps/redis-cart                                    Current   onlineb
     onlineboutique   deployment.apps/shippingservice                               Current   onlineb
     onlineboutique   networkpolicy.networking.k8s.io/adservice                     Current   onlineb
     onlineboutique   networkpolicy.networking.k8s.io/cartservice                   Current   onlineb
     onlineboutique   networkpolicy.networking.k8s.io/checkoutservice               Current   onlineb
     onlineboutique   networkpolicy.networking.k8s.io/currencyservice               Current   onlineb
     onlineboutique   networkpolicy.networking.k8s.io/deny-all                      Current   onlineb
     onlineboutique   networkpolicy.networking.k8s.io/emailservice                  Current   onlineb
     onlineboutique   networkpolicy.networking.k8s.io/frontend                      Current   onlineb
     onlineboutique   networkpolicy.networking.k8s.io/loadgenerator                 Current   onlineb
     onlineboutique   networkpolicy.networking.k8s.io/paymentservice                Current   onlineb
     onlineboutique   networkpolicy.networking.k8s.io/productcatalogservice         Current   onlineb
     onlineboutique   networkpolicy.networking.k8s.io/recommendationservice         Current   onlineb
     onlineboutique   networkpolicy.networking.k8s.io/redis-cart                    Current   onlineb
     onlineboutique   networkpolicy.networking.k8s.io/shippingservice               Current   onlineb
     onlineboutique   service/adservice                                             Current   onlineb
     onlineboutique   service/cartservice                                           Current   onlineb
     onlineboutique   service/checkoutservice                                       Current   onlineb
     onlineboutique   service/currencyservice                                       Current   onlineb
     onlineboutique   service/emailservice                                          Current   onlineb
     onlineboutique   service/frontend                                              Current   onlineb
     onlineboutique   service/paymentservice                                        Current   onlineb
     onlineboutique   service/productcatalogservice                                 Current   onlineb
     onlineboutique   service/recommendationservice                                 Current   onlineb
     onlineboutique   service/redis-cart                                            Current   onlineb
     onlineboutique   service/shippingservice                                       Current   onlineb
     onlineboutique   serviceaccount/adservice                                      Current   onlineb
     onlineboutique   serviceaccount/cartservice                                    Current   onlineb
     onlineboutique   serviceaccount/checkoutservice                                Current   onlineb
     onlineboutique   serviceaccount/currencyservice                                Current   onlineb
     onlineboutique   serviceaccount/emailservice                                   Current   onlineb
     onlineboutique   serviceaccount/frontend                                       Current   onlineb
     onlineboutique   serviceaccount/loadgenerator                                  Current   onlineb
     onlineboutique   serviceaccount/paymentservice                                 Current   onlineb
     onlineboutique   serviceaccount/productcatalogservice                          Current   onlineb
     onlineboutique   serviceaccount/recommendationservice                          Current   onlineb
     onlineboutique   serviceaccount/redis-cart                                     Current   onlineb
     onlineboutique   serviceaccount/shippingservice                                Current   onlineb
     onlineboutique   sidecar.networking.istio.io/adservice                         Current   onlineb
     onlineboutique   sidecar.networking.istio.io/cartservice                       Current   onlineb
     onlineboutique   sidecar.networking.istio.io/checkoutservice                   Current   onlineb
     onlineboutique   sidecar.networking.istio.io/currencyservice                   Current   onlineb
     onlineboutique   sidecar.networking.istio.io/emailservice                      Current   onlineb
     onlineboutique   sidecar.networking.istio.io/frontend                          Current   onlineb
     onlineboutique   sidecar.networking.istio.io/loadgenerator                     Current   onlineb
     onlineboutique   sidecar.networking.istio.io/paymentservice                    Current   onlineb
     onlineboutique   sidecar.networking.istio.io/productcatalogservice             Current   onlineb
     onlineboutique   sidecar.networking.istio.io/recommendationservice             Current   onlineb
     onlineboutique   sidecar.networking.istio.io/redis-cart                        Current   onlineb
     onlineboutique   sidecar.networking.istio.io/shippingservice                   Current   onlineb
     onlineboutique   virtualservice.networking.istio.io/frontend                   Current   onlineb

Conclusion

The Online Boutique’s Helm chart allows to deploy either the default basic setup as well as more advanced, complex and secure setup with Service Mesh and Config Sync (GitOps).

We just saw how you can deploy Online Boutique with its fine granular NetworkPolicies, Sidecars, ServiceAccounts and AuthorizationPolicies. We also saw how you can expose the Online Boutique’s frontend app via an Istio Ingress Gateway.

You can take inspiration of this to improve your own Security Posture with your own workloads.

More examples

You could also find advanced scenarios leveraging this Helm chart with these blogs below:

Hope you enjoyed that one, happy sailing, cheers!