, ,

VKS Cluster Autoscaler Install, Configuration and Upgrade (VCAP-VKS Exam Series, Part 22)

Objective 4.7 asks you to create, configure and upgrade autoscalers on VKS. This Part builds an autoscaled cluster from annotations, installs the package, measures six real scale up events, and walks the pause and repin sequence that an autoscaled upgrade demands.

VCAP-VKS Exam Series · Part 22 of 34
kubectl get machinedeployment -n ns-platform-a NAME CLUSTER REPLICAS READY UPDATED PHASE AGE vks-autoscale-01-np-1 vks-autoscale-01 5 4 5 ScalingUp 38m kubectl get machinedeployment -n ns-platform-a NAME CLUSTER REPLICAS READY UPDATED PHASE AGE vks-autoscale-01-np-1 vks-autoscale-01 3 3 3 Running 39m

Ninety seconds apart, same cluster, nothing scaled down. Something added two nodes and something else took them away, and both of them believed they were correct. That fight is the most common way a VKS autoscaler installation fails, it produces no error anywhere, and objective 4.7 is written in a way that makes it very easy to walk into.

Who this is for: A candidate who has already provisioned and rolled a workload cluster from a terminal, per Parts 20 and 21, and now has to make one size itself. This Part covers Objective 4.7, published wording Create, configure, and upgrade autoscalers. Terms defined on first use: VKS is vSphere Kubernetes Service, the product formerly named TKG Service or TKGS, and the rename is unfinished, so tkg still appears in namespace names, API groups and documentation URLs across VCF 9.0; a VKr is a vSphere Kubernetes release, the pairing of a node image with a Kubernetes version; a MachineDeployment is the Cluster API object that owns one worker node pool; a PackageInstall is the Carvel object that installs and reconciles a package on a cluster; kapp-controller is the agent that reconciles PackageInstalls; a VM Class is the named CPU and memory shape a vSphere Namespace is permitted to consume.
Key takeaways: Objective 4.7 has three verbs and each one has its own trap. Create means annotating a worker nodePool with min and max size and deleting the replicas field, because a replicas value and an autoscaler annotation on the same pool will cycle nodes forever. Configure means the autoscaler is a standard package installed as a PackageInstall in tkg-system that lands a Deployment in kube-system, and its clusterName and clusterNamespace values must match the Cluster object exactly. Upgrade means a four step sequence: pause the autoscaler, roll the VKr, repin the package to the new minor version, unpause. Autoscaler package minor version and VKr minor version are bound one to one, so an upgrade that skips the repin leaves a package that will not reconcile.

Version pinning before you touch a cluster

Part 21 left vks-lifecycle-01 in ns-platform-a sitting on VKr v1.32.0 after a rolling update. This Part builds a second cluster alongside it, vks-autoscale-01, because autoscaler annotations are far cleaner at creation than retrofitted, and then upgrades that cluster with the autoscaler in place. Same namespace, same storage policies, same VM classes bound from Part 17.

One relationship governs everything below. Broadcom documents a one to one binding between the autoscaler package minor version and the VKr minor version, and states plainly that a mismatch causes package reconciliation to fail. A VKr 1.32.x cluster takes a 1.32.x autoscaler. Not 1.33, not 1.31, no exceptions, no compatibility window. Write that down before you write anything else, because it converts the autoscaler from a one time install into a permanent dependency of your upgrade runbook.

# Versions everything below was run against. VCF 9.0, vCenter 9.0.0.0 build 24755230 Supervisor version v1.31.4+vmware.wcp.2 VKS 3.3.1, ClusterClass builtin-generic-v3.1.0 kubectl v1.32.2, kubectl-vsphere plugin 9.0.0 VCF CLI v9.0.0 Target namespace ns-platform-a, 3 vSphere Zones kubectl config use-context ns-platform-a # Short form kr works from VKS 3.2 onward. Below 3.2 the object is tanzukubernetesreleases. kubectl get kr NAME VERSION READY COMPATIBLE v1.31.4—vmware.1-fips-vkr.3 v1.31.4+vmware.1-fips True True v1.32.0—vmware.6-fips-vkr.2 v1.32.0+vmware.6-fips True True # VM classes the namespace is allowed to consume. Autoscaling cannot exceed this binding. kubectl get virtualmachineclassbindings -n ns-platform-a NAME VIRTUALMACHINECLASS AGE guaranteed-medium guaranteed-medium 26d best-effort-small best-effort-small 26d # Namespace capacity is the real ceiling on scale up. Read it before choosing max size. kubectl describe namespace ns-platform-a | grep -A4 "Resource Quotas"

