Cloud Native OCI

Deploying MuShop

Created with ❤ by Oracle A-Team

Environment Options

  • docker
  • kubernetes
  • helm
  • A microservices design offers excellent separation of concerns, and developer independence.
  • While these benefits are clear, they can often introduce some complexity for development environments.
  • Services support configurations that offer flexibity as necessary, and establish parity as much as possible.
  • Use the same tools for development - production.

✅ Checklist

Many of these configurations will be used at different times within the material that follows. Create a file with the following information to simplify lookups later.
region:       # Region where resources will be provisioned. (ex: us-phoenix-1)
tenancy:      # Tenancy OCID value
user:         # API User OCID value
compartment:  # Compartment OCID value
key:          # Private API Key file path (ex: /Users/jdoe/.oci/oci_key.pem)
fingerprint:  # Public API Key fingerprint (ex: 43:65:2c...)
ℹī¸ It is also recommeded to configure the OCI Command Line with using these values. Refer the Documentation on CLI configuration .

Lab Overview

  • Get Source Code
  • Cluster Setup
  • Create a deployment with Helm
  • Verify

MuShop Source Code

  • Clone Repository
  • Project Structure
  • Use this command to clone the repo into a folder named mushop:
    git clone \ \
    Change working directory:
    cd mushop
    Source Code
  • The source code will look something like the following:
    #> mushop
    ├── deploy
    │   ├── basic
    │   └── complete
    │       ├── docker-compose
    │       ├── helm-chart
    │       └── kubernetes
    └── src
        ├── api
        ├── assets
        ├── carts
        ├── catalogue
        ├── edge-router
        ├── events
        ├── fulfillment
        ├── dbtools
        ├── load
        ├── orders
        ├── payment
        ├── storefront
        └── user
    • ./deploy: Collection of application deployment resources
    • ./src: MuShop individual service code, Dockerfile, etc.

OKE Cluster Setup

  • OKE Kubeconfig
  • K8s Namespace
  • Cluster Setup
  • Hostname Ingress
  • Connection to an OKE cluster requires the oci command line interface. Follow these instructions to connect to an OKE cluster:
    TIP: Use the OCI Cloud Shell with pre-installed oci and kubectl
    TIP: Use kubectx to switch context easily & often from the command line

    1. Install the OCI Command Line
    2. Verify CLI is configured correctly (Object Storage namespace):
      oci os ns get
    3. From the OKE Cluster detail page, click . Copy the command that resembles the following:
      oci ce cluster create-kubeconfig \
        --cluster-id \
        --file $HOME/.kube/config --region us-ashburn-1 --token-version 2.0.0
    4. Check kubectl context:
      kubectl config current-context
      # cluster-c4daylfgvrg
  • Set the default kubectl namespace to skip adding
    --namespace <name> to every command:
    TIP: use kubens to switch namespace easily & often from the command line
    Use "mushop":
    kubectl create namespace mushop
    kubectl config set-context \
      --current --namespace=mushop
    Use "your name":
    kubectl create namespace <your_name>
    kubectl config set-context \
      --current --namespace=<your_name>
  • MuShop provides an umbrella helm chart called setup, which includes several recommended installations on the cluster. These installations represent common 3rd party services, which integrate with Oracle Cloud Infrastructure or enable certain application features.
    Chart Purpose Option
    Prometheus Service metrics aggregation prometheus.enabled
    Grafana Infrastructure/service visualization dashboards grafana.enabled
    Metrics Server Support for Horizontal Pod Autoscaling metrics-server.enabled
    Ingress Nginx Ingress controller and public Load Balancer ingress-nginx.enabled
    Service Catalog Service Catalog chart utilized by Oracle Service Broker catalog.enabled
    1. Check kubectl context:
      kubectl config current-context
    2. Create a namespace for MuShop utilities:
      kubectl create namespace mushop-utilities
    3. Install cluster dependencies using helm:
      helm dependency update deploy/complete/helm-chart/setup
      helm install mushop-utils deploy/complete/helm-chart/setup \
        --namespace mushop-utilities
      ⚠ī¸ It is possible that certain services may conflict with pre-existing installs.
      If so, try setting --set <chart>.enabled=false for any conflicting charts.
  • Part of the cluster setup includes the installation of an nginx ingress controller. This resource exposes an OCI load balancer, with a public ip address mapped to the OKE cluster.

    By default, the mushop helm chart creates an Ingress resource, routing ALL traffic on that ip address to the svc/edge component. This is OK for simple scenarios, however it may be desired to differentiate ingress traffic, using host names on the same ip address. (for example multiple applications on the cluster)

    TLDR; Configure the mushop helm chart ingress values in cases where traffic must be differentiated from one service to another:

    1. Locate the EXTERNAL-IP assigned to the ingress controller:
      kubectl get svc \
        mushop-utils-ingress-nginx-controller \
        --namespace mushop-utilities
      NAME                                    TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                      AGE
      mushop-utils-ingress-nginx-controller   LoadBalancer   80:30195/TCP,443:31059/TCP   1d
    2. Create an /etc/hosts entry on your computer with this ip address:
      # MuShop ingress load balancer
      # EXTERNAL-IP            MuShop DNS name
      Windows users follow a process as described here
    3. If using myvalues.yaml (Optional):
      # Configure ingress...

