Hur man kör Istio med Kubernetes i produktion. Del 1

Vad är Istio? Это так называемый Service mesh, технология, которая добавляет уровень абстракции над сетью. Мы перехватываем весь или часть трафика в кластере и производим определенный набор операций с ним. Какой именно? Например, делаем умный роутинг, или реализуем подход circuit breaker, можем организовывать «canary deployment», частично переключая трафик на новую версию сервиса, а можем ограничивать внешние взаимодействия и контролировать все походы из кластера во внешнюю сеть. Есть возможность задавать policy правила для контроля походов между разными микросервисами. Наконец, мы можем получить всю карту взаимодействия по сети и сделать унифицированный сбор метрик полностью прозрачно для приложений.

Du kan läsa om hur mekanismen fungerar i den officiella dokumentationen. Istio är verkligen ett kraftfullt verktyg som kan lösa många uppgifter och problem. I den här artikeln skulle jag vilja besvara de viktigaste frågorna som vanligtvis dyker upp i början av arbetet med Istio. Det kommer att hjälpa dig att förstå det snabbare.

Hur man kör Istio med Kubernetes i produktion. Del 1

Arbetsprincip.

Istio består av två huvudsakliga zoner — kontrollplanen och dataplans. Kontrollplanen innehåller de viktigaste komponenterna som säkerställer att de andra fungerar korrekt. I den aktuella versionen (1.0) har kontrollplanen tre huvudkomponenter: Pilot, Mixer, Citadel. Citadel kommer vi inte att titta på, den behövs för att generera certifikat för att säkerställa användningen av mutual TLS mellan tjänster. Låt oss ta en närmare titt på hur Pilot och Mixer är konstruerade och deras syfte.

Hur man kör Istio med Kubernetes i produktion. Del 1

Pilot är den huvudsakliga styrkomponenten som sprider all information om vad vi har i klustret – tjänster, deras endpoints och routingregler (till exempel, regler för Canary deployment eller regler för circuit breaker).

Mixer är en valfri komponent i kontrollplanen som ger möjlighet att samla in mätvärden, loggar och all information om nätverksinteraktion. Den övervakar också efterlevnaden av policyregler och efterlevnaden av begränsningar för hastighet.

Data plane implementeras med hjälp av sidecar proxycontainrar. Som standard används en kraftfull proxyserver envoy. Den kan ersättas med en annan implementering, till exempel nginx (nginmesh).

För att Istio ska fungera helt transparent för applikationerna finns det ett automatiskt injektionssystem. Den senaste implementeringen passar för versioner av Kubernetes 1.9+ (mutational admission webhook). För versioner av Kubernetes 1.7, 1.8 finns möjlighet att använda Initializer.

Sidecarcontainrarna kopplar ihop med Pilot via GRPC-protokollet, vilket gör att man kan optimera modellen för att push:a ändringar som sker i klustret. GRPC började användas i Envoy från och med version 1.6, i Istio används det sedan version 0.8 och representerar pilot-agent — ett wrapper i golang över envoy, som konfigurerar startparametrarna.

Pilot och Mixer är helt stateless komponenter, allt tillstånd hålls i minnet. Konfigurationen för dem anges i form av Kubernetes Custom Resources, som sparas i etcd.
Istio-agenten får adressen till Pilot och öppnar en GRPC-stream till den.

Som jag redan nämnt, implementerar Istio all funktionalitet helt transparent för applikationerna. Låt oss förstå hur. Algoritmen är följande:

  1. Vi distribuerar en ny version av tjänsten.
  2. Beroende på tillvägagångssättet för injektering läggs istio-init-container och istio-agent-container (envoy) till under konfigurationens tillämpningssteg, eller så kan de redan ha hårdputsats in i Pod-entiteten i Kubernetes.
  3. istio-init-container är ett skript som tillämpar iptables-regler för podden. Det finns två alternativ för att konfigurera hur trafiken ska dirigeras till istio-agent-container: att använda omdirigeringsregler för iptables, eller TPROXY. Vid tidpunkten för artikelskrivandet används som standard tillvägagångssättet med omdirigeringsregler. I istio-init finns möjlighet att ställa in vilken trafik som ska fångas och dirigeras till istio-agent. Till exempel, för att fånga all inkommande och all utgående trafik, måste följande parametrar ställas in -i och -b till värdet *. Specifika portar kan anges som behöver fångas. För att undvika att fånga en viss undernät kan den anges med hjälp av flaggan -x.
  4. Efter att init-containrarna har körts startas huvudcontainrarna, inklusive pilot-agent (envoy). Den ansluter till redan distribuerat Pilot via GRPC och får information om alla existerande tjänster och routingpolicys i klustret. Utifrån den mottagna informationen konfigurerar den kluster och registrerar direkt endpointarna för våra applikationer i Kubernetes-klustret. Det är också viktigt att notera att envoy dynamiskt konfigurerar lyssnare (par av IP, port) som den börjar lyssna på. Därför, när förfrågningar går in i podden, omdirigeras de med hjälp av omdirigeringsregler för iptables till sidecar, och envoy kan framgångsrikt hantera dessa anslutningar och förstå vart trafiken ska proxys. Vid denna tidpunkt sker också överföring av information till Mixer, som vi kommer att titta närmare på senare, och överföring av tracing spanar.

