← Todos os posts
2 de jul. de 2026

Evicções do Jellyfin Rastreadas ao root-dir do kubelet no Disco Errado

TL;DR: o ephemeral-storage allocatable do kubelet é calculado a partir do filesystem que sustenta seu root-dir (padrão /var/lib/kubelet), não do --data-dir do k3s; neste cluster o root-dir ficava numa partição /var de 22G enquanto os dados reais viviam numa partição /srv de 838G, então o kubelet reportava ~20.5GiB de ephemeral storage disponível, disparava o threshold de eviction sob o churn normal de pods/logs/emptyDir, e evictava o Jellyfin — que usava 1.1MB — simplesmente por ter o ranking mais alto entre pods sem request. Mudar --kubelet-arg root-dir “corrige” o número mas quebra o CSI do Longhorn e o socket do device-plugin de GPU, ambos com paths fixos sob /var/lib/kubelet; a correção que funciona é montar (bind mount) o disco grande direto no path convencional /var/lib/kubelet (a mesma abordagem que a EKS usa por padrão) depois de um reboot completo do nó pra garantir zero mounts vivos por baixo, repetido um nó por vez.

Mensagens de eviction do Kubernetes dizem qual recurso cruzou um threshold e qual pod morreu por isso — nunca dizem que o threshold em si foi calculado contra o filesystem errado. Quando o root-dir do kubelet e o disco de dados real divergem, todo consumidor de ephemeral-storage allocatable fica silenciosamente errado, e o pod evictado quase nunca é o que causa a pressão. A correção segura não é a flag anunciada exatamente pra esse propósito — é um bind mount no path que essa flag deveria substituir.

O Jellyfin usava 1.1 megabyte de disco. O kubelet evictou mesmo assim, sem pestanejar: The node was low on resource: ephemeral-storage. Threshold quantity: 1160345207, available: 714168Ki. Container jellyfin was using 1112Ki.... Lida sozinha, essa mensagem manda você procurar vazamento de disco no cache de transcode do Jellyfin. Não tinha vazamento nenhum — o Jellyfin era a menor coisa no nó. Ele foi escolhido porque o Kubernetes eviction ordena pods por “o quanto você passou do seu request”, e um pod sem request nenhum perde essa disputa por definição no instante em que qualquer pressão existe.

Este post é pra quem roda k3s (ou kubeadm) com data directory fora do filesystem do /var, especialmente junto com Longhorn ou qualquer outro CSI driver. Pressupõe que você já sabe o que é node-pressure eviction e como o df -h mente sobre a coisa que realmente importa.

Esse é o terceiro modo de falha ligado a storage encontrado no mesmo cluster; veja também Travamento de Nó k3s: Stalls de iSCSI do Longhorn e Pressão de Memória e Mounts SMB no Kubernetes Vão Travar Seu Nó pros outros dois — as três são causas-raiz sem relação entre si que só coincidem de estar no mesmo nó.

Sumário

  1. O sintoma: pods Evicted num nó com disco livre em todo lugar
  2. O sinal real, enterrado sob uma pista falsa
  3. Causa raiz: root-dir e data-dir apontando pra discos diferentes
  4. A correção que quebra tudo: mover root-dir
  5. O quase-desastre: cp -a andando por dentro de mounts CSI vivos
  6. A correção que funciona: bind mount do disco grande no path convencional
  7. Procedimento por nó
  8. Consequências e o que esperar do Longhorn nesse meio tempo
  9. Quando isso não se aplica

Por que o Jellyfin estava sendo evictado num nó com disco livre em todo lugar?

Resumo: o Jellyfin ficava ciclando entre Evicted e Error, e o kubectl describe pod apontava DiskPressure — mas o df -h no nó mostrava nenhum filesystem nem perto de cheio: partição raiz 34% usada, /var 17%, /srv 28%. Essa incompatibilidade é a armadilha inteira. DiskPressure é uma condição derivada do Kubernetes, calculada a partir da contabilidade interna de allocatable/requested de ephemeral-storage do kubelet, não de porcentagens crua de disco cheio, então um df -h saudável não diz nada sobre se existe pressão de eviction. A primeira teoria, razoável à primeira vista — que o emptyDir do cache de transcode do Jellyfin estava enchendo o nó — estava errada, porque nada no nó estava de fato enchendo. O problema real vivia uma camada abaixo do que o df -h consegue ver: em como o kubelet tinha calculado a capacidade total de ephemeral-storage disponível pra ele, um número baseado no disco errado.

