Showing posts with label OpenShift Containerized Storage. Show all posts
Showing posts with label OpenShift Containerized Storage. Show all posts

Saturday, May 01, 2021

Configuring Noobaa S3 Storage for Red Hat Advanced Cluster Management Observability

 


Nevermind other storage vendors, Noobaa in OpenShift Container Storage (OCS) can provide all the object storage needs Red Hat Advanced Cluster Management Observability ever needed.   In the following blog I will demonstrate how to configure the Noobaa backend in OCS to be used by Red Hat Advanced Cluster Management Observability.

Red Hat Advanced Cluster Management consists of several multicluster components, which are used to access and manage a fleet of OpenShift clusters.  With the observability service enabled, you can use Red Hat Advanced Cluster Management to gain insight about and optimize a fleet managed clusters.

First lets discuss some assumptions I make about the setup:

-This is a 3 master 3 (or more) worker OpenShift cluster

-OCP 4.6.19 (or higher) w/ OCS 4.6.4 in a hyperconverged configuration

-RHACM 2.2.2 is installed on the same cluster

With the stated above assumptions lets move onto configuring a Noobaa object bucket.   The first thing we need to do is create a resource yaml file that will create our object bucket.  The below is an example:

$ cat << EOF > ~/noobaa-object-storage.yaml
apiVersion: objectbucket.io/v1alpha1
kind: ObjectBucketClaim
metadata:
  name: obc-schmaustech
spec:
  generateBucketName: obc-schmaustech-bucket
  storageClassName: openshift-storage.noobaa.io
EOF

Once we have created our object bucket resource yaml we need to go ahead and create in our OpenShift cluster with following command:

$ oc create -f ~/noobaa-object-storage.yaml
objectbucketclaim.objectbucket.io/obc-schmaustech created


Once the object bucket resource is created we can see it by listing current object buckets:

$ oc get objectbucket
NAME                          STORAGE-CLASS                 CLAIM-NAMESPACE   CLAIM-NAME        RECLAIM-POLICY   PHASE   AGE
obc-default-obc-schmaustech   openshift-storage.noobaa.io   default           obc-schmaustech   Delete           Bound   30s

There are some bits of information we need to gather from the object bucket that we created which we will need to configure our thanos-object-bucket resource yaml required for our Observability configuration.  Those bits are found by describing the object bucket we created and the object buckets secret.   First lets look at the object bucket itself:

$ oc describe objectbucket obc-default-obc-schmaustech
Name:         obc-default-obc-schmaustech
Namespace:    
Labels:       app=noobaa
              bucket-provisioner=openshift-storage.noobaa.io-obc
              noobaa-domain=openshift-storage.noobaa.io
Annotations:  <none>
API Version:  objectbucket.io/v1alpha1
Kind:         ObjectBucket
Metadata:
  Creation Timestamp:  2021-05-01T00:12:54Z
  Finalizers:
    objectbucket.io/finalizer
  Generation:  1
  Managed Fields:
    API Version:  objectbucket.io/v1alpha1
    Fields Type:  FieldsV1
    fieldsV1:
      f:metadata:
        f:finalizers:
          .:
          v:"objectbucket.io/finalizer":
        f:labels:
          .:
          f:app:
          f:bucket-provisioner:
          f:noobaa-domain:
      f:spec:
        .:
        f:additionalState:
          .:
          f:account:
          f:bucketclass:
          f:bucketclassgeneration:
        f:claimRef:
          .:
          f:apiVersion:
          f:kind:
          f:name:
          f:namespace:
          f:uid:
        f:endpoint:
          .:
          f:additionalConfig:
          f:bucketHost:
          f:bucketName:
          f:bucketPort:
          f:region:
          f:subRegion:
        f:reclaimPolicy:
        f:storageClassName:
      f:status:
        .:
        f:phase:
    Manager:         noobaa-operator
    Operation:       Update
    Time:            2021-05-01T00:12:54Z
  Resource Version:  4864265
  Self Link:         /apis/objectbucket.io/v1alpha1/objectbuckets/obc-default-obc-schmaustech
  UID:               9c7eddae-4453-439b-826f-f226513d78f4
Spec:
  Additional State:
    Account:                obc-account.obc-schmaustech-bucket-f6508472-4ba6-405d-9e39-881b45a7344e.608c9d05@noobaa.io
    Bucketclass:            noobaa-default-bucket-class
    Bucketclassgeneration:  1
  Claim Ref:
    API Version:  objectbucket.io/v1alpha1
    Kind:         ObjectBucketClaim
    Name:         obc-schmaustech
    Namespace:    default
    UID:          e123d2c8-2f9d-4f39-9a83-ede316b8a5fe
  Endpoint:
    Additional Config:
    Bucket Host:       s3.openshift-storage.svc
    Bucket Name:       obc-schmaustech-bucket-f6508472-4ba6-405d-9e39-881b45a7344e
    Bucket Port:       443
    Region:            
    Sub Region:        
  Reclaim Policy:      Delete
  Storage Class Name:  openshift-storage.noobaa.io
Status:
  Phase:  Bound
