Kubernetes (AKS) dla backendów IoT: architektura wielodostępna skalująca się do milionów urządzeń
Większość backendów IoT zaczyna na Azure App Service. To właściwy wybór dla pierwszych 10 000 urządzeń: zarządzany, tani, szybki do wdrożenia. Potem klient podłącza 250 000 czujników w jeden weekend, telemetria przechodzi ze stabilnej w skokową, zespół dodaje procesor strumieniowy, trzy kolejne API, długotrwałe zadanie eksportu i usługę raportowania. Nagle App Service zaczyna z tobą walczyć.
Ten artykuł to architektura, którą wdrażamy w FSS Technology, gdy produkt IoT przekracza próg, przy którym Kubernetes zaczyna się opłacać. Obejmuje moment migracji z App Service, referencyjną topologię AKS dla IoT, decyzje wielodostępności, które mają znaczenie, autoskalowanie sterowane KEDA na Service Bus, stos obserwowalności, który standaryzujemy, GitOps z Flux, zarządzanie sekretami z tożsamością obciążeń (workload identity), wybory magazynu szeregów czasowych oraz wzorce kosztowe, które utrzymują platformę w zdrowiu w skali milionów urządzeń. Uzupełnia lżejszy pipeline, który opisujemy w naszym artykule o potoku danych IoT; to jest to, co przychodzi później.
Kiedy wyrasta się z App Service dla IoT
App Service jest doskonały, dopóki którekolwiek z poniższych nie stanie się prawdą:
- Potrzebujesz więcej niż 30 planów w różnych regionach, aby izolować obciążenia
- Zimne starty na Functions w trybie consumption blokują scenariusze czasu rzeczywistego
- Uruchamiasz długotrwałe procesory strumieniowe, które nie pasują do modelu żądanie/odpowiedź
- Potrzebujesz precyzyjnych proporcji CPU i pamięci, których poziomy App Service nie oferują
- Polityki sieciowe, sidecary lub service mesh są na mapie drogowej
- Izolacja wielodostępna wymaga granic obliczeniowych per-najemca, nie tylko danych per-najemca
- Chcesz spójnej parzystości środowiska lokalnego z produkcją (Docker Compose do Kubernetes jest bliżej niż Docker Compose do App Service)
Jeśli kiwasz głową przy trzech lub więcej z tych punktów, AKS to następny przystanek. Jeśli tylko przy jednym, napraw objaw i zostań tam, gdzie jesteś. Kubernetes nie jest darmowy, a podatek operacyjny jest realny. Zaplanuj co najmniej jednego inżyniera, który odpowiada za operacje klastra od początku do końca, zanim się zdecydujesz; „ktoś z DevOps to ogarnie” nie jest planem.
Referencyjna topologia AKS dla IoT
Klaster, który wdrażamy dla produkcyjnych obciążeń IoT, ma cztery logiczne warstwy, każda we własnej puli węzłów z odpowiednimi SKU maszyn wirtualnych.
- Warstwa ingest: bezstanowe usługi przyjmujące telemetrię z Azure IoT Hub, brokerów MQTT i webhooków HTTP. Podatna na skoki, wrażliwa na opóźnienia. Uruchamiaj na maszynach serii D z włączonym autoskalowaniem klastra.
- Warstwa przetwarzania: procesory strumieniowe, wzbogacanie, silniki reguł, zadania downsamplingu. Ograniczona przepustowością. Uruchamiaj na maszynach serii F zoptymalizowanych pod obliczenia.
- Warstwa API: endpointy REST i GraphQL dla aplikacji najemców, aplikacji mobilnych, integracji partnerskich. Zrównoważona pamięciowo. Uruchamiaj na maszynach serii D z HPA na tempie żądań.
- Warstwa magazynu telemetrii: nie sama baza danych, ale usługi bramkowe rozmawiające z Event Hubs, Azure Data Explorer, blob i Cosmos DB. Uruchamiaj na maszynach serii D z magazynem o wysokim IOPS, jeśli potrzebne jest buforowanie lokalne.
Pody systemowe (CoreDNS, kube-proxy, ingress, obserwowalność) żyją w dedykowanej systemowej puli węzłów z co najmniej trzema węzłami dla wysokiej dostępności. Nigdy nie uruchamiaj obciążeń systemowych w tej samej puli co obciążenia aplikacyjne; hałaśliwy najemca nigdy nie powinien móc wywłaszczyć ingressu.
Wzorzec Azure IoT Hub plus AKS
IoT Hub pozostaje właściwą bramą urządzeń, nawet gdy reszta backendu jest na AKS. Posiada tożsamość urządzeń, obsługę protokołów MQTT/AMQP, stan bliźniaka urządzenia (device twin) i wywoływanie metod bezpośrednich. AKS posiada logikę biznesową.
Wzorzec integracji:
- Urządzenia łączą się z IoT Hub przez MQTT 3.1.1 lub MQTT 5
- IoT Hub kieruje telemetrię do Event Hubs (endpoint domyślny) lub tematów Service Bus (trasy filtrowane)
- Obciążenia AKS konsumują z Event Hubs za pomocą EventProcessorClient z checkpointingiem w magazynie blob
- Polecenia chmura-do-urządzenia wracają przez IoT Hub za pomocą metod bezpośrednich lub pożądanych właściwości bliźniaka
- AKS publikuje do Service Bus dla rozgłaszania, z subskrybentami per najemca lub per funkcja
Ten wzorzec jest naturalnym rozszerzeniem prostszej architektury, którą opisujemy w linkowanym powyżej artykule o potoku danych IoT. Model przetwarzania jest ten sam; podłoże uruchomieniowe jest potężniejsze, a granice per-najemca stają się egzekwowalne zamiast aspiracyjne.
Wielodostępność: przestrzeń nazw na najemcę vs klaster na najemcę
To najbardziej brzemienna w skutki decyzja architektoniczna, jaką podejmiesz. Oba modele działają; zły wybór będzie cię boleśnie kosztować.
Przestrzeń nazw na najemcę
Zalety: tanie, proste w obsłudze, jedna płaszczyzna kontroli do aktualizacji, łatwa analityka między najemcami. Wady: współdzielony promień rażenia klastra, ryzyko hałaśliwego sąsiada na płaszczyźnie danych, trudniej zadowolić rygorystyczne reżimy zgodności wymagające izolacji obliczeniowej, kubelet i apiserver stają się współdzielonymi wąskimi gardłami skalowania.
Używaj tego, gdy najemcy są podobnej wielkości, ufają sobie nawzajem (lub ufają, że ty wyegzekwujesz izolację), a wartość prostoty operacyjnej przeważa nad ścisłą izolacją. Stosuj NetworkPolicy, ResourceQuota, LimitRange i Pod Security Admission do każdej przestrzeni nazw domyślnie.
Klaster na najemcę
Zalety: twarda izolacja, niezależny rytm aktualizacji, SLO per-najemca, prosta historia zgodności. Wady: 5- do 10-krotny koszt operacyjny, trudniejsze funkcje między najemcami, złożoność zarządzania flotą (Azure Arc, Cluster API lub Fleet Manager stają się obowiązkowe).
Używaj tego, gdy najemcy są wystarczająco duzi, by uzasadnić narzut (zwykle 50 000+ urządzeń każdy), lub gdy wymagają tego regulacje (obronność, regulowana farmacja, niektóre scenariusze rządowe).
Hybryda, którą zwykle wdrażamy
Współdzielony klaster z przestrzenią nazw na najemcę dla długiego ogona, plus dedykowane klastry dla kilku dużych klientów, którzy potrzebują lub chcą twardej izolacji. Działa to, ponieważ kod platformy jest identyczny; różni się tylko topologia wdrożenia. GitOps sprawia, że duplikacja jest do opanowania.
Ingress z NGINX i AGIC
Dla wewnętrznego ruchu wschód-zachód i subdomen najemców pod współdzielonym apeksem NGINX Ingress Controller jest pragmatycznym domyślnym wyborem: dobrze rozumiany, szybki, nieskończenie regulowalny. Dla ingressu natywnego dla Azure z WAF i integracją z Azure Front Door właściwym wyborem jest Application Gateway Ingress Controller (AGIC).
Wzorzec, który uruchamiamy dla backendów IoT, to AGIC na publicznej krawędzi dla pokrycia WAF i DDoS, NGINX wewnątrz klastra dla routingu najemców i terminacji TLS per subdomena. Cert-manager z Let’s Encrypt dla zautomatyzowanych certyfikatów, ExternalDNS dla automatycznych rekordów Azure DNS.
Skalowanie KEDA na głębokości kolejki Service Bus
Horizontal Pod Autoscaler na CPU jest błędny dla IoT. Przeciążenie zwrotne nie ujawnia się jako nasycenie CPU; ujawnia się jako rosnąca kolejka. KEDA (Kubernetes Event-driven Autoscaling) czyta kolejkę i skaluje odpowiednio.
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: telemetry-processor-scaler
namespace: tenant-acme
spec:
scaleTargetRef:
name: telemetry-processor
pollingInterval: 15
cooldownPeriod: 120
minReplicaCount: 2
maxReplicaCount: 60
triggers:
- type: azure-servicebus
metadata:
queueName: telemetry-ingest
namespace: fss-prod-sb
messageCount: "500"
authenticationRef:
name: keda-azure-auth
---
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: keda-azure-auth
namespace: tenant-acme
spec:
podIdentity:
provider: azure-workload
identityId: a1b2c3d4-...
Dwie liczby, które mają znaczenie: messageCount to cel per-replika, a nie łączny próg. Ustaw go na przepustowość jednej repliki w stanie ustalonym, aby KEDA skalowała, utrzymując ten stosunek. cooldownPeriod zapobiega migotaniu; 120 sekund to rozsądna wartość domyślna dla IoT, gdzie skoki są częste.
Dla Event Hubs (ingest telemetrii) KEDA ma dedykowany wyzwalacz, który skaluje na opóźnieniu partycji, a nie na głębokości kolejki. Używaj go; skalowanie oparte na CPU dla konsumentów Event Hubs jest zawsze błędne, bo konsument jest ograniczony operacjami IO na brokerze.
Obserwowalność: Prometheus, Grafana, OpenTelemetry, Application Insights
Stos, który standaryzujemy, dzieli odpowiedzialność czysto:
- Metryki: Prometheus skrobiący pody, kube-state-metrics i node-exporter. Magazyn długoterminowy w zarządzanym Prometheusie Azure Monitor. Wizualizacja w Azure Managed Grafana.
- Logi: logi kontenerów do Azure Monitor Container Insights, z politykami retencji per przestrzeń nazw. Logi aplikacji strukturyzowane jako JSON, nigdy jako wolny tekst.
- Ślady: OpenTelemetry SDK w każdej usłudze, eksporter OTLP do Azure Monitor Application Insights. Próbkowanie na poziomie 100 procent dla błędów, 1 procent dla sukcesów.
- Monitoring syntetyczny: testy dostępności Application Insights wobec subdomen najemców, z sondami wieloregionalnymi.
Rzecz nie do negocjacji: każdy log, metryka i ślad niesie identyfikator najemcy jako etykietę lub atrybut. Bez tego nie odpowiesz na pytanie „jak radzi sobie najemca X teraz”, które jest pytaniem najważniejszym, gdy coś płonie.
GitOps z Flux lub ArgoCD
Ręczne kubectl apply na produkcji to błąd w sztuce. GitOps zamyka pętlę: Git jest źródłem prawdy, klaster uzgadnia się sam ku Gitowi, dryft jest niemożliwy, bo zostaje skorygowany w ciągu minut.
Flux v2 to lżejszy wybór i integruje się natywnie z AKS przez rozszerzenie GitOps. ArgoCD ma bogatszy interfejs i lepszą ergonomię wieloklastrową. Oba działają; wybierz na podstawie preferencji zespołu i trzymaj się tego.
Układ repozytorium, którego używamy:
fleet/
clusters/
prod-weu/
flux-system/
infrastructure/ # ingress, cert-manager, KEDA, obserwowalność
tenants/
acme/
contoso/
prod-eus/
...
apps/
telemetry-processor/
base/ # baza Helm chart lub kustomize
overlays/
prod/
staging/
charts/
fss-iot-stack/ # parasolowy Helm chart, patrz poniżej
Struktura values Helm
Parasolowy Helm chart dla platformy ze strukturą values, która pozwala nadpisaniom per-najemca pozostać małymi.
global:
region: westeurope
env: prod
imageRegistry: fssprod.azurecr.io
workloadIdentity:
enabled: true
clientId: ""
observability:
otlpEndpoint: https://otel.fss.cc
ingest:
replicas: 3
image:
repository: fss/iot-ingest
tag: 2.14.0
resources:
requests: { cpu: 250m, memory: 512Mi }
limits: { cpu: 1, memory: 1Gi }
iotHub:
eventHubEndpoint: ""
consumerGroup: ingest
processing:
replicas: 4
keda:
enabled: true
minReplicas: 4
maxReplicas: 80
queueName: telemetry-ingest
targetMessageCount: 500
api:
replicas: 2
ingress:
host: api.tenant.fss.cc
tlsSecret: api-tls
storage:
adx:
cluster: fss-adx-weu
database: telemetry
cosmos:
account: fss-cosmos-weu
database: device-state
tenants:
- name: acme
deviceQuota: 250000
overrides:
processing:
targetMessageCount: 1000
Kształt tych values ma znaczenie tak samo jak ich zawartość: każdy parametr, który różni się per najemca, musi żyć pod tenants[].overrides, nigdy rozsypany po całym charcie. To właśnie utrzymuje platformę w łatwej do utrzymania formie w miarę wzrostu liczby najemców. Sparuj chart z Helmfile lub Flux Kustomization, który renderuje wydania per-najemca z jednego źródła prawdy.
Zarządzanie sekretami z Azure Key Vault i workload identity
Montowanie łańcuchów połączeń jako sekretów Kubernetes przez zwykłe values Helm to historyczny antywzorzec. Nowoczesne podejście wykorzystuje Azure Workload Identity plus Secrets Store CSI Driver.
- Każde obciążenie działa jako ServiceAccount Kubernetes powiązany z Azure Managed Identity
- Managed Identity ma zawężone uprawnienia do Key Vault
- Sekrety są montowane jako pliki (lub synchronizowane do sekretów Kubernetes) przez sterownik CSI, z automatyczną rotacją
- Żadne długotrwałe poświadczenia nie żyją w klastrze, w Git ani w pipeline'ach
W połączeniu z prywatnymi endpointami na Key Vault i dostępem ograniczonym IP zadowala to nawet rygorystyczne przeglądy zgodności bez dodawania złożoności operacyjnej dla zespołów aplikacyjnych.
Wybory baz danych dla szeregów czasowych
Azure Data Explorer (ADX)
Nasz domyślny wybór dla telemetrii IoT powyżej 1 miliarda zdarzeń miesięcznie. ADX pozyskuje przy ekstremalnych tempach (zmierzyliśmy utrzymane 1,2 miliona zdarzeń na sekundę na skromnym klastrze), KQL jest doskonały do analityki szeregów czasowych, a integruje się natywnie z Event Hubs jako źródłem strumieniowym. Koszt skaluje się z rozmiarem klastra i retencją, nie z liczbą zapytań. Sparuj ADX z widokami zmaterializowanymi dla typowych zapytań pulpitu; opóźnienie do pierwszego bajtu dla 30-dniowego zbiorczego zestawienia spada z sekund do dziesiątek milisekund.
TimescaleDB
Właściwy wybór, gdy telemetria musi żyć w magazynie relacyjnym z kluczami obcymi do danych operacyjnych, lub gdy SQL jest twardym wymogiem dla konsumentów w dalszej części łańcucha. Uruchom go na Azure Database for PostgreSQL Flexible Server lub samodzielnie hostowany na AKS dla pełnej kontroli. Hypertabele i ciągłe agregaty obsługują większość potrzeb zimnego magazynu i downsamplingu.
InfluxDB i inne
InfluxDB jest w porządku dla mniejszych wdrożeń poniżej 100 milionów zdarzeń miesięcznie. ClickHouse konkuruje z ADX pod względem przepustowości, ale wymaga większej odpowiedzialności operacyjnej. Cosmos DB ze wzorcem szeregów czasowych działa dla scenariuszy o niskiej kardynalności, ale szybko drożeje w skali IoT.
Wzorce optymalizacji kosztów
Pięć dźwigni porusza rachunek bardziej niż cokolwiek innego.
- Prawidłowo dobrane pule węzłów: seria F dla obliczeń, seria D dla zrównoważonych, seria E dla obciążeń pamięciożernych. Mieszanie SKU między pulami ogranicza nadmierne provisionowanie.
- Pule węzłów Spot dla bezstanowego przetwarzania: warstwy przetwarzania sterowane KEDA działają pięknie na Spot z redukcją kosztów 60 do 80 procent. Zawsze miej bazową linię poza Spot dla odporności.
- Instancje zarezerwowane i plany oszczędnościowe: zobowiązania 1-roczne i 3-letnie dla bazowej puli węzłów. Typowe oszczędności 30 do 40 procent.
- Warstwowy magazyn telemetrii: gorący w ADX przez 30 dni, ciepły w Parquet na blobie przez 1 rok, zimny w archiwalnym blobie dłużej. Tabele zewnętrzne ADX czynią zimną warstwę odpytywalną na żądanie.
- Dyscyplina egress: utrzymuj ruch w regionie, używaj prywatnych endpointów, aby unikać opłat za publiczny egress, wsadowo zapisuj w dół łańcucha, aby ograniczyć koszty per-operacja.
Dla typowej wielodostępnej platformy IoT obsługującej 1 do 2 milionów urządzeń te wzorce razem tną koszt bieżący mniej więcej o połowę w porównaniu z naiwnym wdrożeniem. Widzimy miesięczny koszt w stanie ustalonym w zakresie 12 000 do 22 000 EUR dla tej skali, zdominowany przez ADX i egress, a nie obliczenia.
Lista kontrolna doskonałości operacyjnej
- Autoskalowanie klastra włączone z rozsądnym min i max per pula
- Pod Disruption Budgets na każdym obciążeniu
- Sondy liveness, readiness i startup poprawnie rozróżnione
- NetworkPolicy z domyślną odmową i jawnymi regułami zezwalającymi
- Skanowanie obrazów w CI, podpisywanie obrazów Notation, kontrola dopuszczenia z Ratify lub Kyverno
- Backup obciążeń stanowych z Velero, testowane przywrócenia kwartalnie
- Podręcznik odtwarzania po awarii z udokumentowanym RTO i RPO per poziom najemcy
Żadne z tych nie jest opcjonalne w skali, którą ten artykuł zakłada. Wzorce, które stosujemy w naszej szerszej praktyce DevOps i fundamenty chmurowe, które oferujemy klientom, są wokół nich zbudowane. Ta sama płaszczyzna kontroli obsługuje backendy stojące za YIS i OMNIYON; wzorce są sprawdzone w polu pod realnym obciążeniem floty.
Podsumowanie
AKS nie jest srebrną kulą; to podłoże, które użyte z dyscypliną pozwala platformie IoT skalować się od jednego najemcy do setek i od tysięcy urządzeń do milionów bez przepisywania backendu. Wzorce w tym artykule (rozdzielenie warstwy ingest, KEDA na głębokości kolejki, GitOps, workload identity, ADX dla telemetrii, warstwowy magazyn i Spot dla przetwarzania) to to, co decyduje o różnicy między klastrem Kubernetes, który działa, a operacyjnym koszmarem.
Jeśli prowadzisz produkt IoT, który wyrósł z App Service, lub projektujesz nową platformę, która musi skalować się od pierwszego dnia, zespół FSS Cloud Infrastructure może zaprojektować, wdrożyć i obsługiwać backendy IoT oparte na AKS od początku do końca. Dostarczyliśmy ten stos dla grup hotelarskich, flot morskich i operatorów przemysłowych, i oferujemy go jako zarządzaną platformę lub jednorazowe zlecenie, które doprowadzi twój zespół do produkcji. Porozmawiaj z nami o tygodniowym przeglądzie architektury, zanim zdecydujesz się na kierunek.