Broadcom lists the floor for this feature as vSphere 8 Update 3 with VKr 1.27.x or later, which matters only if you are studying against an older estate. On VCF 9.0 with VKS 3.3 you get one capability that changes design: scaling a pool up from zero and down to zero, on VKr 1.31.4 and later. Before 3.3 the floor was one node per pool, which meant a batch pool cost you a machine around the clock. Now it does not, and that is worth knowing because it is the kind of version boundary an exam item can hang a scenario on.

Cluster spec with autoscaler annotations

Two annotations on the worker nodePool do all the work, and one omission carries the whole thing. You do not set replicas on an autoscaled pool. Cluster API reads min size as the starting replica count, so a pool with min 3 comes up with three workers and then hands ownership of that number to the autoscaler. Leave replicas in the spec and the topology controller keeps enforcing your number while the autoscaler keeps enforcing its own.

# vks-autoscale-01.yaml apiVersion: cluster.x-k8s.io/v1beta1 kind: Cluster metadata: name: vks-autoscale-01 namespace: ns-platform-a spec: clusterNetwork: services: cidrBlocks: [10.96.0.0/12] pods: cidrBlocks: [192.168.0.0/16] serviceDomain: cluster.local topology: class: builtin-generic-v3.1.0 version: v1.32.0—vmware.6-fips-vkr.2 controlPlane: replicas: 3 variables: – name: vmClass value: guaranteed-medium – name: storageClass value: vsan-default-storage-policy – name: storageClasses value: [vsan-default-storage-policy, vsan-high-perf] workers: machineDeployments: – class: node-pool name: np-1 # No replicas key here. That is deliberate. metadata: annotations: cluster.x-k8s.io/cluster-api-autoscaler-node-group-min-size: "3" cluster.x-k8s.io/cluster-api-autoscaler-node-group-max-size: "8" kubectl apply -f vks-autoscale-01.yaml cluster.cluster.x-k8s.io/vks-autoscale-01 created # Min size became the starting replica count. Nothing else set it. kubectl get machinedeployment -n ns-platform-a NAME CLUSTER REPLICAS READY UPDATED PHASE AGE vks-autoscale-01-np-1 vks-autoscale-01 3 3 3 Running 14m

Control plane replicas stay hard coded at three. Cluster autoscaling on VKS adjusts worker nodes only, and an item that offers you a control plane min and max annotation is offering you a wrong answer. Note also that the annotations sit under the machineDeployment metadata, not under the cluster metadata, and not on the ClusterClass. Placement is exactly the sort of detail a drag and drop item can test.

Package repository and autoscaler install

Annotations alone do nothing. A cluster carrying min and max annotations with no autoscaler package installed sits at min size forever and reports no error, which is a state worth recognising because it looks healthy from every angle. Installation runs against the workload cluster context, not the Supervisor, and it needs the standard package repository from Part 23 territory in place first.

kubectl vsphere login –server=supervisor.lab.local –tanzu-kubernetes-cluster-namespace ns-platform-a –tanzu-kubernetes-cluster-name vks-autoscale-01 –vsphere-username $VKS_USER # Password read from the VKS_PASS environment variable at the prompt. Never inline it. kubectl config use-context vks-autoscale-01 # Standard package repository. Confirm the current bundle tag in the Standard Package release notes. cat <<EOF | kubectl apply -f – apiVersion: packaging.carvel.dev/v1alpha1 kind: PackageRepository metadata: name: tanzu-standard namespace: tkg-system spec: fetch: imgpkgBundle: image: projects.packages.broadcom.com/vsphere/supervisor/packages/2025.10.22/vks-standard-packages:3.5.0-20251022 EOF kubectl get packagerepository -A NAMESPACE NAME AGE DESCRIPTION tkg-system tanzu-standard 2m22s Reconcile succeeded # Available autoscaler versions. Pick the one whose minor matches your VKr minor. kubectl get package -n tkg-system | grep cluster-autoscaler cluster-autoscaler.kubernetes.vmware.com.1.31.3+vmware.1-vks.1 1.31.3+vmware.1-vks.1 cluster-autoscaler.kubernetes.vmware.com.1.32.2+vmware.1-vks.1 1.32.2+vmware.1-vks.1 cluster-autoscaler.kubernetes.vmware.com.1.33.0+vmware.2-vks.1 1.33.0+vmware.2-vks.1 cluster-autoscaler.kubernetes.vmware.com.1.34.0+vmware.1-vks.1 1.34.0+vmware.1-vks.1

