Modul 8 — Orchestrace: Kubernetes

36. Services a síťování v Kubernetes

Jak Kubernetes řeší service discovery a přístup k Podům pomocí objektu Service a jeho typů.

Odhadovaná délka studia: 55 minut · Stav: nehotovo

Technologie: Kubernetes

Úvod a kontext

Pody jsou z principu nestálé — Deployment je může kdykoliv smazat a
nahradit novými, a každý nový Pod dostane novou IP adresu. Kdyby se
jiné aplikace musely spoléhat na konkrétní IP Podu, přestaly by po
každém restartu fungovat. Kubernetes tento problém řeší objektem
Service — stabilním síťovým bodem, přes který se k sadě Podů
přistupuje bez ohledu na to, jak se mění jejich skutečné IP adresy.

Teorie

Jak Service funguje

Service vybírá cílové Pody pomocí selektoru (stejný princip jako u
ReplicaSetu — podle labelů), a Kubernetes automaticky udržuje seznam
IP adres aktuálně odpovídajících Podů v objektu Endpoints. Service
sama dostane stabilní virtuální IP (ClusterIP) a DNS jméno, které se
nemění, i když se Pody pod ní neustále obměňují.

apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8000

Tato Service nasměruje provoz na port 80 na libovolný Pod s labelem
app: web, na jeho port 8000. Uvnitř clusteru je dosažitelná pod DNS
jménem web (v rámci stejného namespace) nebo plně kvalifikovaně
web.<namespace>.svc.cluster.local.

Typy Services

  • ClusterIP (výchozí) — Service dostane IP adresu platnou jen
    uvnitř clusteru. Používá se pro komunikaci mezi vnitřními
    komponentami (např. backend → databáze), není zvenčí dosažitelná.
  • NodePort — kromě ClusterIP otevře i stejný port na každém
    worker uzlu clusteru (v rozsahu 30000–32767). Umožňuje přístup
    zvenčí přes <libovolný-uzel>:<nodePort>, ale v produkci se
    používá jen výjimečně (nepohodlné porty, chybí load balancing mezi
    uzly).
  • LoadBalancer — v cloudovém prostředí (AWS, GCP, Azure)
    automaticky vytvoří externí cloudový load balancer, který směruje
    provoz do clusteru. Nejběžnější způsob vystavení služby veřejně v
    cloudu.
  • ExternalName — nevytváří žádný proxy, jen DNS alias mapující
    jméno Service na externí DNS jméno (např. napojení na databázi mimo
    cluster pod interním jménem).
apiVersion: v1
kind: Service
metadata:
  name: web-public
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8000

Jak se provoz skutečně směruje: kube-proxy

Komponenta kube-proxy běžící na každém worker uzlu sleduje objekty
Service a Endpoints a nastavuje síťová pravidla (typicky přes
iptables nebo modernější IPVS), která realizují load balancing
provozu na ClusterIP mezi jednotlivé backend Pody. Z pohledu klienta
uvnitř clusteru je to transparentní — stačí znát DNS jméno Service.

Service discovery přes DNS

Kubernetes cluster typicky provozuje interní DNS server (CoreDNS),
který automaticky vytváří DNS záznam pro každou Service. Aplikace v
Podu se tak může připojit k databázové Service jednoduše pod jejím
jménem, stejně jako to fungovalo u vlastní Docker bridge sítě v
předchozím modulu — jen v mnohem větším měřítku a s automatickým
load balancingem mezi replikami.

Praktický příklad

Kompletní ukázka: interní databázová Service (ClusterIP) a veřejně
dostupná webová Service (LoadBalancer).

# db-service.yaml — jen uvnitř clusteru
apiVersion: v1
kind: Service
metadata:
  name: db
spec:
  selector:
    app: db
  ports:
    - port: 5432
      targetPort: 5432
---
# web-service.yaml — dostupná zvenčí přes cloudový load balancer
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8000
kubectl apply -f db-service.yaml -f web-service.yaml
kubectl get services
# web má EXTERNAL-IP přidělenou cloudovým load balancerem,
# db má jen ClusterIP a je dosažitelná pouze zevnitř clusteru

# aplikace v Podu "web" se připojí k databázi pod jménem "db":
kubectl exec -it deploy/web -- psql -h db -U postgres

Shrnutí

Service poskytuje stabilní síťovou identitu (IP a DNS jméno) pro
skupinu Podů vybraných podle labelu, přestože se skutečné IP adresy
Podů neustále mění. ClusterIP slouží pro vnitřní komunikaci,
NodePort a hlavně LoadBalancer pro přístup zvenčí, ExternalName pro
alias na externí systém. Směrování provozu zajišťuje kube-proxy na
základě Endpoints, které Kubernetes automaticky udržuje aktuální.

Kontrolní otázky

  1. Proč nelze v Kubernetes spoléhat na přímou IP adresu konkrétního
    Podu pro komunikaci mezi aplikacemi?
  2. Jaký je rozdíl mezi typy Service ClusterIP, NodePort a
    LoadBalancer a kdy použijete který?
  3. Jak Service ví, které Pody má zahrnout do load balancingu?
  4. Mini cvičení: nasaďte Deployment se 2 replikami jednoduchého
    webového image (např. nginx) s labelem app: demo, vytvořte k
    němu ClusterIP Service se selektorem app: demo a ověřte příkazem
    kubectl run tmp --rm -it --image=busybox -- wget -O- demo, že
    provoz projde na některý z Podů.

Lekce na sebe nejsou zamčené — libovolnou lekci můžete otevřít i označit jako hotovou v jakémkoliv pořadí.