kubectl get pods -n media neste cluster k3s de homelab (três nós control-plane/etcd: node A, node B, node C) mostrava o Jellyfin ciclando repetidamente entre Evicted e Error. kubectl describe pod dava a linha padrão de eviction:

Warning  Evicted  kubelet  The node had condition: [DiskPressure].

df -h no node B dizia que nenhum filesystem estava sob pressão real: partição raiz 34% usada, /var 17% usada, /srv 28% usada. Essa é a armadilha. DiskPressure e as porcentagens do df -h descrevem dois sistemas de contabilidade diferentes, e a primeira investigação — “o emptyDir do cache de transcode do Jellyfin está enchendo o nó” — era razoável e errada. Percentual de ocupação numa partição não diz nada sobre a contabilidade interna de allocatable/requested/limit do kubelet pra ephemeral-storage, que é o que de fato dirige node-pressure eviction. Veja a documentação de node-pressure eviction pra lista completa de sinais que o kubelet observa — DiskPressure é uma condição derivada, não uma checagem crua de disco cheio.

Qual era o sinal real, enterrado sob a pista falsa?

Resumo: a mensagem de eviction trazia os números reais, fáceis de passar batido: threshold quantity 1160345207 bytes (~1.16GB), available 714168Ki (~697MB), e o uso do próprio Jellyfin de 1112Ki — um erro de arredondamento perto de qualquer um dos dois. A eviction nunca foi sobre o consumo de disco do Jellyfin; era sobre o ephemeral-storage allocatable total do nó ser pequeno o bastante pra que o churn normal — logs, emptyDirs, contabilidade interna do kubelet — empurrasse o disponível abaixo do threshold de ~1.16GB, forçando o kubelet a matar alguém. O Kubernetes ordena candidatos a eviction por uso-acima-do-request, e um pod com request zero de storage fica em primeiro lugar no instante em que qualquer pressão existe, porque “o quanto você passou do seu request” é indefinido-mas-máximo em zero. O Jellyfin foi escolhido por ser descartável e não pedir nada, não por usar disco de forma relevante — inocente e descartável, nessa ordem.

Um evento de eviction posterior trouxe o número que importava:

Warning  Evicted  kubelet  The node was low on resource: ephemeral-storage.
Threshold quantity: 1160345207, available: 714168Ki. Container jellyfin was using 1112Ki...

1160345207 bytes é ~1.16GB — o threshold de eviction. 714168Ki é ~697MB — o que o kubelet achava que ainda estava disponível. O uso do próprio Jellyfin, 1112Ki, é um erro de arredondamento perto de qualquer um dos dois números. A eviction não era sobre o Jellyfin. Era sobre o ephemeral-storage allocatable total do nó ser pequeno o bastante pra que o churn normal de pods — logs, emptyDirs, contabilidade interna do kubelet — empurrasse o disponível abaixo de um threshold de ~1.16GB, e o kubelet precisava matar alguém. O ranking é por uso-acima-do-request; um pod com request zero e uso quase zero ainda fica em primeiro lugar no instante em que o nó entra em pressão, porque “o quanto você passou do seu request” é indefinido-mas-máximo com request zero. O Jellyfin era inocente e descartável, nessa ordem.

Causa raiz: root-dir e data-dir apontando pra discos diferentes

Resumo: o kubelet calcula o ephemeral-storage allocatable a partir do filesystem que sustenta seu diretório de trabalho root-dir (padrão /var/lib/kubelet), de forma totalmente independente da flag --data-dir do k3s. Neste cluster, o root-dir ficava numa partição /var de 22G enquanto --data-dir /srv/k3s tinha movido o estado real do k3s — etcd, manifests, imagens — pra uma partição /srv de 838G. O kubectl get node ... allocatable.ephemeral-storage retornava 22046558601 bytes (~20.5GiB), suspeitosamente perto do tamanho da partição pequena /var, porque era exatamente isso que estava sendo medido. Ninguém tinha movido o root-dir pra acompanhar o --data-dir, então o kubelet continuava calculando capacidade contra uma partição que nunca foi instruído a abandonar, enquanto o disco com os dados reais ficava totalmente fora do radar do eviction manager. Os três nós compartilhavam o mesmo particionamento e o mesmo descuido — isso estava embutido no bootstrap dos nós, não era um erro isolado numa única máquina.

kubectl get node node-b -o jsonpath='{.status.allocatable.ephemeral-storage}'
# 22046558601   (~20.5GiB)