Events:   <none>

In the object bucket describe output we are specifically interested in the bucket name and the bucket host.  Below lets capture the bucket name and assign it to a variable and then echo it out to confirm the variable was set correctly:

$ BUCKET_NAME=`oc describe objectbucket obc-default-obc-schmaustech|grep 'Bucket Name'|cut -d: -f2|tr -d " "`
$echo $BUCKET_NAME
obc-schmaustech-bucket-f6508472-4ba6-405d-9e39-881b45a7344e

Lets do the same thing for the bucket host information.  Again we will assign it to a variable and then echo the variable to confirm it was set correctly:

$ BUCKET_HOST=`oc describe objectbucket obc-default-obc-schmaustech|grep 'Bucket Host'|cut -d: -f2|tr -d " "`
$ echo $BUCKET_HOST
s3.openshift-storage.svc

After we gathered the bucket name and bucket host name we need to also get the access and secret keys for our bucket.  These are stored in a secret file which will have the same name as the metadata name defined in our original object bucket resource file we created above.  In our example the metadata name was obc-schmaustech.  Lets show that secret below:

$ oc get secret obc-schmaustech
NAME              TYPE     DATA   AGE
obc-schmaustech   Opaque   2      117s

The access and secret keys will be visible in the contents of the secret resource and we can visually see them if we get the secret but also ask for the yaml version of the output as we have done below:

$ oc get secret obc-schmaustech -o yaml
apiVersion: v1
data:
  AWS_ACCESS_KEY_ID: V3M2TmpGdWVLd3Vjb2VoTHZVTUo=
  AWS_SECRET_ACCESS_KEY: ck4vOTBaM2NkZWJvOVJLQStaYlBsK3VveWZOYmFpN0s0OU5KRFVKag==
kind: Secret
metadata:
  creationTimestamp: "2021-05-01T00:12:54Z"
  finalizers:
  - objectbucket.io/finalizer
  labels:
    app: noobaa
    bucket-provisioner: openshift-storage.noobaa.io-obc
    noobaa-domain: openshift-storage.noobaa.io
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:AWS_ACCESS_KEY_ID: {}
        f:AWS_SECRET_ACCESS_KEY: {}
      f:metadata:
        f:finalizers:
          .: {}
          v:"objectbucket.io/finalizer": {}
        f:labels:
          .: {}
          f:app: {}
          f:bucket-provisioner: {}
          f:noobaa-domain: {}
        f:ownerReferences:
          .: {}
          k:{"uid":"e123d2c8-2f9d-4f39-9a83-ede316b8a5fe"}:
            .: {}
            f:apiVersion: {}
            f:blockOwnerDeletion: {}
            f:controller: {}
            f:kind: {}
            f:name: {}
            f:uid: {}
      f:type: {}
    manager: noobaa-operator
    operation: Update
    time: "2021-05-01T00:12:54Z"
  name: obc-schmaustech
  namespace: default
  ownerReferences:
  - apiVersion: objectbucket.io/v1alpha1
    blockOwnerDeletion: true
    controller: true
    kind: ObjectBucketClaim
    name: obc-schmaustech
    uid: e123d2c8-2f9d-4f39-9a83-ede316b8a5fe
  resourceVersion: "4864261"
  selfLink: /api/v1/namespaces/default/secrets/obc-schmaustech
  uid: eda5cd99-dc57-4c7b-acf3-377343d6fef8
type: Opaque

The access and secret keys are base64 encoded so we need to ensure we gather them from a decoded perspective.  As we did with the bucket name and bucket host we will assign them to variables.  First lets pull out the access key from the yaml, decode it and then assign it to a variable and confirm the variable has the access key content:

$ AWS_ACCESS_KEY_ID=`oc get secret obc-schmaustech -o yaml|grep -m1 AWS_ACCESS_KEY_ID|cut -d: -f2|tr -d " "| base64 -d`
$ echo $AWS_ACCESS_KEY_ID
Ws6NjFueKwucoehLvUMJ

We will do the same for the secret key and verify again:

$ AWS_SECRET_ACCESS_KEY=`oc get secret obc-schmaustech -o yaml|grep -m1 AWS_SECRET_ACCESS_KEY|cut -d: -f2|tr -d " "| base64 -d`
$ echo $AWS_SECRET_ACCESS_KEY
rN/90Z3cdebo9RKA+ZbPl+uoyfNbai7K49NJDUJj

Now that we have our four variables which contain the values for the bucket name, bucket host, access key and secret key we are now ready to create our thanos-object-storage resource yaml file which we will need to start the configuration and deployment of the Red Hat Advanced Cluster Management Observability component.  This file provides the observability service the information about the S3 object storage.   Below is how we can create the file noting that the variables will substitute in the values for resource definition:

$ cat << EOF > ~/thanos-object-storage.yaml
apiVersion: v1
kind: Secret
metadata:
  name: thanos-object-storage