Cluster is on VKr v1.32.0, so the autoscaler is 1.32.2+vmware.1-vks.1. Reading four available versions and taking the newest is the reflex that breaks this, and it is the reflex most Kubernetes operators have built over a decade of package management.

# autoscaler.yaml apiVersion: v1 kind: ServiceAccount metadata: name: autoscaler-sa namespace: tkg-system — apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: autoscaler-role-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: – kind: ServiceAccount name: autoscaler-sa namespace: tkg-system — apiVersion: packaging.carvel.dev/v1alpha1 kind: PackageInstall metadata: name: autoscaler namespace: tkg-system spec: serviceAccountName: autoscaler-sa packageRef: refName: cluster-autoscaler.kubernetes.vmware.com versionSelection: constraints: 1.32.2+vmware.1-vks.1 values: – secretRef: name: autoscaler-data-values — apiVersion: v1 kind: Secret metadata: name: autoscaler-data-values namespace: tkg-system stringData: values.yml: | — arguments: ignoreDaemonsetsUtilization: true maxNodeProvisionTime: 15m maxNodesTotal: 0 metricsPort: 8085 scaleDownDelayAfterAdd: 10m scaleDownDelayAfterDelete: 10s scaleDownDelayAfterFailure: 3m scaleDownUnneededTime: 10m clusterConfig: clusterName: "vks-autoscale-01" clusterNamespace: "ns-platform-a" paused: false kubectl apply -f autoscaler.yaml kubectl get pkgi -n tkg-system autoscaler NAME PACKAGE NAME PACKAGE VERSION DESCRIPTION AGE autoscaler cluster-autoscaler.kubernetes.vmware.com 1.32.2+vmware.1-vks.1 Reconcile succeeded 3m52s kubectl get pods -n kube-system | grep autoscaler cluster-autoscaler-798b65bd9f-bht8n 1/1 Running 0 2m

Two namespaces, and candidates mix them up under time pressure. PackageInstall, ServiceAccount and data values secret live in tkg-system. Running Deployment and pod land in kube-system. If you look for the pod in tkg-system and find nothing, the install is probably fine and your kubectl is pointed at the wrong namespace.

The clusterName and clusterNamespace values are not decoration. Broadcom sample manifests use gc1 and cluster as defaults, and copying them unchanged against a cluster named anything else produces an autoscaler pod that starts, stays Running, reports healthy, and never scales a thing, because it is watching a Cluster object that does not exist.

Scale behaviour with measured timings

Testing scale up is a matter of creating pods that cannot be scheduled. Scale a Deployment past what three guaranteed-medium workers can hold, watch pods go Pending, and watch a MachineDeployment replica count climb. What people underestimate is how long a node takes, because a VKS worker is a virtual machine cloned from a content library image, not a cloud instance from a warm pool.

Pending pod to Ready node, six scale up events vks-autoscale-01, guaranteed-medium workers, three vSphere Zones, VKr v1.32.0 Event 1 Event 2 Event 3 Event 4 Event 5 Event 6 3m 52s 4m 05s 4m 11s 4m 20s 6m 48s 11m 12s maxNodeProvisionTime default 15m Median 4m 16s. Event 5 landed on a zone doing a vSAN resync. Event 6 waited on a content library image cache miss. Every scale up costs minutes, which is why aggressive scale down settings cost more than they save.
Measured node provision times on the series lab estate. Cloud instance intuition does not transfer.

Median was 4 minutes 16 seconds across six events, worst case 11 minutes 12 seconds. Now read the scale down defaults against that. A node has to sit unneeded for scaleDownUnneededTime, 10 minutes, before removal is even considered, and scaleDownDelayAfterAdd holds off any removal for 10 minutes after a scale up. Both defaults look conservative until you notice that reacquiring a node costs four minutes minimum and can cost eleven. Cut scaleDownUnneededTime to 2 minutes because a blog told you it saves money, put a bursty CI workload on it, and you will pay for the same node three times an hour in provisioning latency while your pipeline sits Pending. Leave the defaults unless you have measured your own arrival pattern.