20.5GiB é suspeitosamente perto do tamanho de /dev/nvme0n1p3, a partição /var de 22G. Não é coincidência — é o bug inteiro. O kubelet calcula o ephemeral-storage allocatable a partir do filesystem que sustenta seu diretório de trabalho, o root-dir, documentado como uma flag --root-dir simples com padrão /var/lib/kubelet na referência de CLI do kubelet. O k3s estava configurado com --data-dir /srv/k3s, o que move o estado próprio do k3s (dados do etcd, manifests, imagens de container) pra partição de 838G /dev/nvme0n1p5 — mas --data-dir e o root-dir do kubelet são knobs independentes. Ninguém tinha movido o root-dir. O kubelet continuava calculando capacidade contra a partição pequena que nunca foi instruído a abandonar, enquanto todos os dados que o k3s realmente usava ficavam num disco que o eviction manager do kubelet não sabia que existia.

Os três nós (node A, node B, node C) tinham particionamento idêntico e o mesmo descuido idêntico — isso não era específico de um nó, estava embutido no processo de bootstrap dos nós desde o dia zero.

A correção que quebra tudo: mover root-dir

Resumo: --kubelet-arg=root-dir=/srv/k3s/agent/kubelet — a flag que o k3s expõe especificamente pra isso — funcionou exatamente como anunciado: o ephemeral-storage allocatable pulou pra ~796GiB. Também quebrou o CSI do Longhorn em minutos, porque o longhorn-csi-plugin fixa hostPath mounts e um --kubelet-registration-path apontando pra /var/lib/kubelet/plugins/driver.longhorn.io/..., e o socket de registro do Longhorn nunca apareceu onde o kubelet passou a esperar. Todo pod novo que precisasse anexar um volume Longhorn falhava indefinidamente, o que derrubou o Postgres de um serviço Git self-hosted, depois o próprio serviço Git, depois dois serviços internos de build/ETL que puxavam imagens do registro desse serviço — uma flag mal aplicada, três serviços não relacionados fora do ar. Isso não é específico do Longhorn: quase todo CSI driver ou fixa /var/lib/kubelet ou exige reconfiguração separada pra seguir um root-dir movido, e o diretório de socket do device-plugin do próprio kubelet não respeita root-dir em nenhuma configuração — o que também teria quebrado o device plugin de GPU do qual o Jellyfin depende pra transcode por hardware.

Aplicando a flag: funciona, e o Longhorn quebra em minutos

A correção óbvia, e a que o k3s expõe explicitamente uma flag pra fazer, é --kubelet-arg=root-dir=/srv/k3s/agent/kubelet (conforme a referência de CLI do servidor k3s). Aplicada e reiniciada, funcionou exatamente como anunciado: o ephemeral-storage allocatable pulou pra ~796GiB, refletindo corretamente o /srv.

Também quebrou o CSI do Longhorn em minutos. O DaemonSet longhorn-csi-plugin do Longhorn fixa hostPath mounts e uma flag --kubelet-registration-path apontando pra /var/lib/kubelet/plugins/driver.longhorn.io/.... Com o diretório de trabalho real do kubelet agora em outro lugar, o socket de registro do Longhorn nunca apareceu onde o kubelet esperava, e todo pod novo que precisasse anexar um volume Longhorn falhava indefinidamente:

MountVolume.MountDevice failed ... driver name driver.longhorn.io not found

Isso derrubou o Postgres de um serviço Git self-hosted (PVC do Longhorn), que cascateou pro próprio serviço Git (sem banco de dados), que cascateou pra dois serviços internos de build/ETL que puxavam imagens do registro desse mesmo serviço Git — fora do ar, porque o serviço por trás do registro estava fora do ar. Uma flag mal aplicada, três serviços não relacionados fora do ar.

Isso é um bug específico do Longhorn?

Isso não é um bug específico do Longhorn — é o formato geral do problema de mover root-dir. Quase todo CSI driver ou fixa /var/lib/kubelet ou exige uma reconfiguração explícita e separada pra seguir o path movido: o Longhorn expõe um valor csi.kubeletRootDir no chart Helm, o csi-driver-smb expõe um valor linux.kubelet na documentação de instalação. Pior: o diretório de socket do device-plugin do próprio kubelet (/var/lib/kubelet/device-plugins/) é fixo e não respeita root-dir em nenhuma configuração — o que também teria quebrado o device plugin de GPU Intel do qual o Jellyfin depende pra transcode por hardware, além do Longhorn.