Resultatet blir ett helt nätverk av envoy-proxy-servrar som vi kan konfigurera från en enda punkt (Pilot). Alla inkommande och utgående förfrågningar passerar genom envoy. Endast TCP-trafik fångas. Det betyder att Kubernetes-tjänstens IP löses med hjälp av kube-dns via UDP utan förändringar. Efter att namnlösningen sker fångas den utgående förfrågan och bearbetas av envoy, som sedan beslutar vilken endpoint förfrågan ska skickas till (eller om den inte ska skickas, vid åtkomstpolicies eller om circuit breaker-algoritmen aktiveras).

Nu när vi har förstått Pilot, måste vi förstå hur Mixer fungerar och varför det behövs. Den officiella dokumentationen kan läsas. ). Ett typiskt exempel på användning:.

Mixer i sin nuvarande form består av två komponenter: istio-telemetry och istio-policy (tidigare var detta en komponent som hette istio-mixer fram till version 0.8). Båda dessa utgör mixer, där var och en ansvarar för sin specifika uppgift. Istio telemetry tar emot rapporter via GRPC från sidecar-containrarna om vem som går vart och med vilka parametrar. Istio-policy tar emot Check-förfrågningar för att verifiera efterlevnaden av Policy-regler. Policy-kontroller utförs givetvis inte för varje förfrågan, utan cachas på klienten (i sidecar) under en viss tid. Rapportkontroller skickas som batch-förfrågningar. Hur man konfigurerar och vilka specifika parametrar som ska skickas kommer vi att titta på lite senare.

Mixer förväntas vara en hög tillgänglig komponent som säkerställer en oavbruten drift av insamling och behandling av telemetrydata. Systemet blir i slutändan en flervärdsbuffert. Ursprungligen buffras data på sidan av sidecar-containrar, sedan på sidan av mixer och skickas sedan till så kallade mixer-backends. Om någon komponent i systemet skulle sluta fungera växer bufferten, och efter att systemet återställs spolas den. Mixer-backends utgör slutpunkter för att skicka telemetrydata: statsd, newrelic osv. Du kan skriva din egen backend, och det är ganska enkelt, och vi kommer att se hur man gör det.

Hur man kör Istio med Kubernetes i produktion. Del 1

Sammanfattningsvis är arbetsflödet för istio-telemetry så här.

  1. Tjänst 1 skickar en begäran till tjänst 2.
  2. Vid utgång från tjänst 1 packas begäran in i dess egen sidecar.
  3. Sidecar envoy övervakar hur begäran passerar till tjänst 2 och förbereder den nödvändiga informationen.
  4. Den skickar sedan denna information till istio-telemetry med hjälp av en Rapport-begäran.
  5. Istio-telemetry avgör om rapporten ska skickas till backends, till vilka specifika backends och vilka data som ska skickas.
  6. Istio-telemetry skickar rapportdata till backend om det är nödvändigt.

Låt oss nu titta på hur man implementerar Istio-systemet som bara består av de grundläggande komponenterna (Pilot och sidecar envoy).

Först tittar vi på den grundläggande konfigurationen (mesh) som Pilot läser:

apiVersion: v1
kind: ConfigMap
metadata:
  name: istio
  namespace: istio-system
  labels:
    app: istio
    service: istio
data:
  mesh: |-

    # För tillfället skickar vi inte någon tracing information (pilot kommer att konfigurera envoy så att skickande inte kommer att ske)
    enableTracing: false

    # För tillfället anger vi inte mixer-endpointar, så att sidecar-containrarna inte skickar information dit
    #mixerCheckServer: istio-policy.istio-system:15004
    #mixerReportServer: istio-telemetry.istio-system:15004

    # Vi ställer in tidsintervallet som envoy kommer att fråga Pilot (detta är för den gamla versionen av envoy proxy)
    rdsRefreshDelay: 5s

    # Standardkonfiguration för envoy sidecar
    defaultConfig:
      # som rdsRefreshDelay
      discoveryRefreshDelay: 5s

      # håll standard (väg till konfiguration och binär för envoy)
      configPath: "/etc/istio/proxy"
      binaryPath: "/usr/local/bin/envoy"

      # standardnamn för den körande sidecar-containern (används till exempel i servicenamn vid skickande av tracing spans)
      serviceCluster: istio-proxy

      # tid som envoy kommer att vänta innan den tvingat avslutar alla etablerade anslutningar
      drainDuration: 45s
      parentShutdownDuration: 1m0s

      # som standard används REDIRECT-regler för iptables. Kan ändras till TPROXY.
      #interceptionMode: REDIRECT

      # Port där adminpanelen för varje sidecar-container (envoy) kommer att köras
      proxyAdminPort: 15000

      # Adress dit trace kommer att skickas via zipkin-protokollet (i början stängde vi av själva överföringen, så detta fält kommer för närvarande inte att användas)
      zipkinAddress: tracing-collector.tracing:9411

      # statsd-adress för att skicka metrics för envoy-containrar (stänger av)
      # statsdUdpAddress: aggregator:8126

      # Stänger av stöd för alternativet Mutual TLS
      controlPlaneAuthPolicy: NONE

      # Adress där istio-pilot kommer att lyssna för att informera alla sidecar-containrar om service discovery
      discoveryAddress: istio-pilot.istio-system:15007