type: Opaque
stringData:
  thanos.yaml: |
    type: s3
    config:
      bucket: $BUCKET_NAME
      endpoint: $BUCKET_HOST
      insecure: false
      access_key: $AWS_ACCESS_KEY_ID
      secret_key: $AWS_SECRET_ACCESS_KEY
      trace:
        enable: true
      http_config:
        insecure_skip_verify: true
EOF

Once we have the definition created we can go ahead and create the open-cluster-management-observability namespace:

$ oc create namespace open-cluster-management-observability
namespace/open-cluster-management-observability created

Next we want to assign the clusters pull-secret to the docker config json variable:

$ DOCKER_CONFIG_JSON=`oc extract secret/pull-secret -n openshift-config --to=-`
# .dockerconfigjson

At this point we can go ahead and create the thanos-object-storage resource from the yaml file we created:

$ oc create -f thanos-object-storage.yaml -n open-cluster-management-observability
secret/thanos-object-storage created

Once the thanos-object-storage resource is created we can create a multiclusterobservability resource yaml file like the example below.  Notice that it references the thanos-object-storage resource we created above:

$ cat << EOF > ~/multiclusterobservability_cr.yaml
apiVersion: observability.open-cluster-management.io/v1beta1
kind: MultiClusterObservability
metadata:
  name: observability #Your customized name of MulticlusterObservability CR
spec:
  availabilityConfig: High             # Available values are High or Basic
  imagePullPolicy: Always
  imagePullSecret: multiclusterhub-operator-pull-secret
  observabilityAddonSpec:              # The ObservabilityAddonSpec is the global settings for all managed clusters
    enableMetrics: true                # EnableMetrics indicates the observability addon push metrics to hub server
    interval: 60                       # Interval for the observability addon push metrics to hub server
  retentionResolution1h: 5d            # How long to retain samples of 1 hour in bucket
  retentionResolution5m: 3d
  retentionResolutionRaw: 1d
  storageConfigObject:                 # Specifies the storage to be used by Observability
    metricObjectStorage:
      name: thanos-object-storage
      key: thanos.yaml
EOF

We can cat out the file to confirm it looks correct:

$ cat multiclusterobservability_cr.yaml
apiVersion: observability.open-cluster-management.io/v1beta1
kind: MultiClusterObservability
metadata:
  name: observability #Your customized name of MulticlusterObservability CR
spec:
  availabilityConfig: High             # Available values are High or Basic
  imagePullPolicy: Always
  imagePullSecret: multiclusterhub-operator-pull-secret
  observabilityAddonSpec:              # The ObservabilityAddonSpec is the global settings for all managed clusters
    enableMetrics: true                # EnableMetrics indicates the observability addon push metrics to hub server
    interval: 60                       # Interval for the observability addon push metrics to hub server
  retentionResolution1h: 5d            # How long to retain samples of 1 hour in bucket
  retentionResolution5m: 3d
  retentionResolutionRaw: 1d
  storageConfigObject:                 # Specifies the storage to be used by Observability
    metricObjectStorage:
      name: thanos-object-storage
      key: thanos.yaml

At this point we can double check that nothing is running under the open-cluster-management-observability namespace:

$ oc get pods -n open-cluster-management-observability
No resources found in open-cluster-management-observability namespace.


Once confirmed there are no resource running we can apply the multiclusterobservability resource file we created to start the deployment of the observability components:

$ oc apply -f multiclusterobservability_cr.yaml
multiclusterobservability.observability.open-cluster-management.io/observability created

It will take a few minutes for the associated pods to come up but after a few minutes if we look for the pods under the open-cluster-management-observability namespace we should see the following:

$  oc get pods -n open-cluster-management-observability
NAME                                                              READY   STATUS    RESTARTS   AGE
alertmanager-0                                                    2/2     Running   0          97s
alertmanager-1                                                    2/2     Running   0          73s
alertmanager-2                                                    2/2     Running   0          57s
grafana-546fb568b4-bqn22                                          2/2     Running   0          97s
grafana-546fb568b4-hxpcz                                          2/2     Running   0          97s
observability-observatorium-observatorium-api-85cf58bd8d-nlpxf    1/1     Running   0          74s
observability-observatorium-observatorium-api-85cf58bd8d-qtm98    1/1     Running   0          74s
observability-observatorium-thanos-compact-0                      1/1     Running   0          74s
observability-observatorium-thanos-query-58dc8c8ccb-4p6l8         1/1     Running   0          74s
observability-observatorium-thanos-query-58dc8c8ccb-6tmvd         1/1     Running   0          74s
observability-observatorium-thanos-query-frontend-f8869cdf66c2c   1/1     Running   0          74s
observability-observatorium-thanos-query-frontend-f8869cdfstwrg   1/1     Running   0          75s
observability-observatorium-thanos-receive-controller-56c9x6tt5   1/1     Running   0          74s
observability-observatorium-thanos-receive-default-0              1/1     Running   0          74s
observability-observatorium-thanos-receive-default-1              1/1     Running   0          56s
observability-observatorium-thanos-receive-default-2              1/1     Running   0          37s
observability-observatorium-thanos-rule-0                         2/2     Running   0          74s
observability-observatorium-thanos-rule-1                         2/2     Running   0          49s
observability-observatorium-thanos-rule-2                         2/2     Running   0          32s
observability-observatorium-thanos-store-memcached-0              2/2     Running   0          74s
observability-observatorium-thanos-store-memcached-1              2/2     Running   0          70s
observability-observatorium-thanos-store-memcached-2              2/2     Running   0          66s
observability-observatorium-thanos-store-shard-0-0                1/1     Running   0          75s
observability-observatorium-thanos-store-shard-1-0                1/1     Running   0          74s
observability-observatorium-thanos-store-shard-2-0                1/1     Running   0          75s
observatorium-operator-797ddbd9d-kqpm6                            1/1     Running   0          98s
rbac-query-proxy-769b5dbcc5-qprrr                                 1/1     Running   0          85s
rbac-query-proxy-769b5dbcc5-s5rbm                                 1/1     Running   0          91s