Upgrade sequence for an autoscaled cluster

Here is where objective 4.7 stops being an install task. An autoscaled cluster cannot be rolled the way Part 21 rolled vks-lifecycle-01, because a rolling update deliberately removes and replaces nodes while an autoscaler is deliberately reacting to node removals. Broadcom is unambiguous: pause the autoscaler first. Order is the whole answer.

flowchart TD
  A[Set paused true in autoscaler data values] --> B[Apply secret and confirm reconcile]
  B --> C[Edit topology version to new VKr]
  C --> D[Control plane rolls, then workers roll]
  D --> E{UPDATED equals REPLICAS on every pool}
  E -->|No| D
  E -->|Yes| F[Repin PackageInstall to matching autoscaler minor]
  F --> G[Set paused false in the same apply]
  G --> H[Confirm Reconcile succeeded and pod Running]
  H --> I[Force one pending pod and watch a node appear]
Pause, roll, repin, unpause. Skipping any step leaves either a fight or a dead autoscaler.
# Step 1. Pause. Only the paused key changes; keep every other value identical. kubectl -n tkg-system patch secret autoscaler-data-values –type merge -p ‘{"stringData":{"values.yml":"—narguments:n ignoreDaemonsetsUtilization: truen maxNodeProvisionTime: 15mn maxNodesTotal: 0n metricsPort: 8085n scaleDownDelayAfterAdd: 10mn scaleDownDelayAfterDelete: 10sn scaleDownDelayAfterFailure: 3mn scaleDownUnneededTime: 10mnclusterConfig:n clusterName: vks-autoscale-01n clusterNamespace: ns-platform-anpaused: truen"}}’ kubectl get pkgi -n tkg-system autoscaler autoscaler cluster-autoscaler.kubernetes.vmware.com 1.32.2+vmware.1-vks.1 Reconcile succeeded 1m4s # Step 2. Roll the cluster from the Supervisor context, exactly as in Part 21. kubectl config use-context ns-platform-a kubectl patch cluster vks-autoscale-01 –type merge -p ‘{"spec":{"topology":{"version":"v1.33.1—vmware.1-fips-vkr.2"}}}’ # Trust UPDATED against REPLICAS, not the VERSION column on the Cluster object. kubectl get machinedeployment -n ns-platform-a -w NAME CLUSTER REPLICAS READY UPDATED PHASE AGE vks-autoscale-01-np-1 vks-autoscale-01 3 2 1 RollingUpdate 3h12m vks-autoscale-01-np-1 vks-autoscale-01 3 3 3 Running 3h41m # Step 3 and 4. Repin the package minor to 1.33 and unpause in one apply. kubectl config use-context vks-autoscale-01 kubectl -n tkg-system patch pkgi autoscaler –type merge -p ‘{"spec":{"packageRef":{"versionSelection":{"constraints":"1.33.0+vmware.2-vks.1"}}}}’ # then set paused back to false in autoscaler-data-values kubectl get pkgi -n tkg-system autoscaler autoscaler cluster-autoscaler.kubernetes.vmware.com 1.33.0+vmware.2-vks.1 Reconcile succeeded 58s

Repinning is the step people drop, and it fails quietly in the worst possible way. A 1.32 autoscaler against a 1.33 cluster leaves a PackageInstall stuck in reconcile failure while the pod from the previous version may still be Running from before the constraint changed. Cluster looks upgraded, autoscaler pod looks alive, and nothing scales. Add a line to your upgrade runbook that says check pkgi after every VKr change, because kubectl get nodes will never tell you.

Real failures, with their error lines

Two failures are worth reproducing on purpose tonight, because both are silent in different ways and both map directly onto how objective 5.2 will come back at you in Part 31.

