Якщо ви підтримуєте драйвер CSI, який використовує токени службових облікових записів, Kubernetes v1.35 приносить удосконалення, про яке вам варто знати. З моменту введення функції TokenRequests, токени службових облікових записів, запитувані драйверами CSI, передавалися їм через поле volume_context. Хоча це працювало, це не ідеальне місце для конфіденційної інформації, і ми бачили випадки, коли токени випадково реєструвалися в драйверах CSI.
Kubernetes v1.35 вводить рішення бета-версії для вирішення цієї проблеми:
Опція драйвера CSI для токенів службових облікових записів через поле Secrets.
Це дозволяє драйверам CSI отримувати токени службових облікових записів
через поле secrets у NodePublishVolumeRequest,
яке є відповідним місцем для конфіденційних даних у специфікації CSI.
Коли драйвери CSI використовують функцію TokenRequests, вони можуть запитувати токени службових облікових записів для ідентифікації робочого навантаження, налаштовуючи поле TokenRequests у специфікації CSIDriver. Ці токени передаються драйверам як частина мапи атрибутів тому, використовуючи ключ csi.storage.k8s.io/serviceAccount.tokens.
Поле volume_context працює, але воно не призначене для конфіденційних даних. Через це виникають кілька викликів:
По-перше, інструмент protosanitizer, який використовують драйвери CSI, не розглядає контекст тому як конфіденційний, тому токени службових облікових записів можуть потрапити до журналів, коли реєструються gRPC-запити. Це сталося з CVE-2023-2878 у Secrets Store CSI Driver та CVE-2024-3744 у Azure File CSI Driver.
По-друге, кожен драйвер CSI, який хоче уникнути цієї проблеми, повинен реалізовувати власну логіку санітізації, що призводить до неузгодженості між драйверами.
Специфікація CSI вже має поле secrets у NodePublishVolumeRequest, яке призначене саме для такого роду конфіденційної інформації. Проблема полягає в тому, що ми не можемо просто змінити місце, де ми розміщуємо токени, без порушення роботи поточних драйверів CSI, які очікують їх у контексті тому.
Kubernetes v1.35 вводить механізм увімкнення, який дозволяє драйверам CSI вибирати, як вони отримують токени службових облікових записів. Таким чином, поточні драйвери продовжують працювати як і раніше, а інші драйвери можуть перейти до більш відповідного поля secrets, коли будуть готові.
Драйвери CSI можуть встановити нове поле у своїй специфікації CSIDriver:
#
# УВАГА: це приклад конфігурації.
# Не використовуйте це для власного кластера!
#
apiVersion: storage.k8s.io/v1
kind: CSIDriver
metadata:
name: example-csi-driver
spec:
# ... наявні поля ...
tokenRequests:
- audience: "example.com"
expirationSeconds: 3600
# Нове поле для опції доставки через secrets
serviceAccountTokenInSecrets: true # стандартно false
Поведінка залежить від поля serviceAccountTokenInSecrets:
Коли встановлено false (стандартно), токени розміщуються у VolumeContext з ключем csi.storage.k8s.io/serviceAccount.tokens, як і сьогодні.
Коли встановлено true, токени розміщуються лише у полі Secrets з тим самим ключем.
Функціональна можливість CSIServiceAccountTokenSecrets стандартно увімкнена як для kubelet, так і для kube-apiserver. Оскільки поле serviceAccountTokenInSecrets стандартно має значення false, увімкнення функціональної можливості не змінює жодної поточної поведінки. Усі драйвери продовжують отримувати токени через контекст тому, якщо вони явно не оберуться. Це пояснює, чому ми почувалися комфортно, починаючи з бета-версії, а не альфа.
Якщо ви підтримуєте драйвер CSI, який використовує токени службових облікових записів, ось як запровадити цю функцію.
Спочатку оновіть код вашого драйвера, щоб перевіряти обидва місця на наявність токенів. Це робить ваш драйвер сумісним з обома підходами, старим і новим:
const serviceAccountTokenKey = "csi.storage.k8s.io/serviceAccount.tokens"
func getServiceAccountTokens(req *csi.NodePublishVolumeRequest) (string, error) {
// Перевірити поле secrets спочатку (нова поведінка, коли драйвер обирається)
if tokens, ok := req.Secrets[serviceAccountTokenKey]; ok {
return tokens, nil
}
// Резерв до контексту тому (поточна поведінка)
if tokens, ok := req.VolumeContext[serviceAccountTokenKey]; ok {
return tokens, nil
}
return "", fmt.Errorf("service account tokens not found")
}
Ця резервна логіка є зворотньо сумісною та безпечною для випуску в будь-якій версії драйвера, навіть до оновлення кластерів до v1.35.
Автори драйверів CSI повинні дотримуватися певної послідовності при прийнятті цієї функції, щоб уникнути порушення наявних томів.
Підготовка драйвера (може відбутися будь-коли)
Ви можете почати підготовку вашого драйвера прямо зараз, додавши резервну логіку, яка перевіряє як поле secrets, так і контекст тому на наявність токенів. Ця зміна коду є зворотньо сумісною та безпечною для випуску в будь-якій версії драйвера, навіть до оновлення кластерів до v1.35. Ми заохочуємо вас додати цю логіку раніше, випускати релізи та навіть робити зворотні портування до гілок обслуговування, де це можливо.
Оновлення кластера та увімкнення функції
Після того, як ваш драйвер має резервну логіку, ось безпечний порядок розгортання для увімкнення функції в кластері:
serviceAccountTokenInSecrets: trueНайважливіше, що потрібно памʼятати, — це час. Якщо ваш DaemonSet драйвера CSI та обʼєкт CSIDriver знаходяться в одному маніфесті або чарті Helm, вам потрібно два окремі оновлення. Спочатку розгорніть нову версію драйвера з резервною логікою, зачекайте завершення розгортання DaemonSet, потім оновіть специфікацію CSIDriver, щоб встановити serviceAccountTokenInSecrets: true.
Також не оновлюйте CSIDriver перед тим, як усі поди драйвера будуть розгорнуті. Якщо ви це зробите, монтування томів зазнають невдачі на вузлах, які все ще працюють зі старою версією драйвера, оскільки ті поди перевіряють лише контекст тому.
Прийняття цієї функції допомагає в кількох аспектах:
protosanitizer автоматично правильно обробляє поле secrets, тому вам не потрібні специфічні для драйвера обхідні шляхиМи (Kubernetes SIG Storage) заохочуємо авторів драйверів CSI прийняти цю функцію та надати відгуки про досвід міграції. Якщо у вас є думки щодо дизайну API або виникають будь-які проблеми під час прийняття, будь ласка, зверніться до нас у каналі #csi на Kubernetes Slack (для запрошення відвідайте https://slack.k8s.io/).
Ви можете стежити за KEP-5538 щоб відстежувати прогрес у наступних релізах Kubernetes.