Вчора, 9 грудня, відбувся черговий реліз Kubernetes - 1.17. За традицією, що склалася для нашого блогу, ми розповідаємо про найбільш значущі зміни в новій версії.
Інформація, використана для підготовки цього матеріалу, взята з офіційного анонсу, таблиці Kubernetes enhancements tracking, CHANGELOG-1.17 та відповідних issues, pull requests, а також Kubernetes Enhancement Proposals (KEP). Отже, що нового?
Маршрутизація з урахуванням топології
Ось уже довгий час у спільноті Kubernetes чекали на цю фічу. Topology-aware service routing. Якщо КЕП за нею бере свій початок у жовтні 2018-го, а офіційний Посилення - 2 роки тому, то звичайні issues (начебто цього) - І зовсім старше ще на кілька років ...
Загальна ідея зводиться до того, щоб надати можливість реалізовувати локальну маршрутизацію для сервісів, що знаходяться в Kubernetes. «Локальність» у цьому випадку означає «той самий топологічний рівень» (topology level), Яким може бути:
однаковий для сервісів вузол,
та ж серверна стійка,
той самий регіон,
той самий хмарний провайдер,
...
Приклади використання такої фічі:
економія на трафіку в хмарних інсталяціях з безліччю зон доступності (multi-AZ) - див. свіжу ілюстрацію на прикладі трафіку одного регіону, але різних AZ в AWS;
менші затримки у продуктивності/краща пропускна спроможність;
шардований сервіс, що має локальну інформацію про сайт у кожному шарді;
розміщення fluentd (або аналогів) на один вузол із додатками, логи яких збираються;
Подробиці про те, як фіча влаштована і як їй вже можна скористатися, читайте у цієї статті від однієї з авторів.
Підтримка подвійного стека IPv4/IPv6
Значний прогрес зафіксовано в іншій мережній фічі: одночасної підтримки двох IP-стеків, що була вперше представлена в K8s 1.16. Зокрема, новий реліз приніс такі зміни:
у kube-proxy реалізована можливість одночасної роботи в обох режимах (IPv4 та IPv6);
в Pod.Status.PodIPsз'явилася підтримка downward API (одночасно з цим у /etc/hosts тепер вимагають для хоста додавати і IPv6-адресу);
підтримка двох стеків у ЯКЩО (Kubernetes IN Docker) та kubeadm;
оновлені e2e-тести.
Ілюстрація використання подвійного стека IPV4/IPv6 в KIND
Ініціатива щодо міграції плагінів томів на CSI - CSI Migration - Досягнула бета-версії. Ця фіча критична для того, щоб перекласти існуючі плагіни сховищ (in-tree) на сучасний інтерфейс (CSI, out-of-tree) непомітно для кінцевих користувачів Kubernetes. Адміністраторам кластерів буде достатньо активувати CSI Migration, після чого існуючі stateful-ресурси та робочі навантаження, як і раніше, «просто працюватимуть»… але вже з використанням актуальних CSI-драйверів замість застарілих, що входять до ядра Kubernetes.
На даний момент у статусі бета-версії готова міграція для драйверів AWS EBS (kubernetes.io/aws-ebs) та GCE PD (kubernetes.io/gce-pd). Прогнози щодо інших сховищ такі:
Про те, як «традиційна» підтримка сховищ у K8s прийшла до CSI, ми розповідали у цієї статті. А переходу міграції CSI у статус бета-версії присвячено окрема публікація у блозі проекту.
Крім того, статусу бета-версії (тобто включення за умовчанням) у релізі Kubernetes 1.17 досягла інша значуща функціональність у контексті CSI, що бере свій початок (альфа-реалізацію) в K8s 1.12, - створення снапшотів та відновлення з них. Серед змін, зроблених у Kubernetes Volume Snapshot на шляху до бета-релізу:
розбивка sidecar'а CSI external-snapshotter на два контролери,
додано секрет на видалення (deletion secret) як інструкція до вмісту снапшота тома,
новий фіналізатор (finalizer) для запобігання видаленню API-об'єкта снапшота за наявності зв'язків, що залишилися.
На момент релізу 1.17 фіча підтримується у трьох драйверів CSI: GCE Persistent Disk CSI Driver, Portworx CSI Driver і NetApp Trident CSI Driver. Докладніше про її реалізацію та використання можна прочитати в цієї публікації у блозі.
Cloud Provider Labels
Лейбли, які автоматично призначаються на створювані вузли та томи в залежності від використовуваного хмарного провайдера, були доступні в Kubernetes як бета-версія вже дуже давно - починаючи з релізу K8s 1.2 (квітень 2016 року!). Враховуючи їх широке застосування так довго, розробники вирішили, що настав час оголосити стабільну фічу (GA).
Тому всі вони були перейменовані відповідним чином (за топологіями):
… але, як і раніше, доступні і за своїми старими назвами (для зворотної сумісності). Проте всім адміністраторам рекомендується переходити на актуальні лейбли. Відповідна документація K8s було оновлено.
Мотивація до реалізації цієї фічі (відповідно до КЕП) така:
Хоча Kubernetes і може бути розгорнутий вручну, стандартом де-факто (якщо не де-юре) для цієї операції є використання kubeadm. Популярні інструменти управління системами типу Terraform спираються на kubeadm для деплою Kubernetes. Заплановані поліпшення в Cluster API включають компонований пакет для bootstrapping'а Kubernetes з kubeadm і cloud-init.
Без структурованого висновку навіть найнеобразливіші на перший погляд зміни можуть зламати Terraform, Cluster API та інший софт, який використовує результати роботи kubeadm.
У найближчих планах значиться підтримка (як структурованого висновку) для наступних команд kubeadm:
alpha certs
config images list
init
token create
token list
upgrade plan
version
Ілюстрація JSON-відповіді на команду kubeadm init -o json:
Взагалі ж, реліз Kubernetes 1.17 відбувся під девізом.Стабільність». Тому сприяв той факт, що дуже багато фічі в ньому (їх загальна кількість - 14) отримали статус GA. Серед таких:
«Захист фіналізатора» (Finalizer Protection) для балансувальників навантаження (перевірка відповідних ресурсів Service'а перед видаленням ресурсів LoadBalancer'а);
оптимізація kube-apiserver у продуктивності при роботі з безліччю watches, що спостерігають за ідентичними наборами об'єктів, — досягається завдяки уникненню повторної серіалізації одних і тих же об'єктів для кожного watcher'а.
Інші зміни
Повний список нововведень у Kubernetes 1.17, звичайно, не обмежується перерахованими вище. Ось деякі інші (а для більш повного переліку - див. КАНГЕЛОГ):
аналогічна зміна спіткало EndpointSlice API (теж з K8s 1.16), однак поки це рішення для поліпшення продуктивності/масштабуемості Endpoint API не активовано за умовчанням;