Vi kommer att placera alla huvudkomponenter för kontrollplanet (control plane) i namespace istio-system i Kubernetes.

Minimalt behöver vi bara implementera Pilot. För detta kommer vi att använda denna konfiguration.

Och vi kommer att konfigurera manuell injecting av sidecar-containern.

Init-container:

initContainers:
 - name: istio-init
   args:
   - -p
   - "15001"
   - -u
   - "1337"
   - -m
   - REDIRECT
   - -i
   - '*'
   - -b
   - '*'
   - -d
   - ""
   image: istio/proxy_init:1.0.0
   imagePullPolicy: IfNotPresent
   resources:
     limits:
       memory: 128Mi
   securityContext:
     capabilities:
       add:
       - NET_ADMIN

Och sidecar:

       name: istio-proxy
       args:
         - "bash"
         - "-c"
         - |
           exec /usr/local/bin/pilot-agent proxy sidecar 
           --configPath 
           /etc/istio/proxy 
           --binaryPath 
           /usr/local/bin/envoy 
           --serviceCluster 
           service-name 
           --drainDuration 
           45s 
           --parentShutdownDuration 
           1m0s 
           --discoveryAddress 
           istio-pilot.istio-system:15007 
           --discoveryRefreshDelay 
           1s 
           --connectTimeout 
           10s 
           --proxyAdminPort 
           "15000" 
           --controlPlaneAuthPolicy 
           NONE
         env:
         - name: POD_NAME
           valueFrom:
             fieldRef:
               fieldPath: metadata.name
         - name: POD_NAMESPACE
           valueFrom:
             fieldRef:
               fieldPath: metadata.namespace
         - name: INSTANCE_IP
           valueFrom:
             fieldRef:
               fieldPath: status.podIP
         - name: ISTIO_META_POD_NAME
           valueFrom:
             fieldRef:
               fieldPath: metadata.name
         - name: ISTIO_META_INTERCEPTION_MODE
           value: REDIRECT
         image: istio/proxyv2:1.0.0
         imagePullPolicy: IfNotPresent
         resources:
           requests:
             cpu: 100m
             memory: 128Mi
           limits:
             memory: 2048Mi
         securityContext:
           privileged: false
           readOnlyRootFilesystem: true
           runAsUser: 1337
         volumeMounts:
         - mountPath: /etc/istio/proxy
           name: istio-envoy

För att allt ska starta framgångsrikt måste du skapa en ServiceAccount, ClusterRole, ClusterRoleBinding, CRD för Pilot, vars beskrivningar kan hittas. ). Ett typiskt exempel på användning:.

I slutändan måste tjänsten, där vi injicerar sidecar med envoy, lyckas starta, få all discovery från piloten och hantera förfrågningar.

Det är viktigt att förstå att alla komponenter i kontrollplanet är stateless-applikationer och kan enkelt skalas horisontellt. All data finns i etcd som anpassade resursbeskrivningar av Kubernetes.

Dessutom har Istio (än så länge experimentellt) möjlighet att köras utanför klustret och att se och dela service discovery mellan flera Kubernetes-kluster. Mer om detta kan du läsa. ). Ett typiskt exempel på användning:.

Vid installation av flera kluster bör följande begränsningar beaktas:

  1. Pod CIDR och Service CIDR måste vara unika över alla kluster och får inte överlappa varandra.
  2. Alla Pod CIDR måste vara tillgängliga från alla Pod CIDR mellan klustren.
  3. Alla Kubernetes API-servrar måste vara tillgängliga för varandra.

Detta är grundläggande information som hjälper dig att börja arbeta med Istio. Men det finns många fällor. Till exempel specifikationer för extern trafikrouting (utanför klustret), metoder för att felsöka sidecars, profilering, konfigurering av mixer och skriva en anpassad mixer backend, samt konfigurering av tracing-mekanismen och dess arbete med hjälp av envoy.
Vi kommer att gå igenom allt detta i kommande publiceringar. Ställ gärna era frågor så ska jag försöka belysa dem.

Källa: habr.com

Köp pålitlig webbhotell med DDoS-skydd, VPS VDS-servrar 🔥 Köp pålitlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster