カスタム Istio ゲートウェイの展開 Helm

Istio-管理アプリのトラフィックのイングレスとイグレスのゲートウェイを定義するリソースを編集して、ゲートウェイをカスタマイズする。

Istio アドオンバージョン 1.24 以降の Helm への移行に伴い、 IstioOperator カスタムリソースは使用されなくなりました。

Helm のセットアップ

カスタムゲートウェイのデプロイと管理を始める前に、 Helm 3.18.4、またはそれ以前をセットアップしてください。

  1. Helm 3.18.4 以前をインストールしてください。

    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. Istio の Helm リポジトリを追加します。

    helm repo add istio https://istio-release.storage.googleapis.com/charts
    
  3. helm repo update コマンドを実行します。

    helm repo update
    

既存のデフォルトゲートウェイの変更

アドオンは、カスタマイズ可能な istio-ingressgatewayistio-egressgateway を1つずつ配備する。 Helm チャートのゲートウェイ ConfigMaps をカスタマイズするには、コントロール・プレー ンで行うようにキーと値のペアを追加するのではなく、 value.yaml キーにある複数行の文字列を編集する。

これらの value.yaml ファイルは、 managed-istio-ingressgateway-valuesmanaged-istio-egressgateway-values ConfigMaps 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

istio-ingressgatewayistio-egressgateway value.yaml

  1. クラスターを作成します。

  2. マネージド Istio アドオンをインストールする 1.24 またはそれ以降。

    ibmcloud ks cluster addon enable istio -c $CLUSTERID --version 1.24
    
  3. クラスタの kubeconfig

    ibmcloud ks cluster config -c $CLUSTERID
    
  4. イングレスゲートウェイとイグレスゲートウェイの value.yaml コンテンツを保持する2つの Istio ゲートウェイ ConfigMaps を見つける。

    kubectl get cm -n ibm-operators
    

    出力:

    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. ゲートウェイの values.yaml をファイルに出力する。

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

    出力:

    # "_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. これらのゲートウェイを含むデータプレーンを管理することができる。 パッチの自動更新、優先ポッドのアンチアフィニティ、エッジノードの許容と優先を含むデフォルトの設定から始める。 カスタマイズは自己責任でお願いします。 コントロールプレーンの value.yaml ファイルとは異なり、 value.yaml ファイルは ConfigMaps で編集することができる。

    これらは、デフォルトのIngressコンフィギュレーションを使用して、istio/gatewayチャートによって作成されたリソースです。 イグレスも同じ命名規則である。

    • PodDisruptionBudget Service、、 は、 名前空間の で命名されている。 Deployment HorizontalPodAutoscaler istio-system istio-ingressgateway これらの名前は、 values.yamlname フィールドによって設定される。
    • ServiceAccount Role、 は、 名前空間の で命名されている。 Rolebinding istio-system istio-ingressgateway-service-account これらの名前は、 values.yamlserviceAccount.name フィールドによって設定される。
  7. まず、保存した gateway-values.yaml で変更を加えてみてください。 その後、 Helm のドライランを使用して、マニフェストの変更を確認する。

    次に例を示します。

    以下に変更例を示す。 変更点のみが表示され、 values.yaml の残りのコンテンツは変更されていない。 これらの変更例には以下が含まれる:

    • リソース名の変更

    • リソース要求/制限の調整

    • オートスケールの増加

    • ノードアフィニティの追加

      • ゾーン・アフィニティを作成するためにノード・アフィニティを使用することを 考えている場合、代わりに topologySpreadConstraints

    a. 必要に応じて values.yaml の内容を修正する。

    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. マニフェストを出力するには、 Helm を --dry-run オプションと一緒に使用します。これにより、構文を確認し、コンフィギュレーションが意図に合っていることを確認できます。

    デフォルトのゲートウェイ( istio-ingressgateway または istio-egressgateway )のいずれかをターゲットにしている場合は、このコマンドを --dry-run オプション付きで実行するだけでよい。 このコマンドを --dry-run オプションなしで実行しないでください。

    helm upgrade istio-ingressgateway istio/gateway --version 1.29.0 --install -n istio-system -f gateway-values.yaml --dry-run
    
  8. 変更に満足したら、 kubectl edit を使って、ゲートウェイの values.yaml を、 ConfigMap の中で編集する。

    a. gateway-values.yaml を開き、 values.yaml ファイルのコピーをスペース4つ分インデントする。

    b. kubectl edit コマンドを実行します。

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

    c. 前の values.yaml の行を削除する。

    d. values.yaml キーを複数行の文字列で始める。 次に例を示します。 |

    e. 4スペースインデントした values.yaml ファイルを、 values.yaml キーより下の行にコピーする。

    次に例を示します。

    data:
      values.yaml: |
        <Copy values.yaml here.>
      values.yaml.helm.result: |
        <Don't remove these previous Helm logs.>
    
  9. 約10分後、その ConfigMap の values.yaml.helm.result フィールドに更新された Helm ログがないか確認し、必要に応じてデバッグを行う。

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

    出力例:

    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. 設定オプションを表示します。

    a. 値を表示する。

    helm show values istio/gateway --version 1.29.5
    

    b. 表示される可能性のあるキーを確認してください。

        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
    