# FAILURE 1. Constraint that no package in the repository satisfies. kubectl get pkgi -n tkg-system autoscaler NAME PACKAGE NAME PACKAGE VERSION DESCRIPTION AGE autoscaler cluster-autoscaler.kubernetes.vmware.com Reconcile failed: Error (see .status.usefulErrorMessage for details) 47s kubectl get pkgi -n tkg-system autoscaler -o jsonpath='{.status.usefulErrorMessage}’ Expected to find at least one version, but did not (details: all=4 -> after prereleaseFilter=4 -> after constraintFilter=0) # Fix: list what the repository actually holds and pin an exact string from that list. kubectl get package -n tkg-system | grep cluster-autoscaler # FAILURE 2. replicas and autoscaler annotations on the same node pool. kubectl get cluster vks-autoscale-01 -n ns-platform-a -o jsonpath='{.spec.topology.workers.machineDeployments[0].replicas}’ 3 # Autoscaler adds nodes, topology controller removes them, indefinitely. kubectl get events -n ns-platform-a –sort-by=.lastTimestamp | tail -4 2m Normal ScaleUp machinedeployment/vks-autoscale-01-np-1 Scaled up to 5 1m Normal MachineDeleted machinedeployment/vks-autoscale-01-np-1 Deleted machine vks-autoscale-01-np-1-x7b2q 1m Normal ScaleUp machinedeployment/vks-autoscale-01-np-1 Scaled up to 5 34s Normal MachineDeleted machinedeployment/vks-autoscale-01-np-1 Deleted machine vks-autoscale-01-np-1-k4rvd # Fix: remove the replicas key from that machineDeployment entry. kubectl patch cluster vks-autoscale-01 -n ns-platform-a –type=json -p='[{"op":"remove","path":"/spec/topology/workers/machineDeployments/0/replicas"}]’ cluster.cluster.x-k8s.io/vks-autoscale-01 patched

Table below is the artifact to keep. Every row is a state you can reach in a lab in under ten minutes, and the middle column is what you will actually be shown in an exam item, because item authors do not give you the cause, they give you the symptom.

Symptom you are shownCauseRemediation
Pods Pending, node count never moves, no errors anywhereAnnotations present but autoscaler package never installedkubectl get pkgi -A on the workload cluster; install the package pinned to the VKr minor
Autoscaler pod Running and healthy, still no scalingclusterName or clusterNamespace left at the sample values gc1 and clusterCorrect clusterConfig in autoscaler-data-values to match the Cluster object exactly, then reapply
Node count oscillates every 60 to 120 secondsreplicas still set on an annotated machineDeploymentRemove the replicas key from that pool in spec.topology.workers.machineDeployments
PackageInstall shows Reconcile failed after a cluster upgradeAutoscaler package minor no longer matches VKr minorRepin constraints to the matching minor from kubectl get package output
New Machine stuck Provisioning, removed after 15 minutesNamespace CPU or memory quota exhausted, or VM class no longer boundRaise the vSphere Namespace quota or lower max size; confirm virtualmachineclassbindings
Rolling update never completes on an autoscaled clusterAutoscaler not paused, reacting to nodes the roll is drainingSet paused true, let the roll finish, repin and unpause afterwards
Scale down never happens on an idle clusterDaemonSet or unevictable pods holding nodes, or pool already at min sizeConfirm ignoreDaemonsetsUtilization is true and check min size against current replicas
Rollback and clean removal: Backing out is undramatic if you do it in the right order. Set paused true first so nothing reacts while you work. Delete the PackageInstall and its data values secret from tkg-system, which removes the Deployment from kube-system. Then add replicas back to the machineDeployment and remove both annotations, in the same apply, so the pool never sits in a state where neither controller owns the count. Deleting the PackageInstall while leaving the annotations in place is safe but leaves a cluster that silently never scales, which is exactly the first row of the table above.

Field note from forty wasted minutes

My first autoscaler on VKS went onto an existing cluster rather than a new one, because rebuilding felt wasteful. I added min 3 and max 8 to the node pool, installed the package, pinned the right minor, and ran a load test. Nodes appeared. Nodes vanished. Nodes appeared again. Over roughly forty minutes that cluster created and destroyed twelve machines, and vCenter tasks were a wall of clone and delete pairs that made it look like a storage problem.

Nothing logged an error. Autoscaler was doing its job. Topology controller was doing its job. My original spec still carried replicas: 3 on that pool, and I had added annotations next to it without removing it, because every other Kubernetes autoscaler I had used tolerates that. Forty minutes of investigation, twelve pointless machine lifecycles, and a load test I had to rerun from scratch. Fix was deleting four characters from a manifest.

Verdict: create autoscaled clusters with annotations and no replicas from the start, and retrofit only when you have no choice. If you must retrofit, remove replicas and add both annotations in one single apply rather than two, so there is no window where the two controllers disagree. Avoid the pattern of annotating first and cleaning up after, which is what everyone does and what cost me the afternoon. Broader provisioning mechanics live in the VKS series if you want the non exam version of this workflow.

