Adding Storage#

Housekeeping#

See the Getting Started documentation for installing and setting up:

  • microk8s

  • UCS Tools

    • Accessing NGC

    • Setting up repositories

Introduction#

In this tutorial, we will show how to add storage to UCS Microservices and applications.

This will help you get familiar with the basics of:

  • Using a local-path-provisioner to create PersistentVolume (PVs) and PersistentVolumeClaim (PVCs), and

  • Defining and adding PVs and PVCs to microservices.

Local Path Provisioner#

First, install the Local Path Provisioner by running the following command if not already done:

$ curl https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.23/deploy/local-path-storage.yaml | sed 's/^  name: local-path$/  name: mdx-local-path/g' | microk8s kubectl apply -f -

Now, we can use local storage in our microservices.

Defining and Adding PVs and PVCs to Microservices#

Create a PVC by running:

$ curl https://raw.githubusercontent.com/rancher/local-path-provisioner/master/examples/pvc/pvc.yaml | \
      sed 's/storageClassName: local-path$/storageClassName: mdx-local-path/g' | microk8s kubectl apply -f -

Let’s update the microservice manifest of our HTTP server microservice http-server:

type: msapplication
specVersion: 2.5.0
name: ucf.svc.http-server
chartName: http-server
description: http server
version: 0.0.2
tags: []
keywords: []
publish: false
ingress-endpoints:
  - name: http
    description: REST API endpoint
    protocol: TCP
    scheme: http
    mandatory: False
    data-flow: in-out
---
spec:
  - name: http-server-deployment
    type: ucf.k8s.app.deployment
    parameters:
      apptype: stateless

  - name: http-server-container
    type: ucf.k8s.container
    parameters:
      image:
        repository: nvcr.io/nvidia/pytorch
        tag: 22.04-py3
      command: [sh, -c]
      args: [
            "cd /localvol && echo $PWD && touch somefile.txt && ls && python -m http.server 8080
            "]
      ports:
        - containerPort: 8080
          name: http
      volumeMounts:
        - name: localvol
          mountPath: /localvol

  - name: svc
    type: ucf.k8s.service
    parameters:
      ports:
      - port: 8080
        protocol: TCP
        name: http

  - name: localvol
    type: ucf.k8s.volume
    parameters:
      persistentVolumeClaim:
        claimName: local-path-pvc

There are two additions to our manifest file:

  • A keyword volumeMounts with parameters to the UCS Container Component

  • Another UCS Component of type ucf.k8s.volume that will logically connect tp the PVC

We won’t make any changes to client.

In the app.yaml file to the following:

specVersion: 2.5.0
version: 0.0.2
doc: README.md
name: server-client-app
description: Server Client Application

dependencies:
- ucf.svc.curl-client:0.0.1
- ucf.svc.http-server:0.0.2

components:
- name: client
  type: ucf.svc.curl-client
- name: http-server
  type: ucf.svc.http-server

connections:
    client/http: http-server/http

The version of the http-server and the app has been updated.

Building Microservices and Applications and Deploying them#

Follow the steps mentioned below but remember to update the version of the http-server under dependencies section in app.yaml

Inspecting and Debugging Microservices and Application#

Let’s verify that the application was deployed successfully:

$ microk8s kubectl get all
NAME                                                      READY   STATUS             RESTARTS      AGE
pod/http-server-http-server-deployment-575bd9c956-4zd2l   1/1     Running            0             3m27s
pod/curl-client-curl-client-deployment-64b485b4f7-zlqn8   1/1     Running            0             3m27s

NAME                                             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/kubernetes                               ClusterIP   10.152.183.1    <none>        443/TCP    82d
service/http-server-http-server-deployment-svc   ClusterIP   10.152.183.70   <none>        8080/TCP   3m27s

NAME                                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/http-server-http-server-deployment   1/1     1            1           3m27s
deployment.apps/curl-client-curl-client-deployment   1/1     1            1           3m27s

NAME                                                            DESIRED   CURRENT   READY   AGE
replicaset.apps/http-server-http-server-deployment-575bd9c956   1         1         1       3m27s
replicaset.apps/curl-client-curl-client-deployment-64b485b4f7   1         1         1       3m27s

We can check the http-server container to see print the current working directory - in this case the /localvol folder. If we were using something like Triton Inference Server, we could add models here!

$ microk8s kubectl logs --tail -1 -l "app=http-server-http-server-deployment"
/localvol
somefile.txt

We can also get logs to verify if the file was created in the mounted vol:

$ microk8s kubectl logs --tail -1 -l "app=curl-client-curl-client-deployment"
    % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                  Dload  Upload   Total   Spent    Left  Speed
  100   346  100   346    0     0   112k      0 --:--:-- --:--:-- --:--:--  112k
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
  <html>
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Directory listing for /</title>
  </head>
  <body>
  <h1>Directory listing for /</h1>
  <hr>
  <ul>
  <li><a href="somefile.txt">somefile.txt</a></li>
  </ul>
  <hr>
  </body>
  </html>

As we can see somefile.txt shows up in the client, meaning that the file was indeed created in the mounted file path.

Stopping and Cleaning up Microservices and Applications#

Finally, to stop and clean up the application we can run:

$ microk8s helm3 uninstall server-client