With the pods running under the open-cluster-management-observability namespace we can now confirm that the observability service is running by logging into the Red Hat Advanced Cluster Management console and going to observe environments.  In the upper right hand corner of the screen a Grafana link should now be present like in the screenshot below: 


Once you click on the Grafana link the following observability dashboard will appear and it even already be showing metrics from the cluster collections:


If we click on the CPU metric we can even see the breakdown of what is using the CPU of the local-cluster:


At this point we can conclude that the Red Hat Advanced Cluster Management Observability component is installed successfully and using the Noobaa S3 object bucket we created.

Wednesday, May 20, 2020

Installing OpenShift Container Storage and OpenShift Virtualization



There seem to be some mystery as to what might be inside the container when it comes to installing and configuring OpenShift Containerized Storage and OpenShift Virtualization (formerly CNV) but this blog will easily prove there is no need to fear the container.

This blog assumes the availability of an already installed OpenShift 4.4 environment with a 3 master and 3 worker setup.   The workers will be where we run our OCS storage pods so each of those nodes should have at least one extra unused disk for the OSDs to use.  Further the installation of OCS requires that we have local storage PVs already created for OCS to consume during the deployment.  With that said lets get started.

First lets take a quick look at our environment by showing the nodes and looking at one of the workers to see the extra disk (vdb in this case):

$ export KUBECONFIG=/home/cloud-user/scripts/ocp/auth/kubeconfig
$ oc get nodes
NAME       STATUS   ROLES    AGE    VERSION
master-0   Ready    master   59m    v1.18.2
master-1   Ready    master   51m    v1.18.2
master-2   Ready    master   60m    v1.18.2
worker-0   Ready    worker   4m9s   v1.18.2
worker-1   Ready    worker   27m    v1.18.2
worker-2   Ready    worker   27m    v1.18.2

$ oc debug node/worker-0
Starting pod/worker-0-debug ...
To use host binaries, run `chroot /host`
Pod IP: 10.20.0.200
If you don't see a command prompt, try pressing enter.

sh-4.2# chroot /host
sh-4.4# lsblk
NAME                         MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
vda                          252:0    0  100G  0 disk 
|-vda1                       252:1    0  384M  0 part /boot
|-vda2                       252:2    0  127M  0 part /boot/efi
|-vda3                       252:3    0    1M  0 part 
|-vda4                       252:4    0 99.4G  0 part 
| `-coreos-luks-root-nocrypt 253:0    0 99.4G  0 dm   /sysroot
`-vda5                       252:5    0   65M  0 part 
vdb                          252:16   0  100G  0 disk 

Now that we have reviewed the environment lets first label the worker nodes as storage nodes:

$ oc label nodes worker-0 cluster.ocs.openshift.io/openshift-storage=''
node/worker-0 labeled

$ oc label nodes worker-1 cluster.ocs.openshift.io/openshift-storage=''
node/worker-1 labeled

$ oc label nodes worker-2 cluster.ocs.openshift.io/openshift-storage=''
node/worker-2 labeled

oc get nodes -l cluster.ocs.openshift.io/openshift-storage=
NAME       STATUS   ROLES    AGE    VERSION
worker-0   Ready    worker   5m7s   v1.18.2
worker-1   Ready    worker   28m    v1.18.2
worker-2   Ready    worker   28m    v1.18.2

Next we can proceed to the console and install the Local Storage operator.  First we will need to create a local-storage namespace:



Once we have created the namespace we can go to the Operators Hub and search for the LocalStorage operator:


Click on the LocalStorage operator to get the install button:


Click the install button and a page of options will be presented.  Choose the version applicable to the OCP cluster version.  In our case I will use 4.4.  Assign the namespace as the local-storage namespace we created previously and click install:


Once the operator successfully installs the following screen will be displayed:


Now that we have the LocalStorage operator installed lets go back to the command line and create our local storage PVs that will eventually be consumed by OCS.   The first step is to create the local-storage.yaml file and populate it with the following:

apiVersion: local.storage.openshift.io/v1
kind: LocalVolume
metadata:
  name: local-block
  namespace: local-storage
