Distribuzione di gateway personalizzati Istio in Helm

Personalizzare i gateway modificando la risorsa che definisce i gateway di ingresso e di uscita per il traffico dell'app gestita da Istio.

Con il passaggio a Helm per la versione aggiuntiva Istio 1.24 e successive, la risorsa personalizzata IstioOperator non viene più utilizzata.

Configurazione di Helm

Prima di iniziare a distribuire e gestire i gateway personalizzati, configurare Helm 3.18.4 o precedenti.

  1. Installare Helm 3.18.4 o precedenti.

    curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
    chmod 700 get_helm.sh
    helm_version_pin="v3.18.4"
    DESIRED_VERSION="${helm_version_pin}" ./get_helm.sh
    which helm
    helm version
    rm get_helm.sh
    
  2. Aggiungere il repo Istio 's Helm.

    helm repo add istio https://istio-release.storage.googleapis.com/charts
    
  3. Eseguire il comando helm repo update.

    helm repo update
    

Modifica dei gateway predefiniti esistenti

Il componente aggiuntivo distribuisce un sito istio-ingressgateway e un sito istio-egressgateway personalizzabili. Per personalizzare il gateway ConfigMaps per i grafici Helm, invece di aggiungere una coppia chiave-valore come si fa per il piano di controllo, modificare la stringa multilinea nella chiave value.yaml.

Questi file value.yaml si trovano come stringhe multilinea nello spazio dei nomi managed-istio-ingressgateway-values e managed-istio-egressgateway-values ConfigMaps nello spazio dei nomi ibm-operators.

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
  name: managed-istio-egressgateway-values
  namespace: ibm-operators
data:
  values.yaml: |
 ...
      resources:
        requests:
          cpu: 100m
          memory: 128Mi
        limits:
          cpu: 2000m
          memory: 1024Mi

Per modificare il contenuto di istio-ingressgateway e istio-egressgateway value.yaml:

  1. Crea un cluster.

  2. Installare il componente aggiuntivo Istio gestito 1.24 o successivo.

    ibmcloud ks cluster addon enable istio -c $CLUSTERID --version 1.24
    
  3. Ottenere il sito kubeconfig del cluster.

    ibmcloud ks cluster config -c $CLUSTERID
    
  4. Individuare i due gateway Istio ConfigMaps che contengono il contenuto di value.yaml per i gateway di ingresso e di uscita.

    kubectl get cm -n ibm-operators
    

    Output:

    NAME                                        DATA   AGE
    istio-ca-root-cert                          1      12m
    kube-root-ca.crt                            1      24h
    managed-istio-base-control-plane-values     2      13m
    managed-istio-custom                        1      13m
    managed-istio-egressgateway-values          2      13m
    managed-istio-ingressgateway-values         2      13m
    managed-istio-istiod-control-plane-values   2      13m
    
  5. Invia il sito values.yaml dei gateway a un file.

    kubectl get cm -n ibm-operators  managed-istio-ingressgateway-values -o json | jq -r .data.\"values.yaml\" > gateway-values.yaml; open gateway-values.yaml
    

    Output:

    # "_internal_defaults_do_not_set" is a workaround for Helm limitations. Users should NOT set "._internal_defaults_do_not_set" explicitly, but rather directly set the fields internally.
    # For instance, instead of `--set _internal_defaults_do_not_set.foo=bar``, just set `--set foo=bar`.
    _internal_defaults_do_not_set:
    # Name allows overriding the release name. Generally this should not be set
    name: ""
    serviceAccount:
      # If set, a service account will be created. Otherwise, the default is used
      create: true
      # Annotations to add to the service account
      annotations: {}
      # The name of the service account to use.
      # If not set, the release name is used
      name: "istio-ingressgateway-service-account"
    podAnnotations:
        prometheus.io/port: "15020"
        prometheus.io/scrape: "true"
        prometheus.io/path: "/stats/prometheus"
        inject.istio.io/templates: "gateway"
        sidecar.istio.io/inject: "true"
    service:
        # Egress gateways do not need an external LoadBalancer IP so they set "service.type: ClusterIP".
        # Type of service. Set to "None" to disable the service entirely
        type: LoadBalancer
        ports:
        - name: http2
        port: 80
        protocol: TCP
        targetPort: 8080
        - name: https
        port: 443
        protocol: TCP
        targetPort: 8443
        loadBalancerIP: ""
        loadBalancerSourceRanges: []
        externalTrafficPolicy: ""
        externalIPs: []
        ipFamilyPolicy: ""
        ipFamilies: []
        ## Whether to automatically allocate NodePorts (only for LoadBalancers).
        # allocateLoadBalancerNodePorts: false
    resources:
        requests:
        cpu: 100m
        memory: 128Mi
        limits:
        cpu: 2000m
        memory: 1024Mi
    autoscaling:
        enabled: true
        minReplicas: 2
        maxReplicas: 5
        targetCPUUtilizationPercentage: 80
        targetMemoryUtilizationPercentage: {}
        autoscaleBehavior: {}
    tolerations:
    - key: dedicated
        value: edge
    topologySpreadConstraints: []
    affinity:
        podAntiAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
        - podAffinityTerm:
            labelSelector:
                matchExpressions:
                - key: app
                operator: In
                values:
                - istio-ingressgateway
            topologyKey: kubernetes.io/hostname
            weight: 100
        nodeAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
        - preference:
            matchExpressions:
            - key: dedicated
                operator: In
                values:
                - edge
            weight: 100
    
  6. È possibile gestire il piano dati, compresi i gateway. Iniziare con la configurazione predefinita, che include gli aggiornamenti automatici delle patch, l'anti-affinità dei pod preferiti e la tolleranza e la preferenza per i nodi edge. L'utente è responsabile delle personalizzazioni effettuate. A differenza dei file value.yaml del piano di controllo, è possibile modificare i file value.yaml in questi ConfigMaps.

    Queste sono le risorse create dal grafico istio/gateway utilizzando la configurazione di Ingress predefinita. Le stesse convenzioni di denominazione valgono per l'uscita.

    • PodDisruptionBudget, Service, Deployment e HorizontalPodAutoscaler sono denominati in istio-ingressgateway nello spazio dei nomi istio-system. Questi nomi sono impostati dai campi name del file values.yaml.
    • ServiceAccount, Role e Rolebinding sono denominati in istio-ingressgateway-service-account nello spazio dei nomi istio-system. Questi nomi sono impostati dal campo serviceAccount.name del file values.yaml.
  7. Testate le modifiche che volete apportare eseguendole prima nel sito gateway-values.yaml salvato. Quindi utilizzare un'esecuzione a secco di Helm per vedere i cambiamenti del manifesto.

    Esempio:

    Di seguito sono riportati alcuni esempi di modifiche. Vengono mostrate solo le modifiche; il resto del contenuto di values.yaml rimane invariato. Questi esempi di modifiche includono:

    • Modifica dei nomi delle risorse

    • Regolazione delle richieste/limiti di risorse

    • Aumentare l'autoscaling

    • Aggiunta di un'affinità di nodo

      • Se si sta pensando di usare l'affinità dei nodi per creare le affinità di zona, si potrebbe anche usare topologySpreadConstraints.

    a. Rivedere il contenuto di values.yaml se necessario.

    name: "custom-gateway"
    serviceAccount:
        name: "custom-ingressgateway-service-account"
    resources:
        requests:
            cpu: 100m
            memory: 128Mi
        limits:
            cpu: 2500m
            memory: 1024Mi
    autoscaling:
        enabled: true
        minReplicas: 3
        maxReplicas: 7
        targetCPUUtilizationPercentage: 80
        targetMemoryUtilizationPercentage: {}
        autoscaleBehavior: {}            
    affinity:
        nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
            - key: ibm-cloud.kubernetes.io/zone
                operator: In
                values:
                - "dal10"
    

    b. Usare Helm con l'opzione --dry-run per produrre un manifesto, in modo da poter confermare la sintassi e che la configurazione corrisponda alle proprie intenzioni.

    Quando si punta a uno dei gateway predefiniti, che sono istio-ingressgateway o istio-egressgateway, eseguire questo comando solo con l'opzione --dry-run. Non eseguire questo comando senza l'opzione --dry-run.

    helm upgrade istio-ingressgateway istio/gateway --version 1.29.0 --install -n istio-system -f gateway-values.yaml --dry-run
    
  8. Se si è soddisfatti delle modifiche, utilizzare kubectl edit per modificare values.yaml del gateway all'interno di ConfigMap da cui proviene.

    a. Aprite gateway-values.yaml e rientrate la copia del file values.yaml di 4 spazi.

    b. Eseguire il comando kubectl edit.

    kubectl edit cm -n ibm-operators managed-istio-ingressgateway-values
    

    c. Cancellare le righe del precedente values.yaml.

    d. Iniziare il tasto values.yaml con una stringa multilinea. Esempio: |

    e. Copiate il vostro file values.yaml, rientrato di 4 spazi, nelle righe sotto il tasto values.yaml.

    Esempio:

    data:
      values.yaml: |
        <Copy values.yaml here.>
      values.yaml.helm.result: |
        <Don't remove these previous Helm logs.>
    
  9. Dopo circa 10 minuti, verificare la presenza di un log aggiornato di Helm nel campo values.yaml.helm.result di ConfigMap ed eseguire il debug se necessario.

    kubectl get cm -n ibm-operators managed-istio-ingressgateway-values -o json | jq -r .data.\"values.yaml.helm.result\"
    

    Output di esempio:

    GMT HELM_SUCCESS: Release "istio-ingressgateway" does not exist. Installing it now.
    NAME: istio-ingressgateway
    LAST DEPLOYED: Fri Sep 5 16:46:30 2025
    NAMESPACE: istio-system
    STATUS: deployed REVISION: 1
    TEST SUITE: None
    NOTES: "istio-ingressgateway" successfully installed!
    To learn more about the release, try:
    $ helm status istio-ingressgateway -n istio-system
    $ helm get all istio-ingressgateway -n istio-system
    Next steps:
    * Deploy an HTTP Gateway: https://istio.io/latest/docs/tasks/traffic-management/ingress/ingress-control/
    * Deploy an HTTPS Gateway: https://istio.io/latest/docs/tasks/traffic-management/ingress/secure-ingress/
    
  10. Visualizzare le opzioni di configurazione.

    a. Mostrare i valori.

    helm show values istio/gateway --version 1.29.5
    

    b. Esaminare le possibili chiavi che potrebbero essere visualizzate.

        name: # The gateway deployment's and service's name
        serviceAccount:
          name: # The service account, role, and rolebinding name
        resources: # Resource requests and limits
        autoscaling: # Min and Max gateway pods
        tolerations: # Tolerate your taints
        topologySpreadConstraints: # An alternative to node affinities
        affinity: # Where you can specify node affinities
    

Creazione di gateway aggiuntivi

Dopo aver personalizzato il gateway predefinito che ha una distribuzione di gateway, si potrebbe voler configurare altri gateway. Generare il manifest delle risorse con Helm, quindi applicarlo con Helm o con una pipeline CI/CD per le risorse YAML.

  1. Eseguire il comando helm show values.

    helm show values "istio/gateway" --version "1.29.0"
    
  2. Creare un file values.yaml per il gateway. Il seguente esempio è un values.yaml minimalista per un Istio ingressgateway basato sulle opzioni disponibili in Istio 1.24.6.

    rbac:
    # If enabled, roles will be created to enable accessing certificates from Gateways. This is not needed
    # when using http://gateway-api.org/.
      enabled: true
    serviceAccount:
    # If set, a service account will be created. Otherwise, the default is used
      create: true
    # Define the security context for the pod.
    # If unset, this will be automatically set to the minimum privileges required to bind to port 80 and 443.
    # On Kubernetes 1.22+, this only requires the `net.ipv4.ip_unprivileged_port_start` sysctl.
    securityContext:
      runAsGroup: 1337
      runAsNonRoot: true
      runAsUser: 1337
      seccompProfile:
        type: RuntimeDefault
    service:
    # Egress gateways do not need an external LoadBalancer IP so they set "service.type: ClusterIP".
    # Type of service. Set to "None" to disable the service entirely
      type: LoadBalancer
      ports:
      - name: http2
        port: 80
        protocol: TCP
        targetPort: 8080
      - name: https
        port: 443
        protocol: TCP
        targetPort: 8443
    autoscaling:
      enabled: true
      minReplicas: 2
      maxReplicas: 5
    # Deployment Update strategy
    strategy:
      rollingUpdate:
        maxSurge: 100%
        maxUnavailable: 25%
    tolerations:
    - key: dedicated
      value: edge
    affinity:
      podAntiAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
        - podAffinityTerm:
            labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - istio-ingressgateway
            topologyKey: kubernetes.io/hostname
        weight: 100
      nodeAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
        - preference:
            matchExpressions:
            - key: dedicated
              operator: In
              values:
              - edge
        weight: 100
    podDisruptionBudget:
      minAvailable: 1
    # Sets the per-pod terminationGracePeriodSeconds setting.
    terminationGracePeriodSeconds: 30
    # Configure this to a higher priority class in order to make sure that your Istio gateway pods
    # will not be killed because of low priority class.
    # Refer to https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass
    # for more detail.
    priorityClassName: ibm-app-cluster-critical
    

    In alternativa, è possibile utilizzare il sito values.yaml del gateway predefinito come punto di partenza.

    kubectl get cm -n ibm-operators  managed-istio-ingressgateway-values -o json | jq -r .data.\"values.yaml\"
    
  3. Quando si sceglie il nome e lo spazio dei nomi della release Helm, si devono considerare le seguenti condizioni.

    • Il nome e lo spazio dei nomi della release Helm devono corrispondere al nome e allo spazio dei nomi della distribuzione del gateway.
    • Evitare istio-base, istiod, istio-ingressgateway e istio-egressgateway perché il componente aggiuntivo gestito Istio utilizza questi nomi di release.
    • Evitare di usare il nome della release di un altro dei gateway aggiuntivi.
  4. Eseguire una prova generale per vedere il manifest delle risorse YAML per il gateway. Per Istio 1.25.4 e precedenti, è necessario utilizzare Helm v3.18.4.

    helm upgrade --dry-run RELEASE_NAME istio/gateway --version ISTIO_VERSION --install -n NAMESPACE -f values.yaml
    
  5. Applicare queste risorse con uno dei seguenti metodi:

    • Utilizzare il comando Helm upgrade senza l'opzione --dry-run.
    • Prendere il manifest delle risorse YAML e applicarlo come si farebbe con altri YAML del piano dati Istio, a seconda del caso d'uso CI/CD del cluster.

Esempi di personalizzazione

Gateway di uscita

I gateway in uscita devono avere un tipo di servizio ClusterIP, poiché non hanno bisogno di un IP LoadBalancer.

service:
  type: ClusterIP

Richieste e limiti di risorse

Se un campo non viene specificato, vengono utilizzati i valori predefiniti di Istio.

resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 2000m
    memory: 1024Mi

Ridimensionamento automatico

Se è impostato autoscaling.enabled=true, è possibile impostare le repliche minime e massime per l'autoscaler pod orizzontale.

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 5

Terminazione di grazia

La terminazione di grazia offre al gateway un tempo supplementare per gestire le connessioni esistenti durante la terminazione. Questa funzione sostituisce la specificazione della variabile d'ambiente TERMINATION_DRAIN_DURATION. Se necessario, è possibile aumentare il valore di questa impostazione.

# Sets the per-pod terminationGracePeriodSeconds setting.
terminationGracePeriodSeconds: 30

Affinità zona

I vincoli di diffusione della topologia possono essere impostati con il campo topologySpreadConstraints. A seconda del caso d'uso, questa soluzione può essere un'alternativa migliore alla precedente soluzione di affinità di zona.

topologySpreadConstraints: []

Le affinità di zona possono essere specificate aggiungendo un'annotazione di servizio e un'affinità di nodo.

service:
  annotations:
    service.kubernetes.io/ibm-load-balancer-cloud-provider-zone: "dal10"
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: ibm-cloud.kubernetes.io/zone
          operator: In
          values:
          - "dal10"

È possibile specificare l' loadBalancerIP.

Service.spec.loadBalancerIP è stato deprecato da Kubernetes nella versione 1.24. Questa opzione smette di funzionare quando Kubernetes termina la rimozione del campo. Se si specifica un IP che è già in uso altrove nel cluster, il servizio avrà il suo IP esterno in sospeso.

service:
  type: LoadBalancer
  loadBalancerIP: ""

Appuntare la versione di Istio

I gateway Istio hanno image: auto in modo da prelevare l'immagine sidecar proxyv2 prevista alla creazione del pod. Questa impostazione può essere sovrascritta da un'annotazione pod. Se si usa questo override per appuntare il tag immagine, si è responsabili dell'aggiornamento di tale appuntato a ogni patch di Istio e aggiornamento minore.

podAnnotations:
  "sidecar.istio.io/proxyImage": "icr.io/ext/istio/proxyv2:1.24.0"

Disabilitazione del gateway

È possibile disattivare il servizio cambiando il suo tipo in None. È anche possibile ridurre la distribuzione del gateway. In Istio 1.24 e 1.25, c'è un problema in cui replicaCount ha un minimo di 1. In Istio 1.26.0 e successivi, è possibile impostare replicaCount su 0. Quando il tipo di servizio di ingressgateway viene modificato da LoadBalancer a None, il suo IP LoadBalancer viene infine abbandonato. Se il tipo di servizio è stato modificato nuovamente in LoadBalancer, viene assegnato un nuovo IP.

replicaCount: 0
service:
  type: None
autoscaling:
  enabled: false

Rimozione delle distribuzioni di gateway

Se sono stati attivati istio-ingressgateway-public-2, istio-ingressgateway-public-3 o qualsiasi altro gateway personalizzato che si desidera rimuovere, individuare ed eliminare queste risorse.

  1. Individuare i gateway. Se il gateway è stato installato con Helm, è possibile utilizzare helm get all RELEASE_NAME -n NAMESPACE come collegamento.

    kubectl get PodDisruptionBudget -n NAMESPACE GATEWAY_NAME --ignore-not-found
    kubectl get Service -n NAMESPACE GATEWAY_NAME --ignore-not-found
    kubectl get Deployment -n NAMESPACE GATEWAY_NAME --ignore-not-found
    kubectl get HorizontalPodAutoscaler -n NAMESPACE GATEWAY_NAME --ignore-not-found
    kubectl get ServiceAccount -n NAMESPACE --ignore-not-found | grep GATEWAY_NAME
    kubectl get Role -n NAMESPACE --ignore-not-found | grep GATEWAY_NAME
    kubectl get RoleBinding -n NAMESPACE --ignore-not-found | grep GATEWAY_NAME
    
  2. Rimuovere i gateway. Se il gateway è stato installato con Helm, è possibile utilizzare helm uninstall RELEASE_NAME -n NAMESPACE come collegamento.

    Esempio di rimozione di istio-ingressgateway-public-2 nello spazio dei nomi istio-system:

    kubectl delete PodDisruptionBudget -n istio-system istio-ingressgateway-public-2 --ignore-not-found
    kubectl delete Service -n istio-system istio-ingressgateway-public-2 --ignore-not-found
    kubectl delete Deployment -n istio-system istio-ingressgateway-public-2 --ignore-not-found
    kubectl delete HorizontalPodAutoscaler -n istio-system istio-ingressgateway-public-2 --ignore-not-found
    kubectl delete ServiceAccount -n istio-system istio-ingressgateway-public-2-service-account --ignore-not-found
    kubectl delete Role -n istio-system istio-ingressgateway-public-2-sds --ignore-not-found
    kubectl delete RoleBinding -n istio-system istio-ingressgateway-public-2-sds --ignore-not-found
    

    Output di esempio:

    NAME                            MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
    istio-ingressgateway-public-2   N/A             N/A               0                     2m33s
    NAME                            TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
    istio-ingressgateway-public-2   LoadBalancer   172.21.227.3   169.46.62.156   80:32705/TCP,443:31154/TCP   2m32s
    NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
    istio-ingressgateway-public-2   2/2     2            2           2m33s
    NAME                            REFERENCE                                  TARGETS              MINPODS   MAXPODS   REPLICAS   AGE
    istio-ingressgateway-public-2   Deployment/istio-ingressgateway-public-2   cpu: <unknown>/80%   2         5         2          2m34s
    istio-ingressgateway-public-2-service-account   0         2m34s
    istio-ingressgateway-public-2-sds   2025-09-09T17:20:46Z
    istio-ingressgateway-public-2-sds   Role/istio-ingressgateway-public-2-sds   2m34s