online boutique’s helm chart, illustrate advanced scenarios with service mesh and gitops
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:
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:
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:
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:
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:
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:
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!