spec:
  nodeSelector:
    nodeSelectorTerms:
    - matchExpressions:
        - key: cluster.ocs.openshift.io/openshift-storage
          operator: In
          values:
          - ""
  storageClassDevices:
    - storageClassName: localblock
      volumeMode: Block
      devicePaths:
        - /dev/vdb
 

Save the file and then issue the following command to label our nodes with the OCS storage label:

$ oc get nodes -l cluster.ocs.openshift.io/openshift-storage -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}'
worker-0
worker-1
worker-2

Next we will create the block PVs using the local-storage.yaml we created:

$ oc create -f local-storage.yaml 
localvolume.local.storage.openshift.io/local-block created 

Lets validate that the pods and PVs were created:

$ oc -n local-storage get pods
NAME                                      READY   STATUS    RESTARTS   AGE
local-block-local-diskmaker-dxgwj         1/1     Running   0          42s
local-block-local-diskmaker-hrsvj         1/1     Running   0          42s
local-block-local-diskmaker-zsptk         1/1     Running   0          42s
local-block-local-provisioner-pwgfl       1/1     Running   0          42s
local-block-local-provisioner-s56f4       1/1     Running   0          42s
local-block-local-provisioner-wp8bz       1/1     Running   0          42s
local-storage-operator-5c46f48cfc-6ht8r   1/1     Running   0          15m

$ oc get pv
NAME                CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
local-pv-40d06fba   100Gi      RWO            Delete           Available           localblock              30s
local-pv-8aea98b7   100Gi      RWO            Delete           Available           localblock              28s
local-pv-e62c1b44   100Gi      RWO            Delete           Available           localblock              34s

$ oc get sc | grep localblock
localblock   kubernetes.io/no-provisioner   Delete          WaitForFirstConsumer   false                  60s
 

If everything looks good we can now return to the console and install the OCS operator.  As we did with the previous operator we will search for OpenShift Container and it will show the operator available to us:



Click on the operator and the install button will be displayed:


After clicking the install button the options for the operator will be displayed.  Select the option based on the environment.  The ones below are the default and I went with those:


After clicking install the operator will install and return to screen similar to the one below.  Notice that the AWS S3 Operator was installed as well given its a dependency for the OCS operator.


With the OCS operator installed and the local storage PVs ready we can now create our OCS cluster.   Lets use the cluster wizard within the console.  First we need to click on the OpenShift Container Storage operator in the list of installed operators:


Next we will click on the Storage Cluster heading which will display a button to the right for creating the OCS cluster service.  Click on this button:


This will bring up the following screen with the nodes labeled as OCS nodes being already checked and the amount of total raw capacity on those nodes once the local storage class is selected:


Click the create button the cluster will show a progress screen and begin to instantiate the cluster:


If we jump over to the command line we can also see pods are starting to instantiate:

$ oc get pods -n openshift-storage
NAME                                            READY   STATUS              RESTARTS   AGE
aws-s3-provisioner-85b697dd54-zcrv5             1/1     Running             0          12m
csi-cephfsplugin-646jk                          0/3     ContainerCreating   0          27s
csi-cephfsplugin-b6c66                          0/3     ContainerCreating   0          27s
csi-cephfsplugin-ppqdb                          3/3     Running             0          27s
csi-cephfsplugin-provisioner-785b9d8bd5-45cwm   0/5     ContainerCreating   0          26s
csi-cephfsplugin-provisioner-785b9d8bd5-nk9gl   0/5     ContainerCreating   0          26s
csi-cephfsplugin-rfw2m                          0/3     ContainerCreating   0          27s
csi-cephfsplugin-vpzp8                          0/3     ContainerCreating   0          27s
csi-cephfsplugin-xv484                          0/3     ContainerCreating   0          27s
csi-rbdplugin-864jc                             3/3     Running             0          27s
csi-rbdplugin-crgr4                             0/3     ContainerCreating   0          27s
csi-rbdplugin-hwtr4                             0/3     ContainerCreating   0          28s
csi-rbdplugin-provisioner-66c87f8bd4-48q6q      0/5     ContainerCreating   0          27s
csi-rbdplugin-provisioner-66c87f8bd4-js247      0/5     ContainerCreating   0          27s
csi-rbdplugin-s9fr7                             0/3     ContainerCreating   0          27s
csi-rbdplugin-t7tgb                             0/3     ContainerCreating   0          28s
csi-rbdplugin-x25f5                             0/3     ContainerCreating   0          28s
noobaa-operator-6f7d47dff6-dw62k                1/1     Running             0          12m
ocs-operator-6cf4c9fc95-qxllg                   0/1     Running             0          12m
rook-ceph-mon-a-canary-6fb7d8ff5d-bl6kq         1/1     Running             0          9s
rook-ceph-mon-b-canary-864586477c-n6tjs         0/1     ContainerCreating   0          8s
rook-ceph-mon-c-canary-cb7d94fd8-mvvzc          0/1     ContainerCreating   0          3s
rook-ceph-operator-674cfcd899-hpvmr             1/1     Running             0          12m

Once the cluster has installed the console will display the status similar to the image below:


We can also see all the pods are up and running from the command line as well:

