Storage Fusion

 View Only

Fusion Recipe Tips - Running K8 or OpenShift commands during data protection workflows

By Sandeep Prajapati posted Sat March 23, 2024 08:52 AM

  

Introduction

In our previous blog using hooks, we have seen how to run external commands, scale deployments up and down, or wait for certain conditions (such as pods starting up). In this article, we will look at a special case of exec hook that will try to run Kubernetes or OpenShift commands during data protection workflows. This could be required for getting resource information, patching resources, or deleting them.

Background

During the data protection workflows, there are often requirements to retrieve, update, or delete resource information. The most common approach to accomplish these tasks is by issuing oc or kubectl commands. However, in many cases, these binaries are not available within application pods posing challenges in executing necessary actions on K8 or OpenShift cluster.

For this task, creating a kubectl or oc helper pod can solve the purpose, but what about utilizing the existing application pods? Yes, we can use them to issue corresponding API requests. How easy is it to get these API endpoints? Let’s explore in this article.

The Kubernetes API Reference

Navigate the Kubernetes API Reference page to obtain details on any Kubernetes resource endpoint. You can select a specific version of this documentation to access version-specific information. However, a challenge remains: how can one retrieve details on custom resources of an application? Is there an easier method available? This issue will be addressed in the following section.

Get the API equivalents for oc commands

For this, we need to issue oc commands with increased log level verbosity option, say –v=8. Which will give you detailed output consisting of API endpoints, request or response headers, request or response body, status, and any other intermediate results.

For example -

1)  (1)  Put the db2uinstance in maintenance mode by applying annotation

oc command for this operation is -

$ oc annotate db2uinstance db2wh-example db2u.databases.ibm.com/maintenance-pause-reconcile=true

Let’s issue this command with option –v=8.