O quase-desastre: cp -a andando por dentro de mounts CSI vivos

Resumo: durante a reversão da mudança de root-dir, um mv /var/lib/kubelet /srv/k3s/agent/kubelet-data foi rodado num nó vivo — um mv cross-filesystem, que degrada pra cópia recursiva mais remoção, e uma cópia recursiva simples não para em fronteiras de mount. Ela entra dentro do que está montado na origem e copia o conteúdo vivo por baixo, e o /var/lib/kubelet tinha cerca de 28 mounts vivos: volumes tmpfs por pod, Secrets montados, e — o crítico — os dispositivos de bloco ext4 do Longhorn e um share SMB da biblioteca de mídia do Jellyfin. O cp -a duplicou conteúdo de volume Longhorn vivo antes de um set -e posterior abortar o processo, com 22G já copiados. Nenhum dado foi perdido — os mounts originais continuaram intactos — mas a cópia de 22G teve que ser identificada como lixo e descartada. A regra: nunca mv ou cp -a um diretório com mounts vivos por dentro; parar tudo que o usa primeiro, completamente, não só systemctl stop.

O mv que virou uma cópia de mounts vivos

Durante a reversão da mudança de root-dir, uma movimentação de diretório foi tentada no node C com pods ainda rodando: mv /var/lib/kubelet /srv/k3s/agent/kubelet-data. /var é nvme0n1p3; /srv é nvme0n1p5. Um mv cross-filesystem não é um rename — é uma cópia recursiva seguida da remoção da origem, e uma cópia recursiva simples não para em fronteiras de mount. Ela entra dentro de qualquer coisa montada dentro do diretório de origem e copia o conteúdo vivo por baixo, não o ponto de mount vazio.

/var/lib/kubelet tinha cerca de 28 mounts vivos por baixo dele na época:

MountTipoO que era
/var/lib/kubelet/pods/<uid>/volumes/kubernetes.io~projected/kube-api-access-*tmpfsvolumes de token de service account por pod, um por pod rodando
/var/lib/kubelet/pods/<uid>/volumes/kubernetes.io~secret/*tmpfsSecrets do Kubernetes montados (ex: longhorn-grpc-tls, memberlist)
/var/lib/kubelet/plugins/kubernetes.io/csi/driver.longhorn.io/<hash>/globalmountext4 em /dev/longhorn/pvc-*dispositivo de bloco por volume do Longhorn, um por PVC anexado ao nó
/var/lib/kubelet/pods/<uid>/volumes/kubernetes.io~csi/pvc-*/mountext4 no mesmo /dev/longhorn/pvc-*o mesmo volume Longhorn, bind-montado de novo dentro do diretório do pod
/var/lib/kubelet/plugins/.../smb.csi.k8s.io/<hash>/globalmount e o mount de pod correspondentecifs em //nas.lan/media-libraryo share SMB de 1000Gi media-library-pvc usado pelo Jellyfin

O cp -a foi direto nos mounts de dispositivo ext4 do Longhorn — backing stores reais de várias PVCs, não diretórios vazios — e começou a duplicar conteúdo de volume vivo. O script abortou (set -e disparou num passo posterior) depois que 22G já tinham sido copiados pra /srv/k3s/agent/kubelet-data, consistente com algumas das PVCs -config menores terem sido copiadas por completo antes do abort. O share SMB de 1000Gi ou ainda não tinha sido alcançado, ou o CIFS recusou a cópia em massa no meio do caminho. Checar du -xsh no /var/lib/kubelet original depois confirmou que o conteúdo real (222M, 42 diretórios de pod) e todos os mounts continuavam intactos e intocados — nenhum dado foi perdido — mas os 22G no destino tiveram que ser identificados como lixo copiado de PVCs vivas e descartados, não confundidos com um backup legítimo.

Em uma linha: nunca faça mv ou cp -a de um diretório que pode ter mounts vivos por dentro. Pare tudo que usa aquele diretório — completamente, não só systemctl stop — antes de tocar nele. A própria documentação do mv do coreutils é explícita que um move cross-device degrada pra copy-then-remove; ela não diz nada sobre fronteiras de mount porque essa é uma questão de semântica de filesystem que cp/mv nunca foram feitos pra resolver.

Por que o systemctl start não reaplicou a config revertida?

Um segundo erro, menor, apareceu durante o mesmo revert: systemctl start k3s foi rodado numa unit já ativa pra aplicar a config revertida. start numa unit que já está rodando é um no-op — não recarrega nada — então a config quebrada de root-dir continuou rodando silenciosamente em dois dos três nós até o erro ser percebido e systemctl restart ser usado no lugar.