Exam focus for objective 4.7

Objective 4.7, Create, configure, and upgrade autoscalers: What this objective expects you to be able to do is place things correctly and order things correctly. Place the two annotations on the right object, place the PackageInstall in tkg-system and know the Deployment lands in kube-system, and place the correct package minor against a given VKr. Order the upgrade: pause, roll, repin, unpause. Expect build list items on that upgrade order, matching items pairing an autoscaler argument with the behaviour it governs, and hot area or point and click items on a YAML fragment where you identify the field that is wrong. The trap that catches experienced admins is version selection. Everywhere else in Kubernetes, taking the newest available package version is correct and safe. Here the autoscaler package minor is bound one to one to the VKr minor, so newest is usually wrong, and an item that lists four available versions is testing precisely that reflex. A second, quieter trap: a scenario describing an autoscaled cluster being upgraded almost always has pause the autoscaler as step one, and candidates who answer from general Kubernetes habit start with the version edit instead.
Objective checkpoint:

1. A VKS cluster runs VKr v1.32.0. Four autoscaler package versions are available: 1.31.3, 1.32.2, 1.33.0 and 1.34.0, all with vmware and vks build suffixes. Which do you pin, and what happens if you pin the newest?
Answer: pin 1.32.2, matching the VKr minor. Pinning 1.34.0 causes package reconciliation to fail. Reasoning: Broadcom documents a one to one relationship between autoscaler package minor version and VKr minor version, with mismatch producing reconciliation failure rather than a degraded but working autoscaler.

2. A worker node pool carries both min size and max size annotations and a replicas value of 3. Load arrives and node count begins oscillating with no errors logged. What single change resolves it?
Answer: remove the replicas key from that machineDeployment entry in spec.topology.workers.machineDeployments. Reasoning: with replicas set, the topology controller continuously reconciles the pool back to 3 while the autoscaler scales it up, and neither component treats the other as an error condition.

3. Place these steps in the correct order for upgrading a cluster that has the autoscaler installed: repin the autoscaler package, edit the topology version, set paused to false, set paused to true.
Answer: set paused true, edit the topology version, repin the autoscaler package, set paused false. Reasoning: an active autoscaler reacts to nodes that a rolling update is deliberately draining, and the package minor cannot be repinned to match until the cluster actually runs the new VKr minor.

Autoscaler settings I would ship for this estate

My recommendation is to leave every timing argument at its default and spend your configuration effort on min and max instead. Defaults of 10 minutes for scaleDownUnneededTime and scaleDownDelayAfterAdd are well matched to a median 4 minute 16 second node provision time, and every attempt I have seen to tighten them has traded a small amount of idle capacity for a large amount of pod scheduling latency. Set maxNodesTotal to 0 as shipped and bound cost with the vSphere Namespace quota, which is enforced by the Supervisor and cannot be bypassed by editing a secret inside the workload cluster. That is the Supervisor doing what the Supervisor is for, and it is a better control point than an argument a cluster admin can change.

Tonight, do one thing: build vks-autoscale-01 with min 3 and max 8, install the matching autoscaler package, then deliberately reproduce failure 2 above by patching replicas back onto the pool. Watch the oscillation, read the events, then remove replicas and watch it settle. Ten minutes of that is worth an hour of reading, and it is the exact behaviour objective 4.7 and objective 5.2 both lean on. Part 23 moves to package repositories, standard packages and registry secrets, which is where the repository you installed here gets treated properly. Full path is indexed on the VCAP-VKS exam guide pillar.

VCAP-VKS Exam Series · Part 22 of 34
« Previous: Part 21  |  Guide  |  Next: Part 23 »

References

About The Author


Discover more from Journal of Intelligent Infrastructure

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *

Architect’s Toolkit

About the Author

Dr. Pranay Jha is a Cloud and AI Consultant with 18+ years of experience in hybrid cloud, virtualization, and enterprise infrastructure transformation. He specializes in VMware technologies, multi-cloud strategy, and Generative AI solutions. He holds a PhD in Computer Applications with research focused on Cloud and AI, has published multiple research papers, and has been a VMware vExpert since 2016 and a VMUG Community Leader.

Discover more from Journal of Intelligent Infrastructure

Subscribe now to keep reading and get access to the full archive.

Continue reading