$ oc annotate db2uinstance db2wh-example db2u.databases.ibm.com/maintenance-pause-reconcile=true --v=8
I0319 03:39:24.836114  169853 loader.go:372] Config loaded from file:  /root/.kube/config
I0319 03:39:24.860211  169853 round_trippers.go:463] GET https://<HOSTNAME>:6443/apis/db2u.databases.ibm.com/v1/namespaces/db2/db2uinstances/db2wh-example
I0319 03:39:24.860262  169853 round_trippers.go:469] Request Headers:
I0319 03:39:24.860283  169853 round_trippers.go:473]     Accept: application/json
I0319 03:39:24.860299  169853 round_trippers.go:473]     User-Agent: oc/4.11.0 (linux/amd64) kubernetes/1928ac4
I0319 03:39:24.860314  169853 round_trippers.go:473]     Authorization: Bearer <masked>
I0319 03:39:25.125779  169853 round_trippers.go:574] Response Status: 200 OK in 265 milliseconds
I0319 03:39:25.125851  169853 round_trippers.go:577] Response Headers:
...
I0319 03:39:25.126225  169853 request.go:1073] Response Body: {"apiVersion":"db2u.databases.ibm.com/v1","kind":"Db2uInstance","metadata":{"annotations":{"db2u/certs-api-cert":"[secure]","db2u/certs-api-key":"[secure]","db2u/certs-wv-rest":"[secure]","db2u/license":"[secure]","db2u/sshkeys-db2instusr":"[secure]","db2u/sshkeys-db2uadm":"[secure]","db2u/sshkeys-db2uhausr":"[secure]","kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"db2u.databases.ibm.com/v1\",\"kind\":\"Db2uInstance\",\"metadata\":{\"annotations\":{},\"name\":\"db2wh-example\",\"namespace\":\"db2\"},\"spec\":{\"account\":{\"privileged\":true},\"environment\":{\"authentication\":{\"ldap\":{\"enabled\":false}},\"databases\":[{\"dbConfig\":{\"APPLHEAPSZ\":\"25600\",\"LOGPRIMARY\":\"50\",\"LOGSECOND\":\"35\",\"STMTHEAP\":\"51200 AUTOMATIC\"},\"name\":\"BLUDB\"}],\"dbType\":\"db2wh\",\"instance\":{\"dbmConfig\":{\"DIAGLEVEL\":\"2\"},\"registry\":{\"DB2_4K_DEVICE_SUPPORT\":\"NO\",\"DB2_ATS_ENABLE\":\"NO\",\"DB2_DISPATCHER_PEEKTIMEOUT\":\"2\",\"DB2_OBJECT_STORAGE_SETTINGS\":\"OFF\"}},\"partiti [truncated 4780 chars]
I0319 03:39:25.129288  169853 request.go:1073] Request Body: {"metadata":{"annotations":{"db2u.databases.ibm.com/maintenance-pause-reconcile":"true"}}}
I0319 03:39:25.129395  169853 round_trippers.go:463] PATCH https://<HOSTNAME>:6443/apis/db2u.databases.ibm.com/v1/namespaces/db2/db2uinstances/db2wh-example?fieldManager=kubectl-annotate
I0319 03:39:25.129422  169853 round_trippers.go:469] Request Headers:
I0319 03:39:25.129446  169853 round_trippers.go:473]     Accept: application/json
I0319 03:39:25.129473  169853 round_trippers.go:473]     Content-Type: application/merge-patch+json
I0319 03:39:25.129497  169853 round_trippers.go:473]     User-Agent: oc/4.11.0 (linux/amd64) kubernetes/1928ac4
I0319 03:39:25.129524  169853 round_trippers.go:473]     Authorization: Bearer <masked>
I0319 03:39:25.230297  169853 round_trippers.go:574] Response Status: 200 OK in 100 milliseconds
I0319 03:39:25.230366  169853 round_trippers.go:577] Response Headers:
...
I0319 03:39:25.230725  169853 request.go:1073] Response Body: {"apiVersion":"db2u.databases.ibm.com/v1","kind":"Db2uInstance","metadata":{"annotations":{"db2u.databases.ibm.com/maintenance-pause-reconcile":"true","db2u/certs-api-cert":"[secure]","db2u/certs-api-key":"[secure]","db2u/certs-wv-rest":"[secure]","db2u/license":"[secure]","db2u/sshkeys-db2instusr":"[secure]","db2u/sshkeys-db2uadm":"[secure]","db2u/sshkeys-db2uhausr":"[secure]","kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"db2u.databases.ibm.com/v1\",\"kind\":\"Db2uInstance\",\"metadata\":{\"annotations\":{},\"name\":\"db2wh-example\",\"namespace\":\"db2\"},\"spec\":{\"account\":{\"privileged\":true},\"environment\":{\"authentication\":{\"ldap\":{\"enabled\":false}},\"databases\":[{\"dbConfig\":{\"APPLHEAPSZ\":\"25600\",\"LOGPRIMARY\":\"50\",\"LOGSECOND\":\"35\",\"STMTHEAP\":\"51200 AUTOMATIC\"},\"name\":\"BLUDB\"}],\"dbType\":\"db2wh\",\"instance\":{\"dbmConfig\":{\"DIAGLEVEL\":\"2\"},\"registry\":{\"DB2_4K_DEVICE_SUPPORT\":\"NO\",\"DB2_ATS_ENABLE\":\"NO\",\"DB2_DISPATCHER_PEEKTIMEOUT [truncated 5091 chars]
db2uinstance.db2u.databases.ibm.com/db2wh-example annotated

It gives detailed output about the API request.

Note: This oc annotation operation turns to be API PATCH request.

1)  (2) Delete the Maximo core CSV to reconcile it.

       oc command for this operation is - 

$ oc delete csv ibm-mas.v8.11.7

       when invoked with option –v=8, we get delete API request.

$ oc delete csv ibm-mas.v8.11.7 --v=8
I0319 04:40:10.887455  170589 loader.go:372] Config loaded from file:  /root/.kube/config
I0319 04:40:10.917777  170589 request.go:1073] Request Body: {"propagationPolicy":"Background"}
I0319 04:40:10.917922  170589 round_trippers.go:463] DELETE https://<HOSTNAME>:31814/apis/operators.coreos.com/v1alpha1/namespaces/mas-cpst3-core/clusterserviceversions/ibm-mas.v8.11.7
I0319 04:40:10.917946  170589 round_trippers.go:469] Request Headers:
I0319 04:40:10.917972  170589 round_trippers.go:473]     Accept: application/json
I0319 04:40:10.917991  170589 round_trippers.go:473]     Content-Type: application/json
I0319 04:40:10.918007  170589 round_trippers.go:473]     User-Agent: oc/4.11.0 (linux/amd64) kubernetes/1928ac4
I0319 04:40:10.918025  170589 round_trippers.go:473]     Authorization: Bearer <masked>
I0319 04:40:11.096900  170589 round_trippers.go:574] Response Status: 200 OK in 178 milliseconds
I0319 04:40:11.096984  170589 round_trippers.go:577] Response Headers:
...
I0319 04:40:11.097164  170589 request.go:1073] Response Body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Success","details":{"name":"ibm-mas.v8.11.7","group":"operators.coreos.com","kind":"clusterserviceversions","uid":"d1f749f1-7d5b-4819-a133-b2d0fa87cf85"}}
clusterserviceversion.operators.coreos.com "ibm-mas.v8.11.7" deleted
I0319 04:40:11.097716  170589 round_trippers.go:463] GET https://<HOSTNAME>:31814/apis/operators.coreos.com/v1alpha1/namespaces/mas-cpst3-core/clusterserviceversions?fieldSelector=metadata.name%3Dibm-mas.v8.11.7
I0319 04:40:11.097755  170589 round_trippers.go:469] Request Headers:
...
I0319 04:40:11.125853  170589 round_trippers.go:574] Response Status: 200 OK in 28 milliseconds
I0319 04:40:11.125911  170589 round_trippers.go:577] Response Headers:
...
I0319 04:40:11.126145  170589 request.go:1073] Response Body: {"apiVersion":"operators.coreos.com/v1alpha1","items":[],"kind":"ClusterServiceVersionList","metadata":{"continue":"","resourceVersion":"149614443"}}

d.

     Framing API requests

So far, we have gathered API details for a given oc command. To utilize this, a proper API request should be framed. Please take a look at accessing the Kubernetes API from a pod, for creating any such request. A sample example of PATCH request is available in the Storage Fusion Recipe repository.

For above example (1) Put the db2uinstance in maintenance mode by applying annotation, API request will be -

$ curl -X PATCH --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer `cat /var/run/secrets/kubernetes.io/serviceaccount/token`" -H 'Content-Type: application/merge-patch+json' -H 'Accept: application/json' -k https://kubernetes.default.svc/apis/db2u.databases.ibm.com/v1/namespaces/db2/db2uinstances/db2wh-example?fieldManager=kubectl-annotate -d '{"metadata":{"annotations":{"db2u.databases.ibm.com/maintenance-pause-reconcile":"true"}}}'

Congratulations! This is the exact API request will be used for annotating db2uinstance resource, eliminating the need of oc or kubectl binary on application Pod or additional helper pod. 

Conclusion

In this article, we explored ways to get API equivalents for oc or kubectl commands, which can be used in situations where these binaries are not available. Look out for our next blog post “Fusion Recipe Tips” where we explore another aspect of using Fusion Recipes for data protection.

0 comments
22 views

Permalink