A correção que funciona: bind mount do disco grande no path convencional

Resumo: a flag feita especificamente pra resolver isso — mover o root-dir — é a ferramenta errada, porque metade do ecossistema CSI fixa exatamente o path que ela deveria substituir. A correção que de fato funciona é deixar o root-dir no padrão /var/lib/kubelet e mudar o que está fisicamente montado ali: bind mount do disco de 838G direto nesse path convencional. É a mesma abordagem que a EKS usa por padrão em seus nós. Nada do que Longhorn, csi-driver-smb ou o device plugin de GPU esperam muda — o path continua /var/lib/kubelet pra todos eles — só o dispositivo de bloco por baixo muda. É nisso que o incidente inteiro se resume: não mover o path que todo consumidor fixo assume, e sim mover o que está por baixo dele, deixando a indireção no nível de filesystem fazer o trabalho que uma flag de configuração não consegue fazer com segurança.

A flag que existe especificamente pra resolver esse problema é a ferramenta errada, porque metade do ecossistema fixa o path que ela deveria substituir. A correção que de fato funciona é deixar o root-dir no padrão e mudar o que está fisicamente montado ali: bind mount do disco de 838G direto em /var/lib/kubelet. É a mesma abordagem que a EKS usa por padrão em seus nós — o path que kubelet, Longhorn, csi-driver-smb e o device plugin de GPU esperam nunca muda. Só o dispositivo de bloco por baixo muda.

Procedimento por nó

Resumo: o procedimento seguro é desabilitar, depois reiniciar o nó, depois verificar que está vazio antes de tocar em qualquer coisa, repetido um nó por vez. systemctl disable --now k3s (desabilitado, não só parado, pra não voltar a subir sozinho), depois um reboot completo — o passo que fecha a brecha exposta pelo quase-desastre anterior, porque systemctl stop sozinho deixa processos containerd-shim órfãos rodando com os mounts de volume deles junto. Depois do reboot, mount | grep /var/lib/kubelet precisa retornar vazio antes de qualquer outra coisa — o gate de segurança que faltou no incidente anterior. Depois, copiar (nunca mover) o diretório pequeno existente pra outro lugar, bind montar o disco grande no path convencional via /etc/fstab, reiniciar o k3s, e confirmar que o ephemeral-storage allocatable já reflete a partição grande antes de force-deletar qualquer pod preso em Unknown e esperar todo volume Longhorn daquele nó voltar a healthy antes de começar o próximo.

Repetido no node C, depois node A, depois node B — um nó por vez, totalmente verificado antes de começar o próximo:

  1. systemctl disable --now k3s — desabilitado, não só parado, pra não voltar a subir no meio do procedimento.
  2. reboot. Esse é o passo que fecha a brecha exposta pelo quase-desastre anterior: systemctl stop k3s sozinho deixa processos containerd-shim rodando como órfãos (shims são feitos pra sobreviver à morte do processo pai), e os mounts de volume deles sobrevivem junto. Um reboot completo derruba tudo de forma limpa, garantido.
  3. Depois do reboot, antes de tocar em qualquer coisa: mount | grep /var/lib/kubelet precisa retornar vazio. Esse é o gate de segurança que faltou no incidente anterior.
  4. Copiar (não mover) o /var/lib/kubelet pequeno existente pra /srv/k3s/agent/kubelet-root, verificar que tamanho e contagem de pods batem com o original, depois rm -rf /var/lib/kubelet && mkdir -p /var/lib/kubelet.
  5. Adicionar o bind mount no /etc/fstab pra sobreviver a reboots futuros:
    /srv/k3s/agent/kubelet-root /var/lib/kubelet none bind 0 0
    depois mount /var/lib/kubelet.
  6. systemctl enable --now k3s.
  7. Esperar Ready, então confirmar que o ephemeral-storage allocatable agora reflete a partição grande (~796GiB — output esperado 854501760354 bytes).
  8. Force-delete de qualquer pod preso em Unknown (objetos de pod órfãos do reboot abrupto) pra que os controllers os recriem do zero.
  9. Observar o robustness dos volumes Longhorn até todos voltarem a healthy naquele nó antes de começar o próximo.

