Udostępnij przez


Wdrażanie bram wyjściowych dla dodatku Istio Service Mesh do Azure Kubernetes Service

Artykuł przedstawia, jak wdrożyć bramki ruchu wychodzącego dla dodatku Istio service mesh w klastrze usługi Azure Kubernetes Service (AKS).

Przegląd

Brama egress Istio może służyć jako scentralizowany punkt do monitorowania i ograniczania ruchu wychodzącego z aplikacji w sieci. Za pomocą dodatku Istio można wdrożyć wiele bram egress w różnych przestrzeniach nazw, co umożliwia skonfigurowanie wybranej przez Ciebie topologii bram egress: bramy egress na klaster, na przestrzeń nazw, na obciążenie itp. Usługa AKS zarządza aprowizowaniem i cyklem życia bram egress dodatku Istio, ale należy utworzyć niestandardowe zasoby Istio, aby kierować ruch z aplikacji w siatce za pośrednictwem bramy egress, stosować zasady oraz zbierać dane telemetryczne.

Brama ruchu wychodzącego jako dodatkowy element Istio jest również oparta na funkcji Statycznej Bramy Ruchu Wychodzącego, która przypisuje stały prefiks źródłowego adresu IP do zasobników ruchu wychodzącego Istio. Można użyć tego predykowalnego zakresu adresów IP ruchu wychodzącego dla reguł zapory i innych mechanizmów filtrowania ruchu wychodzącego. Korzystając z bramy wyjściowej Istio na podstawie statycznej bramy wyjściowej, można zastosować zasady Istio L7, zasady oparte na tożsamości oraz ograniczenia oparte na adresach IP w celu zapewnienia dogłębnej ochrony kontroli ruchu wychodzącego. Ponadto kierowanie ruchu wychodzącego za pośrednictwem bramy ruchu wychodzącego Istio umożliwia różnym obciążeniom kierowanie ruchu za pośrednictwem pul węzłów Static Egress Gateway, nie wymagając bezpośrednich zmian w zasobnikach lub wdrożeniach aplikacji.

Ograniczenia i wymagania

  • Możesz włączyć maksymalnie 500 bram ruchu wychodzącego jako dodatek Istio na klaster.
  • Nazwy bram egress dodatku Istio muszą być unikatowe w ramach przestrzeni nazw.
  • Nazwy dodatków bramy ruchu wychodzącego Istio muszą zawierać się między znakami 1-53, muszą składać się tylko z małych liter alfanumerycznych, znaków "-" i ".", i muszą zaczynać się i kończyć znakiem alfanumerycznym. Nazwy powinny być również prawidłową nazwą systemu nazw domen (DNS). Wyrażenie regularne używane do walidacji nazw to ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$.
  • Korzystanie z interfejsu API bramy Kubernetes na potrzeby zarządzania ruchem wychodzącym za pomocą dodatku Istio jest obsługiwane tylko w przypadku modelu wdrażania ręcznego.
  • Ponieważ statyczna brama ruchu wychodzącego nie jest obecnie obsługiwana w klastrach podsieci Azure CNI, brama ruchu wychodzącego dodatku Istio również nie jest obsługiwana w klastrach podsieci Pod.

Wymagania wstępne

Włączanie dodatku Istio

Przewodnik zakłada, że postępowałeś zgodnie z dokumentacją, aby włączyć dodatek Istio na klastrze AKS.

Aktualizowanie wersji interfejsu wiersza polecenia platformy Azure

Musisz użyć wersji azure-cli2.80.0 lub nowszej. Uruchom polecenie az --version , aby znaleźć swoją azure-cli wersję i uruchomić az upgrade polecenie , aby uaktualnić.

Włączanie i konfigurowanie statycznej bramy ruchu wychodzącego

Postępuj zgodnie z instrukcjami w dokumentacji Static Egress Gateway, aby włączyć Static Egress Gateway w klastrze, utworzyć pulę węzłów trybu gateway, i utworzyć zasób.

Włącz bramę ruchu wychodzącego Istio

Uwaga / Notatka