$ oc get pods -n openshift-storage
NAME                                                              READY   STATUS      RESTARTS   AGE
aws-s3-provisioner-85b697dd54-zcrv5                               1/1     Running     0          22m
csi-cephfsplugin-646jk                                            3/3     Running     0          10m
csi-cephfsplugin-b6c66                                            3/3     Running     0          10m
csi-cephfsplugin-ppqdb                                            3/3     Running     0          10m
csi-cephfsplugin-provisioner-785b9d8bd5-45cwm                     5/5     Running     0          10m
csi-cephfsplugin-provisioner-785b9d8bd5-nk9gl                     5/5     Running     1          10m
csi-cephfsplugin-rfw2m                                            3/3     Running     0          10m
csi-cephfsplugin-vpzp8                                            3/3     Running     0          10m
csi-cephfsplugin-xv484                                            3/3     Running     0          10m
csi-rbdplugin-864jc                                               3/3     Running     0          10m
csi-rbdplugin-crgr4                                               3/3     Running     0          10m
csi-rbdplugin-hwtr4                                               3/3     Running     0          10m
csi-rbdplugin-provisioner-66c87f8bd4-48q6q                        5/5     Running     1          10m
csi-rbdplugin-provisioner-66c87f8bd4-js247                        5/5     Running     0          10m
csi-rbdplugin-s9fr7                                               3/3     Running     0          10m
csi-rbdplugin-t7tgb                                               3/3     Running     0          10m
csi-rbdplugin-x25f5                                               3/3     Running     0          10m
noobaa-core-0                                                     1/1     Running     0          7m15s
noobaa-db-0                                                       1/1     Running     0          7m15s
noobaa-endpoint-7cdcc9bdc6-85s2v                                  1/1     Running     0          5m57s
noobaa-operator-6f7d47dff6-dw62k                                  1/1     Running     0          22m
ocs-operator-6cf4c9fc95-qxllg                                     1/1     Running     0          22m
rook-ceph-crashcollector-worker-0-7fd95579db-jt85v                1/1     Running     0          8m38s
rook-ceph-crashcollector-worker-1-7f547f4dc-s9q5l                 1/1     Running     0          8m7s
rook-ceph-crashcollector-worker-2-bd6d78488-4pzz7                 1/1     Running     0          8m27s
rook-ceph-drain-canary-worker-0-64d6558fcb-x52z4                  1/1     Running     0          7m16s
rook-ceph-drain-canary-worker-1-7f8858f74-vsc6f                   1/1     Running     0          7m16s
rook-ceph-drain-canary-worker-2-5fd88c555c-2rmnx                  1/1     Running     0          7m18s
rook-ceph-mds-ocs-storagecluster-cephfilesystem-a-8458f9c54l4zx   1/1     Running     0          6m59s
rook-ceph-mds-ocs-storagecluster-cephfilesystem-b-bf76744474rnz   1/1     Running     0          6m58s
rook-ceph-mgr-a-5488b747df-2bmnn                                  1/1     Running     0          7m49s
rook-ceph-mon-a-7884697548-tp5pw                                  1/1     Running     0          8m38s
rook-ceph-mon-b-7b47c5c597-5jdrv                                  1/1     Running     0          8m27s
rook-ceph-mon-c-69f945d575-4pmtn                                  1/1     Running     0          8m7s
rook-ceph-operator-674cfcd899-hpvmr                               1/1     Running     0          22m
rook-ceph-osd-0-7f98849d5-vfhsn                                   1/1     Running     0          7m18s
rook-ceph-osd-1-594cc64794-p45h2                                  1/1     Running     0          7m17s
rook-ceph-osd-2-655df8c45c-wb9g6                                  1/1     Running     0          7m16s
rook-ceph-osd-prepare-ocs-deviceset-0-0-65zj5-fzwxt               0/1     Completed   0          7m29s
rook-ceph-osd-prepare-ocs-deviceset-1-0-w2hl2-z2xns               0/1     Completed   0          7m29s
rook-ceph-osd-prepare-ocs-deviceset-2-0-bj7qz-zhsfs               0/1     Completed   0          7m29s
rook-ceph-rgw-ocs-storagecluster-cephobjectstore-a-66b5b7dh8nzc   1/1     Running     0          6m36s

We can also see a bunch of new storage classes are also available to us:

$ oc get storageclass
NAME                          PROVISIONER                             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
localblock                    kubernetes.io/no-provisioner            Delete          WaitForFirstConsumer   false                  32m
ocs-storagecluster-ceph-rbd   openshift-storage.rbd.csi.ceph.com      Delete          Immediate              false                  12m
ocs-storagecluster-cephfs     openshift-storage.cephfs.csi.ceph.com   Delete          Immediate              false                  12m
openshift-storage.noobaa.io   openshift-storage.noobaa.io/obc         Delete          Immediate              false                  8m35s

At this point OpenShift Container Storage is ready to be consumed by OpenShift Virtualization.  However we still need to install OpenShift Virtualization.  Again we will use the console to install the operator and do so by first searching for it:


Click on the operator to bring up the install button:


Once the install button is clicked it will present the options for the OpenShift Vritualization operator:


Once the options and install have been clicked the operator will install and once complete the following screen is displayed:



Clicking on the OpenShift Virtualization operator and then clicking on CNV Operator Deployment will bring us to the following screen:


Then click on Create HyperConverged Cluster button, accept the defaults and click on create:


This will begin the process of launching the required pods for OpenShift Virtualization.  If we jump over to the command line we can see the pods spinning up:

$ oc get pods -n openshift-cnv
openshift-cnv                                      bridge-marker-4q57k                                               0/1     ContainerCreating   0          12s
openshift-cnv                                      bridge-marker-66vzn                                               1/1     Running             0          11s
openshift-cnv                                      bridge-marker-m6ll8                                               1/1     Running             0          11s
openshift-cnv                                      bridge-marker-slch2                                               0/1     ContainerCreating   0          12s
openshift-cnv                                      bridge-marker-xthw9                                               1/1     Running             0          12s
openshift-cnv                                      bridge-marker-zgvxq                                               1/1     Running             0          11s
openshift-cnv                                      cdi-apiserver-c6bfbc6b9-rjnl4                                     0/1     Running             0          13s
openshift-cnv                                      cdi-deployment-7c4fd9cb5b-rr8fk                                   0/1     ContainerCreating   0          13s
openshift-cnv                                      cdi-operator-7467d4478-9xcrm                                      1/1     Running             0          16m
openshift-cnv                                      cdi-uploadproxy-54c7876d47-wpzvf                                  0/1     ContainerCreating   0          13s
openshift-cnv                                      cluster-network-addons-operator-687c79cc7b-94fdm                  1/1     Running             0          16m
openshift-cnv                                      hco-operator-7cd98b5686-jmb8t                                     0/1     Running             0          16m
openshift-cnv                                      hostpath-provisioner-operator-5d8f6bc547-4f5rd                    1/1     Running             0          16m
openshift-cnv                                      kube-cni-linux-bridge-plugin-cd4zb                                0/1     ContainerCreating   0          15s
openshift-cnv                                      kube-cni-linux-bridge-plugin-cgpkz                                0/1     ContainerCreating   0          15s
openshift-cnv                                      kube-cni-linux-bridge-plugin-cxzvv                                1/1     Running             0          15s
openshift-cnv                                      kube-cni-linux-bridge-plugin-d9qnn                                1/1     Running             0          15s
openshift-cnv                                      kube-cni-linux-bridge-plugin-f9k7g                                1/1     Running             0          15s
openshift-cnv                                      kube-cni-linux-bridge-plugin-gj6th                                1/1     Running             0          15s
openshift-cnv                                      kubevirt-a2582644e49387db02a9524312c0792c76605518-jobczrpsrrgjc   0/1     Completed           0          16s
openshift-cnv                                      kubevirt-ssp-operator-69fbcd58f4-kpqr9                            1/1     Running             0          16m
openshift-cnv                                      nmstate-handler-kwt7d                                             0/1     ContainerCreating   0          8s
openshift-cnv                                      nmstate-handler-llj8z                                             0/1     ContainerCreating   0          8s
openshift-cnv                                      nmstate-handler-vct84                                             0/1     ContainerCreating   0          8s
openshift-cnv                                      nmstate-handler-worker-5rr47                                      0/1     ContainerCreating   0          8s
openshift-cnv                                      nmstate-handler-worker-jg4v4                                      1/1     Running             0          8s
openshift-cnv                                      nmstate-handler-worker-wjnz2                                      0/1     ContainerCreating   0          8s
openshift-cnv                                      node-maintenance-operator-6c76fbb8d-qllp6                         1/1     Running             0          16m
openshift-cnv                                      ovs-cni-amd64-2rgn7                                               0/2     ContainerCreating   0          5s
openshift-cnv                                      ovs-cni-amd64-8rbb6                                               0/2     ContainerCreating   0          5s
openshift-cnv                                      ovs-cni-amd64-hc5b8                                               0/2     ContainerCreating   0          5s
openshift-cnv                                      ovs-cni-amd64-hkdjb                                               0/2     ContainerCreating   0          5s
openshift-cnv                                      ovs-cni-amd64-hw995                                               0/2     ContainerCreating   0          5s
openshift-cnv                                      ovs-cni-amd64-jqg8x                                               0/2     ContainerCreating   0          5s
openshift-cnv                                      virt-operator-6d766f7698-bmsdc                                    1/1     Running             0          16m
openshift-cnv                                      virt-operator-6d766f7698-m2fxl                                    1/1     Running             0          16m


Looking back at the console once all the pods are running we will be presented with the following on the screen:


And if we look back at the command line we can see all the pods running under the opensihft-cnv namespace:

$ oc get pods -n openshift-cnv
NAME                                               READY   STATUS    RESTARTS   AGE
bridge-marker-4q57k                                1/1     Running   0          11m
bridge-marker-66vzn                                1/1     Running   0          11m
bridge-marker-m6ll8                                1/1     Running   0          11m
bridge-marker-slch2                                1/1     Running   0          11m
bridge-marker-xthw9                                1/1     Running   0          11m
bridge-marker-zgvxq                                1/1     Running   0          11m
cdi-apiserver-c6bfbc6b9-rjnl4                      1/1     Running   0          11m
cdi-deployment-7c4fd9cb5b-rr8fk                    1/1     Running   0          11m
cdi-operator-7467d4478-9xcrm                       1/1     Running   0          28m
cdi-uploadproxy-54c7876d47-wpzvf                   1/1     Running   0          11m
cluster-network-addons-operator-687c79cc7b-94fdm   1/1     Running   0          28m
hco-operator-7cd98b5686-jmb8t                      1/1     Running   0          28m
hostpath-provisioner-operator-5d8f6bc547-4f5rd     1/1     Running   0          28m
kube-cni-linux-bridge-plugin-cd4zb                 1/1     Running   0          11m
kube-cni-linux-bridge-plugin-cgpkz                 1/1     Running   0          11m
kube-cni-linux-bridge-plugin-cxzvv                 1/1     Running   0          11m
kube-cni-linux-bridge-plugin-d9qnn                 1/1     Running   0          11m
kube-cni-linux-bridge-plugin-f9k7g                 1/1     Running   0          11m
kube-cni-linux-bridge-plugin-gj6th                 1/1     Running   0          11m
kubevirt-node-labeller-9947m                       1/1     Running   0          11m
kubevirt-node-labeller-ckqbn                       1/1     Running   0          11m
kubevirt-node-labeller-hn9xt                       1/1     Running   0          11m
kubevirt-node-labeller-kw5hb                       1/1     Running   0          11m
kubevirt-node-labeller-n4lxc                       1/1     Running   0          11m
kubevirt-node-labeller-vhmkk                       1/1     Running   0          11m
kubevirt-ssp-operator-69fbcd58f4-kpqr9             1/1     Running   0          28m
nmstate-handler-kwt7d                              1/1     Running   0          11m
nmstate-handler-llj8z                              1/1     Running   0          11m
nmstate-handler-vct84                              1/1     Running   0          11m
nmstate-handler-worker-5rr47                       1/1     Running   0          11m
nmstate-handler-worker-jg4v4                       1/1     Running   0          11m
nmstate-handler-worker-wjnz2                       1/1     Running   0          11m
node-maintenance-operator-6c76fbb8d-qllp6          1/1     Running   0          28m
ovs-cni-amd64-2rgn7                                2/2     Running   0          11m
ovs-cni-amd64-8rbb6                                2/2     Running   0          11m
ovs-cni-amd64-hc5b8                                2/2     Running   0          11m
ovs-cni-amd64-hkdjb                                2/2     Running   0          11m
ovs-cni-amd64-hw995                                2/2     Running   0          11m
ovs-cni-amd64-jqg8x                                2/2     Running   0          11m
virt-api-84fd45c455-2jjbb                          1/1     Running   0          11m
virt-api-84fd45c455-ct7dt                          1/1     Running   0          11m
virt-controller-74c54b549-qz4q9                    1/1     Running   0          11m
virt-controller-74c54b549-zt5qj                    1/1     Running   0          11m
virt-handler-69644                                 1/1     Running   0          11m
virt-handler-7857r                                 1/1     Running   0          11m
virt-handler-bpsjg                                 1/1     Running   0          11m
virt-handler-j48c7                                 1/1     Running   0          11m
virt-handler-rrl6d                                 1/1     Running   0          11m
virt-handler-vr9bf                                 1/1     Running   0          11m
virt-operator-6d766f7698-bmsdc                     1/1     Running   0          28m
virt-operator-6d766f7698-m2fxl                     1/1     Running   0          28m
virt-template-validator-bd96cdfcd-4qgcz            1/1     Running   0          11m
virt-template-validator-bd96cdfcd-6d27x            1/1     Running   0          11m


Finally at this point we can actually go and launch a virtual machine.   If we navigate to workloads in the console we can see there is a Virtualization option:


It is here where we can click on the create a virtual machine button to start the wizard.  In the wizard the first screen is where we set VM specific attributes: name, OS source, OS type, VM size etc.  Below is an example of my VM:


Clicking next we are presented with a networking screen.  Again options for adding various network connectivity are available here but in this example I am just going to accept the defaults:



Next we are brought to storage and by default there is no storageclass assigned to the disk.  If a default storageclass was set on the OCP cluster then it would most likely default to that but I did not have that configured.  Given that I needed to edit the disk using the three dots on the right and set the storageclass:



On the advanced screen we can set the hostname, an SSH key if we desire and also attach a virtual CD-ROM:



Finally we get to a summary screen which shows all the settings as they were chosen through the wizard.  Once reviewed we can click next and create the VM:



Once the VM is creating we can view the status of the VM on the detail page:



Waiting a little bit we can now see the VM is running:


If we jump over to the console we can see we have a login prompt:



Hopefully this gives everyone a tastes of how easy it is to configure OpenShift Container Storage and OpenShift Virtualization in a OpenShift Container Platform 4.4 environment.