Resultado nos três nós: Ready, ephemeral-storage allocatable 854501760354 bytes (~796GiB), bind mount persistido no /etc/fstab, todo pod Running, todo volume Longhorn healthy. Zero mudanças na config do Longhorn, csi-driver-smb ou device plugin de GPU — porque do ponto de vista deles, nada mudou de lugar.

Consequências e o que esperar do Longhorn nesse meio tempo

Resumo: duas coisas parecem alarmantes durante essa recuperação e não são. Um “disks are unavailable” ou ReplicaSchedulingFailure transitório no Longhorn logo após o reboot de um nó é esperado — checar se status.diskStatus volta pra Ready/Schedulable logo depois e seguir em frente. E como o Longhorn serializa o rebuild de réplica por padrão (limite concurrent-rebuild de 1), a contagem de volumes degradados oscila em vez de cair de forma monotônica enquanto uma fila de volumes é reconstruída um por vez — só preocupar se travar por completo. Um achado não relacionado apareceu e foi deliberadamente deixado de lado: o Longhorn manager estava na v1.12.0 enquanto a maioria dos volumes ainda referenciava engine images v1.11.0/v1.11.1. Um upgrade de engine ao vivo no meio do incidente, com volumes ainda se recuperando de três reboots de nó, teria tornado impossível diagnosticar corretamente qualquer sintoma novo — esse upgrade é uma tarefa separada, feita só depois que tudo estiver confirmado healthy de forma independente.

Duas coisas parecem alarmantes e não são:

Um aviso de “disks are unavailable” depois do reboot é uma regressão?

Um “disks are unavailable” ou ReplicaSchedulingFailure transitório no Longhorn logo após um reboot de nó é esperado, não uma regressão — checar se status.diskStatus em kubectl get nodes.longhorn.io <node> -o yaml volta pra Ready/Schedulable logo depois, e seguir em frente.

Por que a contagem de volumes degradados oscila durante o rebuild?

O rebuild de réplica do Longhorn é serializado por padrão (limite concurrent-rebuild de 1), então a contagem de volumes degradados oscila em vez de cair monotonicamente enquanto uma fila de volumes é reconstruída um por vez. Ver ela cair pra zero e depois subir brevemente no meio de um rebuild é normal; só preocupar se travar por completo.

Um achado não relacionado, deixado de propósito de lado: descompasso de versão do engine

Um achado não relacionado apareceu durante esse incidente e foi deliberadamente deixado de lado: o Longhorn manager estava na v1.12.0, mas a maioria dos volumes ainda referenciava engine images v1.11.0/v1.11.1. Um upgrade de engine ao vivo — por volume, ou via concurrent-automatic-engine-upgrade-per-node-limit — é uma tarefa separada, e fazer isso no meio do incidente, com volumes ainda se recuperando de três reboots de nó, teria tornado impossível diagnosticar corretamente qualquer sintoma novo. Fazer isso só depois que tudo estiver confirmado healthy de forma independente.

Quando isso não se aplica?

Resumo: nada disso se aplica se o seu data directory e o root-dir do kubelet já compartilham o mesmo filesystem — o caso comum de quem não separou os dois deliberadamente no bootstrap — porque o ephemeral-storage allocatable já reflete a capacidade real nesse cenário. E se você não roda nenhum CSI driver com paths fixos em /var/lib/kubelet — sem persistent volumes, ou um CSI driver que parametriza totalmente o path do kubelet e você já atualizou isso — mover o root-dir direto é mais simples que um bind mount e não tem desvantagem. A abordagem de bind mount existe especificamente pra interseção de duas condições: root-dir e o disco de dados divergiram, e pelo menos um CSI driver assume o path padrão. Checar as duas antes de usar essa abordagem; se só uma for verdadeira, uma correção mais simples se aplica.

Se o seu data directory e o root-dir do kubelet já vivem no mesmo filesystem — o caso comum de quem não separou os dois deliberadamente no bootstrap — nada disso se aplica, e o ephemeral-storage allocatable já reflete a capacidade real. E se você não roda nenhum CSI driver com paths fixos em /var/lib/kubelet (sem persistent volumes, ou um CSI driver que parametriza totalmente o path do kubelet e você já atualizou isso), mover o root-dir direto é mais simples que um bind mount e não tem desvantagem. A abordagem de bind mount existe especificamente pra interseção de “root-dir e disco de dados divergiram” e “pelo menos um CSI driver assume o path padrão” — checar os dois antes de usar essa abordagem.

Referências


Breno Zanato Detomini
Breno Zanato Detomini

Engenheiro de sistemas embarcados e redes, baseado no Brasil.

← Todos os posts