Kubernetes v1.37: Відстеження моменту останнього використання PersistentVolumeClaim (Бета)

Kubernetes v1.37 переводить функціональну можливість PersistentVolumeClaimUnusedSinceTime у Beta (стандартно увімкнену). Завдяки цій функції контролер захисту PersistentVolumeClaim (PVC) додає стан Unused до кожного PVC, повідомляючи вам, чи посилається на нього наразі будь-який запущений Pod, без потреби у власних інструментах чи перехресних посиланнях.

Визначення станів PVC в API дивіться у довіднику API PersistentVolumeClaim. Читайте далі, щоб дізнатися, як працює стан Unused та як його використовувати.

Чому відстежувати використання PVC?

У великомасштабних кластерах Kubernetes користувачі часто створюють PVC, а потім видаляють повʼязані Podʼи, не прибираючи сховище, оскільки Kubernetes не видаляє PVC автоматично, коли їхні Podʼи видаляються (щоб захистити від випадкової втрати даних). З часом ці осиротілі PVC можуть накопичуватися, мовчки споживаючи ємність сховища та збільшуючи витрати на хмарні ресурси.

До Kubernetes v1.37 було легко визначити невикористовуваний PersistentVolume, але набагато складніше зʼясувати, чи все ще використовується PVC. Для цього потрібно було зіставляти Podʼи, PersistentVolumes та PVC протягом потенційно великого проміжку часу. Адміністратори часто вдавалися до власних конвеєрів моніторингу або скриптів, щоб відповісти на, здавалося б, просте запитання: "Чи використовує цей том хтось насправді?"

Функція PersistentVolumeClaimUnusedSinceTime вирішує цю проблему, роблячи відповідь доступною нативно у статусі PVC. Щойно функцію увімкнено, кожен PVC отримує стан Unused, яким керує контролер захисту PVC.

Сценарії використання

  • Адміністратор сховища: «Я хочу знати, які PVC у моєму кластері не використовуються жодним Podʼом, щоб безпечно визначити осиротілі томи та запланувати їх видалення».
  • DevOps-інженер: «Я хочу отримати список PVC, у яких стан Unused має значення True, щоб автоматизувати очищення в середовищах розробки».

Як це працює?

Контролер захисту PVC, який уже стежить за Podʼами, щоб забезпечувати захист обʼєктів сховища, що використовуються, тепер також керує новим станом Unused на PVC.

Стан працює так:

СценарійСтатус стануПричина
Жоден нетермінальний Pod не посилається на PVCUnused=TrueNoPodsUsingPVC
Принаймні один запущений або очікуючий Pod посилається на PVCUnused=FalsePodUsingPVC

Кілька деталей, на які варто звернути увагу:

  • Завершені Podʼи не враховуються: Pod, який завершився (фаза Succeeded або Failed), не тримає PVC позначеним як такий, що використовується. Це означає, що пакетні завдання з restartPolicy: Never не завадять PVC стати Unused=True після їх завершення.
  • Очікуючі Podʼи враховуються: Навіть Pod, який неможливо запланувати, (наприклад, з неможливим селектором вузла) все одно вважається таким, що використовує PVC. Наміру використати том достатньо.
  • Кілька Podʼів: Якщо кілька Podʼів посилаються на один і той самий PVC, стан переходить у Unused=True лише після того, як останній нетермінальний Pod буде видалено або він завершиться.

Використання lastTransitionTime, щоб дізнатися, коли PVC став неактивним

Як і кожен стан Kubernetes, стан Unused має стандартне поле lastTransitionTime. Це означає, що ви отримуєте корисний бонус безкоштовно: коли стан переходить з False у True, lastTransitionTime фіксує точний момент, коли PVC став неактивним. Ви можете використовувати цю позначку часу, щоб відповісти на запитання на кшталт "як довго цей PVC простоює без використання?", наприклад, щоб знайти PVC, які були неактивними понад 30 днів (див. приклад запиту нижче).

Що змінилося від Alpha до Beta?

Kubernetes v1.36 представив цю функцію як Alpha, де вам доводилося вмикати функціональну можливість PersistentVolumeClaimUnusedSinceTime явно. Для Beta у v1.37 функціональну можливість увімкнено стандартно, а функція має повне покриття наскрізними тестами.

Як це використовувати

Оскільки функція є Beta і стандартно увімкнена в Kubernetes v1.37, стан Unused зʼявлятиметься на PVC автоматично. Ось покроковий приклад, щоб побачити її в дії:

  1. Створіть PVC:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: my-data
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
    
  2. Через короткий час перевірте стани PVC:

    kubectl get pvc my-data -o jsonpath='{.status.conditions[*]}' | jq .
    

    Ви маєте побачити стан Unused зі статусом True та причиною NoPodsUsingPVC:

    {
      "lastProbeTime": null,
      "lastTransitionTime": "2026-09-14T12:03:11Z",
      "message": "No pods are currently referencing this PVC",
      "reason": "NoPodsUsingPVC",
      "status": "True",
      "type": "Unused"
    }
    
  3. Створіть Pod, який використовує PVC:

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-app
    spec:
      containers:
      - name: app
        image: busybox
        command: ["sleep", "3600"]
        volumeMounts:
        - name: data
          mountPath: /data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: my-data
    
  4. Перевірте стан знову: тепер він має показувати Unused=False:

    kubectl get pvc my-data -o jsonpath='{.status.conditions[?(@.type=="Unused")].status}'
    

    Вивід:

    False
    
  5. Видаліть Pod і зачекайте, поки стан перейде назад у Unused=True:

    kubectl delete pod my-app
    kubectl get pvc my-data -o jsonpath='{.status.conditions[?(@.type=="Unused")]}'
    

    Стан має знову показувати Unused=True з причиною NoPodsUsingPVC.

Пошук невикористовуваних PVC у кластері

Щоб отримати список усіх PVC, які не використовувалися понад 30 днів, ви можете скористатися командою на кшталт:

Примітка:

Ця команда використовує jq, командний JSON-процесор.
kubectl get pvc -A -o json | jq -r '
  .items[]
  | select(.status.conditions[]? | select(.type=="Unused" and .status=="True"))
  | select(
      (.status.conditions[] | select(.type=="Unused") | .lastTransitionTime) as $t
      | (now - ($t | fromdateiso8601)) > (30 * 86400)
    )
  | "\(.metadata.namespace)/\(.metadata.name) unused since \(.status.conditions[] | select(.type=="Unused") | .lastTransitionTime)"
'

Що далі?

Залежно від відгуків та впровадження, проєкт Kubernetes планує перевести цю функцію до загальної доступності (GA) в одному з майбутніх випусків. Якщо у вас є відгуки щодо цієї функції, будь ласка, створіть тікет у репозиторії kubernetes/kubernetes.

Щоб дізнатися більше про це вдосконалення, зверніться до KEP-5541: час останнього використання PersistentVolumeClaim.

Долучення до спільноти

Проєкт Kubernetes завжди вітає нових учасників. Якщо ви хочете долучитися, ви можете приєднатися до нас у SIG Storage.

Якщо ви хочете поділитися відгуками, ви можете зробити це на нашому публічному каналі Slack (відвідайте https://slack.k8s.io/, щоб отримати запрошення, якщо воно вам потрібне).

Особлива подяка учасникам, які допомогли спроєктувати та реалізувати цю функцію (в алфавітному порядку):

Востаннє змінено September 22, 2026 at 2:07 PM PST: [uk] Ukrainian translation (all-in-one) (bf98050d8c)