追加ゲートウェイの作成

ゲートウェイを1つ配置したデフォルトゲートウェイをカスタマイズした後、追加のゲートウェイを設定したくなるかもしれません。 Helm でリソースマニフェストを生成し、 Helm で適用するか、YAML リソースの CI/CD パイプラインで適用します。

  1. helm show values コマンドを実行します。

    helm show values "istio/gateway" --version "1.29.0"
    
  2. ゲートウェイ用に values.yaml ファイルを作成する。 次の例は、 Istio 1.24.6 で利用可能なオプションに基づく、 Istio ingressgateway のための最小限の values.yaml です。

    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
    

    あるいは、デフォルトゲートウェイの values.yaml

    kubectl get cm -n ibm-operators  managed-istio-ingressgateway-values -o json | jq -r .data.\"values.yaml\"
    
  3. Helm、リリース名とネームスペースを選択する際には、以下の条件を考慮してください。

    • Helm リリース名と名前空間は、ゲートウェイのデプロイメント名と名前空間と一致する必要があります。
    • istio-baseistiodistio-ingressgatewayistio-egressgateway は、 Istio 管理アドオンがこれらのリリース名を使用しているため、避けてください。
    • 追加ゲートウェイの別のリリース名を使用することは避けてください。
  4. ゲートウェイの YAML リソースのマニフェストを確認するために、ドライランを実行します。 Istio 1.25.4 以前の場合は、 Helm v3.18.4 を使用する必要があります。

    helm upgrade --dry-run RELEASE_NAME istio/gateway --version ISTIO_VERSION --install -n NAMESPACE -f values.yaml
    
  5. これらのリソースを以下のいずれかの方法で適用する:

    • --dry-run オプションなしで Helm upgrade コマンドを使用する。
    • YAMLリソースのマニフェストを取得し、クラスタのCI/CDユースケースに応じて、他の Istio データプレーンYAMLと同じように適用します。

カスタマイズ例

出口ゲートウェイ

イグレスゲートウェイは LoadBalancer IPを必要としないので、サービスタイプは ClusterIP

service:
  type: ClusterIP

リソースの要求と制限

フィールドが指定されていない場合は、 Istio のデフォルト値が使用される。

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

自動スケーリング

autoscaling.enabled=true が設定されている場合は、水平ポッド・オートスケーラの最小レプリカ数と最大レプリカ数を設定できます。

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 5

優雅な終了

グレースフル・ターミネーションは、ゲートウェイが終了している間、既存のコネクションを処理するための余分な時間を与える。 この機能は、 TERMINATION_DRAIN_DURATION 環境変数を指定することに取って代わる。 必要に応じて、この設定値を増やすことができる。

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

ゾーン・アフィニティー

トポロジースプレッド制約はtopologySpreadConstraints フィールドで設定できる。 ユースケースによっては、このソリューションは、以前のゾーン・アフィニ ティ・ソリューションよりも優れた代替策となり得る。

topologySpreadConstraints: []

ゾーン・アフィニティは、サービス・アノテーションとノード・アフィニティを追加することで指定できる。

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"

loadBalancerIP を指定することができます。

Service.spec.loadBalancerIP Kubernetes によってバージョン 1.24 で非推奨 となりました。 このオプションは、 Kubernetes がフィールドの削除を完了すると機能しなくなります。 クラスタ上の他の場所ですでに使用されているIPを指定した場合、サービスは外部IPを保留したままになります。

service:
  type: LoadBalancer
  loadBalancerIP: ""

Istio バージョンをピン留めする

Istio ゲートウェイには image: auto があり、ポッド作成時に期待されるサイドカー proxyv2 イメージをピックアップするようになっている。 この設定は、ポッドアノテーションでオーバーライドできます。 このオーバーライドを使用して画像タグを固定する場合、 Istio パッチとマイナーアップデートのたびにその固定を更新する責任があります。

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

ゲートウェイを無効にする

サービスを無効にするには、そのタイプを None に変更します。 ゲートウェイの展開を縮小することもできる。 Istio 1.24 と 1.25 において、 replicaCount1 を最小とする問題がある。 Istio 1.26.0 以降では、 replicaCount0 に設定できます。 ingressgateway のサービスタイプが LoadBalancer から None に変更されると、その LoadBalancer IP は最終的に放棄される。 サービスタイプが LoadBalancer に戻された場合、新しいIPが割り当てられる。

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

ゲートウェイの削除

istio-ingressgateway-public-2istio-ingressgateway-public-3、またはその他のカスタムゲートウェイを有効にしている場合は、これらのリソースを探して削除してください。

  1. ゲートウェイを探す。 ゲートウェイが Helm とともにインストールされている場合は、 helm get all RELEASE_NAME -n NAMESPACE をショートカットとして使用できます。

    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. ゲートウェイを取り外す。 ゲートウェイが Helm とともにインストールされている場合は、 helm uninstall RELEASE_NAME -n NAMESPACE をショートカットとして使用できます。

    istio-system 名前空間の istio-ingressgateway-public-2 を削除する例:

    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
    

    出力例:

    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