10 ноября 2026 года вышел .NET 11. Это релиз со стандартным сроком поддержки (STS): Microsoft обещает обновления до 14 ноября 2028 года, то есть ровно до того же дня, что и у LTS-версии .NET 10. Вместе с платформой вышел C# 15 — для проектов с net11.0 он включён по умолчанию, ничего в .csproj дописывать не нужно.
В статье разобраны все новинки языка: union-типы, закрытые иерархии классов, аргументы в выражениях коллекций, индексаторы-расширения, break и continue с меткой, статические члены интерфейсов на старых средах выполнения и предварительная версия новых правил безопасности памяти. Все примеры собраны и запущены на SDK 11.0.100, вывод — настоящий, с русской локалью (поэтому дробная часть отделяется запятой). Ошибки компилятора приведены с кодами, как их выдаёт dotnet build.
hello собирается под windows/amd64 на nanoserver без инструкции RUN, и docker buildx кладёт Windows-вариант в общий тег с полем os.version, по которому containerd выбирает манифест своей сборки. На Windows нет cgroups и OOM killer: лимиты становятся свойствами job object, requests в ядро не попадают, а процесс сверх лимита памяти получает отказ VirtualAlloc и падает сам, поэтому limits задают всем Windows-подам. Тома даёт csi-driver-smb, логи собирает Alloy в HostProcess-поде в Loki тестового кластера, метрики — windows-exporter, а узел обновляют ежемесячно через drain, перезагрузку и uncordon после того, как Calico пересоздал сеть.
Тестовый кластер собирается на kubeadm из Linux-мастера, двух Linux-воркеров и воркера на Windows Server 2025. Calico 3.33 ставится сразу в VXLAN без BGP, со strictAffinity, windowsDataplane: HNS и прямым адресом API в ConfigMap kubernetes-services-endpoint. На Windows-узле скрипты sig-windows-tools ставят containerd и kubelet службами, kubeadm join с JoinConfiguration сразу вешает taint os=windows:NoSchedule и maxPods: 60, Calico и kube-proxy приходят HostProcess-подами, а Windows-поды на основе Nano Server направляет на узел RuntimeClass windows-2025.
Сеть Windows-узла строит служба HNS, а исполняет VFP — расширение коммутатора Hyper-V: вместо veth у пода vNIC в сетевом отсеке, вместо маршрутов и nftables — политики HNS, которые CNI-плагин, kube-proxy в режиме kernelspace и Felix описывают через её API. Из плагинов на Windows работают Flannel, Calico и Antrea, Cilium — нет. Выбираем Calico в VXLAN Always с выключенным BGP и strictAffinity: CrossSubnet на Windows не работает, а учебный кластер с BGP такой узел не примет — для него собирается отдельный тестовый кластер.
С точки зрения API Windows-узел — такой же узел: kubelet подключается к kube-apiserver, продлевает Lease и получает поды, а планировщик и контроллеры работают с ним без изменений. Различия ниже уровня API: kubelet и containerd работают службами Windows, контейнер создаёт служба HCS как server silo на основе job object вместо namespaces и cgroups, а системные компоненты, которым нужен доступ к самому узлу, запускаются в HostProcess-контейнерах — привилегированных на Windows нет. Kubernetes поддерживает только изоляцию процессов, поэтому сборка ОС в образе должна совпадать со сборкой хоста, а поды разводят по узлам taint os=windows:NoSchedule и RuntimeClass.
Сначала control plane, потом узлы по одному: на мастере переключают репозиторий на новую минорную версию, ставят kubeadm, смотрят kubeadm upgrade plan и выполняют kubeadm upgrade apply, который по очереди заменяет static pods и продлевает сертификаты на год; затем на каждом воркере kubectl drain, kubeadm upgrade node, новый kubelet и uncordon. Минорные версии нельзя перепрыгивать, а kubelet не может быть новее apiserver. Перед началом — снапшот etcd, копия /etc/kubernetes/pki и проверка совместимости Calico и других компонентов.
etcd — хранилище «ключ — значение» с историей версий: kube-apiserver кладёт каждый объект под ключ вида /registry/<ресурс>/<неймспейс>/<имя>, а resourceVersion — это ревизия etcd. Запись считается выполненной, когда её подтвердило большинство членов по протоколу Raft, поэтому членов делают нечётное число, а потеря кворума останавливает API. Каждая запись ждёт fdatasync журнала WAL, так что etcd нужен локальный SSD. Резервная копия — etcdctl snapshot save по расписанию, зашифрованная и выгруженная вне кластера.
Контейнер пишет в stdout и stderr, containerd складывает строки в /var/log/pods/ на узле, а kubelet ротирует файлы по containerLogMaxSize; агент Grafana Alloy в DaemonSet читает их, добавляет метки пода и отправляет в Loki, который индексирует только метки и хранит чанки в S3. Трассы приложение шлёт по OTLP в OpenTelemetry Collector, а тот — в Tempo; сервисы связывает заголовок traceparent. В Grafana три источника сшиваются общими метками и trace id: от exemplar на графике — к трассе, от строки лога — к трассе и обратно.
Эта статья для тех, кому нужен работающий прокси и не хочется разбираться, как он устроен. Здесь только шаги: что нажать, что вставить и что должно получиться. Объяснений нет.
В конце у вас будет свой сервер, через который идёт весь трафик компьютера и телефона, а со стороны это выглядит как обычные визиты на большой сайт. Обычно на всё уходит около получаса.
Как это работает и почему настроено именно так, разобрано в двух подробных статьях: про сервер и клиент для Windows и про клиент для Android. Если что-то пойдёт не так, начните с таблицы в конце этой статьи: она подскажет, что сделать и какой раздел читать.
В кластере два независимых контура: metrics-server каждые 15 секунд снимает с kubelet CPU и память подов и отдаёт их через API metrics.k8s.io для kubectl top и HorizontalPodAutoscaler, а Prometheus сам опрашивает /metrics у экспортёров и приложений и хранит историю на диске. HPA считает ceil(реплики × текущее / целевое), причём проценты берутся от requests, а не от лимита или ядра. Prometheus с Grafana и Alertmanager ставится чартом kube-prometheus-stack, цели добавляются объектом ServiceMonitor, алерты — PrometheusRule.