Zasobniki bramy egress dodatku Istio nie są przypisane do gateway puli węzłów. Pula węzłów gateway jest używana tylko do obsługi ruchu wychodzącego i nie obsługuje standardowych obciążeń. Jeśli potrzebujesz zasobników bramy ruchu wychodzącego zaplanowanych na określone węzły, możesz użyć węzłów systemowych usługi AKS lub etykiety węzła azureservicemesh/istio.replica.preferred . Zasobniki mają powiązania węzłów z preferencją ważoną 100 dla węzłów systemowych usługi AKS (oznaczonych etykietą kubernetes.azure.com/mode: system) oraz z preferencją ważoną 50 dla węzłów oznaczonych etykietą azureservicemesh/istio.replica.preferred: true.

Użyj az aks mesh enable-egress-gateway, aby włączyć bramę ruchu wychodzącego Istio w klastrze AKS. Należy określić nazwę bramy ruchu wychodzącego Istio oraz nazwę StaticGatewayConfiguration, którą utworzono na etapie wymagań wstępnych. Można również określić przestrzeń nazw do wdrożenia bramy ruchu wychodzącego Istio, przy czym musi być to ta sama przestrzeń nazw, w której utworzono StaticGatewayConfiguration. Jeśli nie określisz przestrzeni nazw, brama egress zostanie utworzona w przestrzeni nazw aks-istio-egress.

Najlepszym rozwiązaniem jest poczekać, aż StaticGatewayConfiguration zostanie przypisany do egressIpPrefix, zanim włączysz bramę egress Istio, używając tej konfiguracji bramy.

az aks mesh enable-egress-gateway --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --istio-egressgateway-name $ISTIO_EGRESS_NAME --istio-egressgateway-namespace $ISTIO_EGRESS_NAMESPACE --gateway-configuration-name $ISTIO_SGC_NAME

Sprawdź, czy usługa została utworzona dla bramy wyjściowej.

kubectl get svc $ISTIO_EGRESS_NAME -n $ISTIO_EGRESS_NAMESPACE

Powinna zostać wyświetlona ClusterIP usługa bramy ruchu wychodzącego:

NAME              TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)                    AGE
asm-egress-test   ClusterIP   10.0.128.17   <none>        15021/TCP,80/TCP,443/TCP   6d4h

Możesz również sprawdzić, czy wdrożono bramę egress dla Istio i czy zasobniki tej bramy mają adnotację kubernetes.azure.com/static-gateway-configuration ustawioną na wartość gatewayConfigurationName.

ASM_REVISION=$(az aks show -g $RESOURCE_GROUP -n $CLUSTER_NAME | jq '.serviceMeshProfile.istio.revisions[0]' | sed 's/"//g')

kubectl get deployment $ISTIO_EGRESS_NAME-$ASM_REVISION -n $ISTIO_EGRESS_NAMESPACE -o jsonpath={.spec.template.metadata.annotations."kubernetes\.azure\.com\/static-gateway-configuration"}

Możesz ponownie uruchomić polecenie az aks mesh enable-egress-gateway, aby utworzyć kolejną bramę egress Istio.

Uwaga / Notatka

Po przeprowadzeniu drobnej aktualizacji dodatku Istio, dla każdej bramy ruchu wychodzącego zostanie utworzone kolejne wdrożenie związane z nową wersją płaszczyzny sterowania.

Kierowanie ruchu przez bramę egress Istio

Zbiór outboundTrafficPolicy.mode

Domyślnie Istio outboundTrafficPolicy.mode jest ustawiona na ALLOW_ANY, co oznacza, że Envoy przekazuje dalej żądania dla nieznanych usług. Najlepsza praktyka w zakresie bezpieczeństwa to ustawienie Istio outboundTrafficPolicy.mode na REGISTRY_ONLY, aby serwer proxy Istio blokował żądania do usług, których nie dodano do rejestru usług Istio. Hosty poza klastrem można dodać do rejestru usług Istio za pomocą polecenia ServiceEntry.

Można skonfigurować element outboundTrafficPolicy.mode na poziomie obejmującym siatkę przy użyciu dodatku Istio shared MeshConfig, lub użyć zasobu niestandardowego Sidecar do kierowania na konkretne przestrzenie nazw lub obciążenia.

apiVersion: v1
kind: ConfigMap
metadata:
  name: istio-shared-configmap-asm-1-27
  namespace: aks-istio-system
data:
  mesh: |-
    outboundTrafficPolicy:
      mode: REGISTRY_ONLY

Wdrażanie przykładowej aplikacji

W tym przykładzie przeprowadzamy wdrożenie aplikacji curl w tej samej przestrzeni nazw co brama wyjściowa dodatku Istio. Pamiętaj, aby ISTIO_EGRESS_NAMESPACE oznaczyć etykietą istio.io/rev, tak aby wdrożony zasobnik aplikacji został wyposażony w sidecar.

kubectl label namespace $ISTIO_EGRESS_NAMESPACE istio.io/rev=$ASM_REVISION

Następnie wdróż przykładową aplikację:

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.27/samples/curl/curl.yaml -n $ISTIO_EGRESS_NAMESPACE

Powinien zostać wyświetlony curl zasobnik z wstrzykiwanym kontenerem przyczepki:

NAME                                       READY   STATUS    RESTARTS   AGE
curl-5b549b49b8-bcgts                      2/2     Running   0          13s

Spróbuj wysłać żądanie bezpośrednio z curl do edition.cnn.com.

SOURCE_POD=$(kubectl get pod -n $ISTIO_EGRESS_NAMESPACE -l app=curl -o jsonpath={.items..metadata.name})

kubectl exec -n $ISTIO_EGRESS_NAMESPACE "$SOURCE_POD" -c curl -- curl -sSL -o /dev/null -D - http://edition.cnn.com/politics

Jeśli ustawisz outboundTrafficPolicy.mode na REGISTRY_ONLY, to żądanie curl powinno zakończyć się niepowodzeniem, ponieważ nie utworzyłeś ServiceEntry dla edition.cnn.com. Jeśli outboundTrafficPolicy.mode jest ALLOW_ANY, żądanie powinno zakończyć się powodzeniem.

Aby rzeczywiście kierować żądania z zasobnika edition.cnn.com do bramy ruchu wychodzącego dodatku Istio curl, należy utworzyć ServiceEntry i skonfigurować inne zasoby niestandardowe Istio. Postępuj zgodnie z instrukcjami w jednej z kolejnych sekcji, aby skonfigurować bramę egress HTTP, bramę egress HTTPS, lub bramę egress, która inicjuje połączenie TLS (Transport Layer Security).

Przed rozpoczęciem któregokolwiek z tych następujących scenariuszy ustaw następujące zmienne środowiskowe.

ISTIO_EGRESS_DEPLOYMENT=$ISTIO_EGRESS_NAME-$ASM_REVISION
EGRESS_GTW_SELECTOR=$(kubectl get deployment $ISTIO_EGRESS_DEPLOYMENT -n $ISTIO_EGRESS_NAMESPACE -o jsonpath={.metadata.labels.istio})

Możesz również włączyć rejestrowanie dostępu do usługi Envoy za pośrednictwem interfejsu API MeshConfig lub Telemetrii. Po włączeniu rejestrowania dostępu możesz sprawdzić, czy ruch przepływa przez bramę egress, analizując dzienniki kontenera istio-proxy.

kubectl logs -l istio=$EGRESS_GTW_SELECTOR -n $ISTIO_EGRESS_NAMESPACE

Konfigurowanie bramy egress Istio HTTP

  1. Utwórz element ServiceEntry dla elementu :edition.cnn.com
kubectl apply -n $ISTIO_EGRESS_NAMESPACE -f - <<EOF
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
  name: cnn
spec:
  hosts:
  - edition.cnn.com
  ports:
  - number: 80
    name: http-port
    protocol: HTTP
  - number: 443
    name: https
    protocol: HTTPS
  resolution: DNS
EOF
  1. Utwórz elementy Gateway, VirtualService i DestinationRule, aby skierować ruch HTTP z aplikacji curl do edition.cnn.com przez bramę egress. Pamiętaj, aby odpowiednio ustawić selektor bramy i w pełni kwalifikowaną nazwę domeny (FQDN) na podstawie selektora etykiet istio we wdrożeniu bramy egress.
kubectl apply -n $ISTIO_EGRESS_NAMESPACE -f - <<EOF
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
    istio: $EGRESS_GTW_SELECTOR
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - edition.cnn.com
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: egressgateway-for-cnn
spec:
  host: $ISTIO_EGRESS_NAME.$ISTIO_EGRESS_NAMESPACE.svc.cluster.local
  subsets:
  - name: cnn
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: direct-cnn-through-egress-gateway
spec:
  hosts:
  - edition.cnn.com
  gateways:
  - istio-egressgateway
  - mesh
  http:
  - match:
    - gateways:
      - mesh
      port: 80
    route:
    - destination:
        host: $ISTIO_EGRESS_NAME.$ISTIO_EGRESS_NAMESPACE.svc.cluster.local
        subset: cnn
        port:
          number: 80
      weight: 100
  - match:
    - gateways:
      - istio-egressgateway
      port: 80
    route:
    - destination:
        host: edition.cnn.com
        port:
          number: 80
      weight: 100
EOF
  1. Spróbuj wysłać żądanie HTTP z curl zasobnika do :edition.cnn.com
kubectl exec -n $ISTIO_EGRESS_NAMESPACE "$SOURCE_POD" -c curl -- curl -sSL -o /dev/null -D - http://edition.cnn.com/politics

Odpowiedź HTTP/2 200 powinna być widoczna.

  1. Uprzątnij zasoby
kubectl delete serviceentry cnn -n $ISTIO_EGRESS_NAMESPACE
kubectl delete gateway istio-egressgateway -n $ISTIO_EGRESS_NAMESPACE
kubectl delete virtualservice direct-cnn-through-egress-gateway -n $ISTIO_EGRESS_NAMESPACE
kubectl delete destinationrule egressgateway-for-cnn -n $ISTIO_EGRESS_NAMESPACE

Konfigurowanie bramy wychodzącej HTTPS Istio

  1. Utwórz protokół HTTPS ServiceEntry dla :edition.cnn.com
kubectl apply -n $ISTIO_EGRESS_NAMESPACE -f - <<EOF
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
  name: cnn
spec:
  hosts:
  - edition.cnn.com
  ports:
  - number: 443
    name: tls
    protocol: TLS
  resolution: DNS
EOF
  1. Utwórz elementy Gateway, VirtualService i DestinationRule, aby skierować ruch HTTP z aplikacji curl do edition.cnn.com przez bramę egress. Należy odpowiednio ustawić selektor bramy i FQDN usługi zgodnie z selektorem etykiety istio we wdrożeniu bramy ruchu wychodzącego.
kubectl apply -n $ISTIO_EGRESS_NAMESPACE -f - <<EOF
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
    istio: $EGRESS_GTW_SELECTOR
  servers:
  - port:
      number: 443
      name: tls
      protocol: TLS
    hosts:
    - edition.cnn.com
    tls:
      mode: PASSTHROUGH
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: egressgateway-for-cnn
spec:
  host: $ISTIO_EGRESS_NAME.$ISTIO_EGRESS_NAMESPACE.svc.cluster.local
  subsets:
  - name: cnn
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: direct-cnn-through-egress-gateway
spec:
  hosts:
  - edition.cnn.com
  gateways:
  - mesh
  - istio-egressgateway
  tls:
  - match:
    - gateways:
      - mesh
      port: 443
      sniHosts:
      - edition.cnn.com
    route:
    - destination:
        host: $ISTIO_EGRESS_NAME.$ISTIO_EGRESS_NAMESPACE.svc.cluster.local
        subset: cnn
        port:
          number: 443
  - match:
    - gateways:
      - istio-egressgateway
      port: 443
      sniHosts:
      - edition.cnn.com
    route:
    - destination:
        host: edition.cnn.com
        port:
          number: 443
      weight: 100
EOF
  1. Spróbuj wysłać żądanie HTTPS z curl do :edition.cnn.com
kubectl exec "$SOURCE_POD" -n $ISTIO_EGRESS_NAMESPACE -c curl -- curl -sSL -o /dev/null -D - https://edition.cnn.com/politics

Odpowiedź HTTP/2 200 powinna być widoczna.

  1. Uprzątnij zasoby
kubectl delete serviceentry cnn -n $ISTIO_EGRESS_NAMESPACE
kubectl delete gateway istio-egressgateway -n $ISTIO_EGRESS_NAMESPACE
kubectl delete virtualservice direct-cnn-through-egress-gateway -n $ISTIO_EGRESS_NAMESPACE
kubectl delete destinationrule egressgateway-for-cnn -n $ISTIO_EGRESS_NAMESPACE

Konfigurowanie bramy wyjściowej Istio do inicjowania połączeń TLS

  1. Utwórz element ServiceEntry dla elementu :edition.cnn.com
kubectl apply -n $ISTIO_EGRESS_NAMESPACE -f - <<EOF
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
  name: cnn
spec:
  hosts:
  - edition.cnn.com
  ports:
  - number: 80
    name: http
    protocol: HTTP
  - number: 443
    name: https
    protocol: HTTPS
  resolution: DNS
EOF
  1. Utwórz Gateway, VirtualService i DestinationRule, aby przekierować ruch HTTP z aplikacji curl do edition.cnn.com przez bramę wychodzącą oraz wykonać inicjację TLS w tej bramie. Należy odpowiednio ustawić selektor bramy i FQDN usługi zgodnie z selektorem etykiety istio we wdrożeniu bramy ruchu wychodzącego.
kubectl apply -n $ISTIO_EGRESS_NAMESPACE -f - <<EOF
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
    istio: $EGRESS_GTW_SELECTOR
  servers:
  - port:
      number: 80
      name: https-port-for-tls-origination
      protocol: HTTPS
    hosts:
    - edition.cnn.com
    tls:
      mode: ISTIO_MUTUAL
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: egressgateway-for-cnn
spec:
  host: $ISTIO_EGRESS_NAME.$ISTIO_EGRESS_NAMESPACE.svc.cluster.local
  subsets:
  - name: cnn
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
      portLevelSettings:
      - port:
          number: 80
        tls:
          mode: ISTIO_MUTUAL
          sni: edition.cnn.com
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: direct-cnn-through-egress-gateway
spec:
  hosts:
  - edition.cnn.com
  gateways:
  - istio-egressgateway
  - mesh
  http:
  - match:
    - gateways:
      - mesh
      port: 80
    route:
    - destination:
        host: $ISTIO_EGRESS_NAME.$ISTIO_EGRESS_NAMESPACE.svc.cluster.local
        subset: cnn
        port:
          number: 80
      weight: 100
  - match:
    - gateways:
      - istio-egressgateway
      port: 80
    route:
    - destination:
        host: edition.cnn.com
        port:
          number: 443
      weight: 100
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: originate-tls-for-edition-cnn-com
spec:
  host: edition.cnn.com
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
    portLevelSettings:
    - port:
        number: 443
      tls:
        mode: SIMPLE # initiates HTTPS for connections to edition.cnn.com
EOF
  1. Spróbuj wysłać formularz curl żądania do edition.cnn.com bramy ruchu wychodzącego wykonującego pochodzenie protokołu TLS;
kubectl exec "${SOURCE_POD}" -n $ISTIO_EGRESS_NAMESPACE -c curl -- curl -sSL -o /dev/null -D - http://edition.cnn.com/politics

Powinna zostać wyświetlona 200 odpowiedź o stanie.

  1. Uprzątnij zasoby
kubectl delete serviceentry cnn -n $ISTIO_EGRESS_NAMESPACE
kubectl delete gateway istio-egressgateway -n $ISTIO_EGRESS_NAMESPACE
kubectl delete virtualservice direct-cnn-through-egress-gateway -n $ISTIO_EGRESS_NAMESPACE
kubectl delete destinationrule originate-tls-for-edition-cnn-com -n $ISTIO_EGRESS_NAMESPACE
kubectl delete destinationrule egressgateway-for-cnn -n $ISTIO_EGRESS_NAMESPACE

Wyłączanie bramy ruchu wychodzącego Istio

Uruchom polecenie az aks mesh disable-egress-gateway, aby wyłączyć bramę dla ruchu wychodzącego dodatku Istio, którą utworzyłeś.

az aks mesh disable-egress-gateway --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --istio-egressgateway-name $ISTIO_EGRESS_NAME --istio-egressgateway-namespace $ISTIO_EGRESS_NAMESPACE

Po wyłączeniu bramy ruchu wychodzącego Istio powinieneś móc usunąć StaticGatewayConfiguration, przestrzeń nazw i gateway pulę węzłów, z której korzystała ta brama, jeśli żadna inna brama ruchu wychodzącego Istio z nich nie korzysta.

Dalsze kroki

Uwaga / Notatka

Jeśli występują problemy z wdrażaniem bramy ruchu wychodzącego Istio lub konfigurowaniem routingu ruchu wychodzącego, zapoznaj się z artykułem dotyczącym rozwiązywania problemów z bramami ruchu wychodzącego dodatku Istio