O-RAN O-Cloud K8s Cluster deployment

A step by step guide to deploying a workload cluster using the o2ims interface.

Prerequisites

This exercise will take us from a system with only the Nephio Management cluster setup, to a deployment with:

To perform these exercises, we will need:

  • Access to the installed demo VM environment as the ubuntu user.

The exercise will attempt to simulate the O-RAN O-Cloud architecture by deploying the focom operator to a separate KinD cluster, which will represent the SMO Nephio Management Cluster.

Step 1: Verify the O2IMS operator deployment

Check the operator pod status

kubectl get po -n o2ims

Example output

NAME                              READY   STATUS    RESTARTS   AGE
o2ims-operator-5595cd78b7-mwdxz   1/1     Running   0          5m

Verify that the o2ims CRD is installed

kubectl get crd | grep provisioningrequests

Example output

NAME                                                         CREATED AT
provisioningrequests.o2ims.provisioning.oran.org             2025-03-19T00:41:57Z

Step 2: Deploy the Focom Operator to separate cluster

Create a default kind cluster to simulate the SMO cluster env

kind create cluster -n focom-cluster --kubeconfig /tmp/focom-kubeconfig

Verify the cluster is healthy

kubectl get po -A --kubeconfig /tmp/focom-kubeconfig

Deploy the focom operator to the new cluster

kpt pkg get --for-deployment https://github.com/nephio-project/catalog.git/nephio/optional/focom-operator@origin/main /tmp/focom
kpt fn render /tmp/focom
kpt live init /tmp/focom --kubeconfig /tmp/focom-kubeconfig
kpt live apply /tmp/focom --reconcile-timeout=15m --output=table --kubeconfig /tmp/focom-kubeconfig

Verify the pod is healthy

kubectl get po -n focom-operator-system --kubeconfig /tmp/focom-kubeconfig

Example output

NAME                                                READY   STATUS    RESTARTS   AGE
focom-operator-controller-manager-d8f4d5cb6-dbxjh   1/1     Running   0          99s

Verify that the relevant CRDs are available

kubectl get crd --kubeconfig /tmp/focom-kubeconfig

Example output

NAME                                         CREATED AT
focomprovisioningrequests.focom.nephio.org   2025-03-19T08:30:07Z
oclouds.focom.nephio.org                     2025-03-19T08:30:07Z
resourcegroups.kpt.dev                       2025-03-19T08:29:57Z
templateinfoes.provisioning.oran.org         2025-03-19T08:30:07Z

Step 3: Create kubeconfig Secret

This step may vary depending on the networking of the demo environment.

Get the kube-api IP Address of the target O-Cloud cluster where the o2ims operator is deployed

IP=$(docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' kind-control-plane)

Create a temporary kubeconfig, substituting the IP Address

sed "s|https://127.0.0.1:[^ ]*|https://$IP:6443|" ~/.kube/config > /tmp/kubeconfig-bak

Verify the edit

cat /tmp/kubeconfig-bak | grep server

Example output

server: https://172.18.0.2:6443

Create the secret on the SMO cluster using the demo kubeconfig

kubectl create secret generic ocloud-kubeconfig --from-file=kubeconfig=/tmp/kubeconfig-bak --kubeconfig /tmp/focom-kubeconfig

Example output

secret/ocloud-kubeconfig created

Step 4: Create the demo CRs to trigger the Focom Provisioning Request

Create the OCloud CR, referencing the K8s Secret created previously

cat << EOF | kubectl apply --kubeconfig /tmp/focom-kubeconfig -f - 
apiVersion: focom.nephio.org/v1alpha1
kind: OCloud
metadata:
  name: ocloud-1
  namespace: focom-operator-system
spec:
  o2imsSecret:
    secretRef:
      name: ocloud-kubeconfig
      namespace: default

EOF

Example output

ocloud.focom.nephio.org/ocloud-1 created

Create the required TemplateInfo CR

cat << EOF | kubectl apply --kubeconfig /tmp/focom-kubeconfig -f - 
apiVersion: provisioning.oran.org/v1alpha1
kind: TemplateInfo
metadata:
  name: nephio-workload-cluster-v3.0.0
  namespace: focom-operator-system
spec:
  templateName: nephio-workload-cluster
  templateVersion: v3.0.0
  templateParameterSchema: |
    {
      "type": "object",
      "infra": {
      "param1": {
          "type": "string"
        },
        "params": {
          "type": "integer"
        }
      },
      "required": ["param1"]
    }

EOF

Example output

templateinfo.provisioning.oran.org/nephio-workload-cluster-v3.0.0 created

Create the FocomProvisioningRequest

cat << EOF | kubectl apply --kubeconfig /tmp/focom-kubeconfig -f - 
apiVersion: focom.nephio.org/v1alpha1
kind: FocomProvisioningRequest
metadata:
  name: focom-cluster-prov-req-nephio
  namespace: focom-operator-system
spec:
  name: sample-edge
  description: "Provisioning request for setting up a sample edge kind cluster"
  oCloudId: ocloud-1
  oCloudNamespace: focom-operator-system
  templateName: nephio-workload-cluster
  templateVersion: v3.0.0
  templateParameters:
    clusterName: edge
    labels:
      nephio.org/site-type: edge
      nephio.org/region: europe-paris-west
      nephio.org/owner: nephio-o2ims

EOF

Example output

focomprovisioningrequest.focom.nephio.org/focom-cluster-prov-req-nephio created

Step 5: Monitor the progress of the ProvisioningRequest

Verify that the provisioningrequest has been created on the target O-Cloud cluster

kubectl get provisioningrequests

Example output

NAME                            AGE
focom-cluster-prov-req-nephio   15s

Verify that the packagevariants are created for the edge-cluster. This may take some time.

kubectl get packagevariants

Example output

NAME                            AGE
edge-cluster                    1m
edge-configsync                 1m
edge-crds                       1m
edge-kindnet                    1m
edge-local-path-provisioner     1m
edge-metallb                    1m
edge-multus                     1m
edge-repo                       1m
edge-rootsync                   1m
edge-vlanindex                  1m
focom-cluster-prov-req-nephio   2m18s

Examine the details of the provisioningrequest CR created

kubectl get provisioningrequests focom-cluster-prov-req-nephio -o yaml

Example output

apiVersion: o2ims.provisioning.oran.org/v1alpha1
kind: ProvisioningRequest
metadata:
  annotations:
    provisioningrequests.o2ims.provisioning.oran.org/kopf-managed: "yes"
    provisioningrequests.o2ims.provisioning.oran.org/last-ha-a.A3qw: |
      {"spec":{"description":"Provisioning request for setting up a sample edge kind cluster","name":"sample-edge","templateName":"nephio-workload-cluster","templateParameters":{"clusterName":"edge","labels":{"nephio.org/owner":"nephio-o2ims","nephio.org/region":"europe-paris-west","nephio.org/site-type":"edge"}},"templateVersion":"v3.0.0"}}      
    provisioningrequests.o2ims.provisioning.oran.org/last-handled-configuration: |
      {"spec":{"description":"Provisioning request for setting up a sample edge kind cluster","name":"sample-edge","templateName":"nephio-workload-cluster","templateParameters":{"clusterName":"edge","labels":{"nephio.org/owner":"nephio-o2ims","nephio.org/region":"europe-paris-west","nephio.org/site-type":"edge"}},"templateVersion":"v3.0.0"}}      
  creationTimestamp: "2025-03-19T09:10:23Z"
  generation: 1
  name: focom-cluster-prov-req-nephio
  resourceVersion: "186743"
  uid: 95ba053e-7020-483b-bfc4-41f3cddb39d2
spec:
  description: Provisioning request for setting up a sample edge kind cluster
  name: sample-edge
  templateName: nephio-workload-cluster
  templateParameters:
    clusterName: edge
    labels:
      nephio.org/owner: nephio-o2ims
      nephio.org/region: europe-paris-west
      nephio.org/site-type: edge
  templateVersion: v3.0.0
status:
  provisionedResourceSet:
    oCloudInfrastructureResourceIds:
    - dd62bdc9-ecea-4b83-9484-a34c9cddbf4a
    oCloudNodeClusterId: d10b046d-38bd-4efe-bd08-bb4c4a380371
  provisioningStatus:
    provisioningMessage: Cluster resource created
    provisioningState: fulfilled
    provisioningUpdateTime: "2025-03-19T09:10:31Z"

Check the workload cluster deployment status. This may take some time.

kubectl get cl

Example output:

NAME       CLUSTERCLASS   PHASE         AGE    VERSION
edge       docker         Provisioned   1m     v1.31.0

You should also check that the Workload KinD cluster has come up fully by checking the machinesets You should see READY and AVAILABLE replicas. This may take some time.

kubectl get machinesets

Example output:

NAME                        CLUSTER    REPLICAS   READY   AVAILABLE   AGE    VERSION
edge-md-0-7gp6p-h8gmg       edge       1          1       1           3h1m   v1.31.0

Check that the associated gitea Porch repository is ready for the edge cluster

kubectl get repository | grep edge

Example output:

edge       git    Package   true         True    http://172.18.0.200:3000/nephio/edge.git