Deploy MuShop

  • Deploy with Helm
  • Open App
  • Under the Hood
  • Clean Up
  • Remembering that helm provides a way of packaging and deploying configurable charts, next we will deploy the application in "mock mode" where cloud services are mocked, yet the application is fully functional

    ⚠ī¸ NOTE: Ensure setup steps were completed, and any prior installations are removed

    WITHOUT a hostname:
    helm install mushop \
    deploy/complete/helm-chart/mushop \
    --set global.mock.service="all"
    WITH a hostname:
    helm install mushop \
    deploy/complete/helm-chart/mushop \
    --set global.mock.service="all" \
    --set ingress.hosts[0]=""
      __  __        _____ _                 
    |  \/  |      / ____| |                
    | \  / |_   _| (___ | |__   ___  _ __  
    | |\/| | | | |\___ \| '_ \ / _ \| '_ \ 
    | |  | | |_| |____) | | | | (_) | |_) |
    |_|  |_|\__,_|_____/|_| |_|\___/| .__/ 
                                    | |    
    kubectl get pod --watch
    ⏲ī¸ It may take a few moments to download all the application images.
  • After inspecting the resources created with helm install, go ahead and launch the application in your browser.
    Local Cluster
    Will use a self-signed SSL certificate by default
    OKE or Cluster with Ingress Controller
    Find the EXTERNAL-IP assigned to the ingress controller:
    kubectl get svc \
      mushop-utils-ingress-nginx-controller \
      --namespace mushop-utilities
    Open the IP address in your browser
    Alternatively with kubectl configured on localhost
    Proxy to the MuShop app on http://localhost:8000 (or a port of your choice)
    kubectl port-forward \
      svc/edge 8000:80
    ⚠ī¸ NOTE: For shared clusters, and host-based ingress, use the hostname you setup earlier.
  • To get a beter look at all the installed Kubernetes manifests by using the template command:
    mkdir ./out
    helm template mushop deploy/complete/helm-chart/mushop \
    --set global.mock.service="all" \
    --output-dir ./out
    Explore the files, and see each output. Example:
    # Source: mushop/charts/api/templates/api-deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    name: mushop-api
    labels: api api-0.1.0 mushop
      layer: client "0.1.0" Tiller
    replicas: 1
      matchLabels: api mushop
        layer: client
          layer: client
          - name: api
            image: ""
            imagePullPolicy: Always
              - name: http
                containerPort: 3000
            - name: MOCK_MODE
              value: "all"
            - name: SESSION_REDIS
              value: mushop-session
            - name: CATALOGUE_URL
              value: http://mushop-catalogue
            - name: ORDERS_URL
              value: http://mushop-orders
            - name: CARTS_URL
              value: http://mushop-carts
            - name: USERS_URL
              value: http://mushop-user
            - name: STATIC_MEDIA_URL
              value: ""
                path: /health
                port: http
                path: /health
                port: http
                cpu: 300m
                memory: 300Mi
                cpu: 100m
                memory: 100Mi
                - NET_BIND_SERVICE
                - all
              readOnlyRootFilesystem: true
              runAsNonRoot: true
              runAsUser: 10001
    1. Use helm to list the releases in the namespace:
      helm list
      Expect output like the following:
      NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART       APP VERSION
      mushop  mushop          1               2020-05-06 14:40:37.615416 -0600 MDT    deployed        mushop-
    2. Finally, delete the mushop release:
      helm delete mushop

👍 Good Job!

Version: 1.8.0
Build: 2022-02-17T05:02:17Z
Š 2022, Oracle and/or its affiliates. All rights reserved.