Wave

Migrating PVs in Kubernetes

4censord

Migrating PVs in Kubernetes

In kubernetes, data storage is provided by so called persistent volumes.
Kubernetes itself contains a bunch of different options out of the box, notably HostPath and NFS.

HostPath has the advantage of being incredibly simple. You just take a directory from your host, and make it available in a pod.
But, because it is host specific, that does not work very well if you have more than one host and want to be able to tolerate host failures.

NFS has the advantage of being standard, to the extend that every NAS or storage solution from the last 20 years supports it. But, perfomance often isn't great.
And, unless you are using NFSv4, NFS has some challenges surrounding things like file locking. But those arent important for anything exept rare cases like databases…

Kubernetes supports having multiple types of PVs, and groups them together in StorageClasses. When requesting a PV from kubernetes (using a pvc), you can specify which storageclass you want. If you leave it empty, kubernetes uses the default one.

If you later want to change the storage class, your data needs to be copied from the old volume to the new one.
In a perfect world, kubernetes would to that transparently for you, but as of this writing it does not.

So, lets think about how we can do such a migration.

Application based

Assuming our application supports this, we could just use the applications replication function. e.g. if our application is PostgresSQL, we could deploy a new postgres server with the new storage class, and just replicate all the data over.

But, because thats not specific to kubernetes, we will not look at this further.

Using backups

Assuming we have adequate backups, we could use these.
Just stop our application, take a backup, and restore it to a different PV.

E.g. when using velero0, you just add a modifier for the storage class to the restore job.

https://velero.io/docs/v1.9/restore-reference/#changing-pvpvc-storage-classes

Doing it by hand

Now its getting interesting.

What we basically want is to copy some files from one volume to another volume.
So basically, we want a container that copies files from a to b.

So, lets just create a container with that mounts these two PVs.

Its gonna be easy, right? kubectl run should just be able to mount a pv into a container, right?

1, 2

No, that would be to easy.

When we want to mount a pv into a kubectl run pod, we need to specify that by manually writing json specs for the pod.

Which basically looks like this:

$ kubectl run -i --rm --tty arch --overrides='
{
  "apiVersion": "batch/v1",
  "spec": {
    "template": {
      "spec": {
        "containers": [
          {
            "name": "arch",
            "image": "arch:latest",
            "args": [
              "bash"
            ],
            "stdin": true,
            "stdinOnce": true,
            "tty": true,
            "volumeMounts": [{
              "mountPath": "/pva",
              "name": "the_pv"
            },{
              "mountPath": "/pvb",
              "name": "the_other_pv"
            }]
          }
        ],
        "volumes": [{
          "name":"the_pv",
          "persistentVolumeClaim":{
          	"claimName": "the_pv_id"
          }
        },{
          "name":"the_other_pv",
          "persistentVolumeClaim":{
          	"claimName": "the_other_pv_id"
          }
        }        ]
      }
    }
  }
}
' --restart=Never -- bash

While it works, its also kindoff unwieldy.

We now could just juse rsync or something to move the data to the new volume.

Using pv-migrate

Someone else had thís problem before, and made a tool to make this easier.
Its called pv-migrate.

$ pv-migrate migrate old-pvc new-pvc

Its found at https://github.com/utkuozdemir/pv-migrate/

About the Author

4censord

4censord studies computer science in Germany.

Mia Rose WinterReviewer

This might also interest you

A Mystery Involving Hardware Security Modules and Value Tokens

Forbidden Tempura 10/7/2025

Context Historical context In July, 2021, the phenomenon known as the “Gigaleak” continued. The Gigaleak was a drip-feed of part of the ill-gotten data from the 2018 Nintendo data breach. On July 20, 2021, the iqcvs.tar.xz file was uploaded to the now-defunct file sharing website anonfiles.com and thereby made available to the public by The Hacker Known as 4chan. This file contains a dump of CVS repositories. The repository sw contains the BroadOn network infrastructure around the middle of the year 2006. This is shortly before the Nintendo Wii launched. The network infrastructure was initially launched alongside the iQue Player, a variant of the Nintendo 64 featuring downloadable games and some anti-piracy measures of questionable quality (non-HTTPS link) intended for the Chinese market, which was and still is notorious for being particularly prone to piracy. It was developed by a company then called BroadOn Communications Corp., a California corporation. The iQue Player u

ITInfodump

A Brief Look at the 3DS Cartridge Protocol

Forbidden Tempura 6/2/2024

About a week ago, there has been a little addition to the 3dbrew wiki page about 3DS cartridges (carts) that outlines the technical details of how the 3DS cartridge controller and a 3DS cartridge talk to each other. I would like to take this opportunity to also include the 3DS itself in the conversation to illuminate which part of which device performs which step. I will then proceed to outline where I think the corresponding design decisions originate. Finally, I will conclude with some concrete ideas for improvement. But first, we need to talk about parallel universes This protocol makes no sense unless you have a basic overview of the 3DS AES engine. The 3DS AES engine can load 128-bit AES keys in two ways: Using key-derivation from a keyX and keyY (officially called KeyId and KeySeed, respectively). Directly specifying a full AES key. The key derivation from a keyX and keyY works as follows: AES key = (((keyX ROL 2) XOR keyY) + C1) ROR 41, where ROL is left rotation on a 128-bit

ITGamesInfodump

Reconstructing the 3DS Bootstrapping Process at the Factory

Forbidden Tempura 5/13/2024

Motivation The Nintendo 3DS was a fairly popular console. In spite of that, surprisingly little is known about how it is put together at the factory. Working with information that was uncovered during the so-called Gigaleak, I will try to recover as much information as I can about the manufacturing process up and until the point the 3DS is able to complete a normal boot sequence. One-Time Programmable (OTP) region Every 3DS ships with 0x100 of one-time programmable persistent memory at 0x10012000-0x10012100, containing console-unique keys and information. This obviously has to occur before any normal firmware runs on the system because significant amounts of all data written would fail to account for console-unique information and thus the encrypted values would be all encrypted for the wrong keys. An interesting observations: ctr.7z (SHA-256: 8b05072361254437277576d53c08b95e5f076c6b33a2871fad74eaa5561d1d38) ctr/sources/bootrom/CTR/private/build/bootrom/ctr_bootrom/ARM9/main.c has a pr

ITGamesInfodump
Powered by Wave