2.14. Service Mesh でのトラフィックの管理
Red Hat OpenShift Service Mesh を使用すると、サービス間のトラフィックと API 呼び出しの流れを制御できます。Service Mesh 内の一部のサービスはメッシュ内で通信する必要があり、その他のサービスは非表示にする必要がある場合があります。トラフィックを管理して、特定のバックエンドサービスを非表示にし、サービスを公開し、テストまたはバージョン管理デプロイメントを作成し、または一連のサービスのセキュリティーの層を追加できます。
2.14.1. ゲートウェイの使用 リンクのコピーリンクがクリップボードにコピーされました!
ゲートウェイを使用してメッシュの受信トラフィックおよび送信トラフィックを管理することで、メッシュに入るか、メッシュを出るトラフィックを指定できます。ゲートウェイ設定は、サービスワークロードとともに実行するサイドカー Envoy プロキシーではなく、メッシュのエッジで実行するスタンドアロン Envoy プロキシーに適用されます。
Kubernetes Ingress API など、システムに入るトラフィックを制御する他のメカニズムとは異なり、Red Hat OpenShift Service Mesh ゲートウェイは、トラフィックルーティングの機能と柔軟性を最大限に活用します。
Red Hat OpenShift Service Mesh のゲートウェイリソースでは、ポートなどの 4 - 6 層の負荷分散プロパティーを使用して、Red Hat OpenShift Service Mesh の TLS 設定を公開および設定できます。この API リソースにアプリケーション層トラフィックルーティング (L7) を追加する代わりに、通常の Red Hat OpenShift Service Mesh 仮想サービスをゲートウェイにバインドすることで、Service Mesh 内の他のデータプレーントラフィックと同様にゲートウェイトラフィックを管理できます。
ゲートウェイは ingress トラフィックの管理に主に使用されますが、egress ゲートウェイを設定することもできます。egress ゲートウェイを使用すると、メッシュからのトラフィック専用の終了ノードを設定できます。これにより、Service Mesh にセキュリティー制御を追加することで、外部ネットワークにアクセスできるサービスを制限できます。また、ゲートウェイを使用して完全に内部のプロキシーを設定することもできます。
ゲートウェイの例
ゲートウェイリソースは、着信または発信 HTTP/TCP 接続を受信するメッシュのエッジで動作するロードバランサーを表します。この仕様には、公開する必要のあるポートのセット、使用するプロトコルのタイプ、ロードバランサー用の SNI 設定などが記述されています。
以下の例は、外部 HTTPS Ingress トラフィックのゲートウェイ設定を示しています。
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: ext-host-gwy
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- ext-host.example.com
tls:
mode: SIMPLE
serverCertificate: /tmp/tls.crt
privateKey: /tmp/tls.key
このゲートウェイ設定により、ポート 443 での ext-host.example.com からメッシュへの HTTPS トラフィックが可能になりますが、トラフィックのルーティングは指定されません。
ルーティングを指定し、ゲートウェイが意図される通りに機能するには、ゲートウェイを仮想サービスにバインドする必要もあります。これは、以下の例のように、仮想サービスのゲートウェイフィールドを使用して実行します。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: virtual-svc
spec:
hosts:
- ext-host.example.com
gateways:
- ext-host-gwy
次に、仮想サービスを外部トラフィックのルーティングルールを使用して設定できます。
2.14.1.1. ゲートウェイインジェクションの有効化 リンクのコピーリンクがクリップボードにコピーされました!
ゲートウェイ設定は、サービスワークロードと並行して実行されるサイドカー Envoy プロキシーではなく、メッシュのエッジで実行されるスタンドアロン Envoy プロキシーに適用されます。ゲートウェイは Envoy プロキシーであるため、サイドカーを注入する方法と同様に、ゲートウェイを自動的に注入するように Service Mesh を設定できます。
ゲートウェイの自動注入を使用すると、ServiceMeshControlPlane リソースとは別にゲートウェイをデプロイおよび管理し、ユーザーアプリケーションでゲートウェイを管理できます。ゲートウェイのデプロイに自動注入を使用すると、開発者はゲートウェイのデプロイを完全に制御できると同時に、操作を簡素化できます。新しいアップグレードが利用可能になった場合、または設定が変更された場合は、ゲートウェイ Pod を再起動して更新します。そうすることで、ゲートウェイデプロイメントの操作エクスペリエンスが、サイドカーの操作と同じになります。
ServiceMeshControlPlane namespace (たとえば、istio-system namespace) では、操作はデフォルトで無効になっています。セキュリティーのベストプラクティスとして、コントロールプレーンとは異なる namespace にゲートウェイをデプロイします。
2.14.1.2. 自動ゲートウェイインジェクションのデプロイ リンクのコピーリンクがクリップボードにコピーされました!
ゲートウェイをデプロイする場合は、インジェクションのラベルまたはアノテーションをゲートウェイ deployment オブジェクトに追加して、インジェクションをオプトインする必要があります。次の例では、ゲートウェイをデプロイします。
前提条件
-
namespace は、
ServiceMeshMemberRollで定義するか、ServiceMeshMemberリソースを作成して、メッシュのメンバーにする必要があります。
手順
Istio Ingress ゲートウェイに一意のラベルを設定します。この設定は、ゲートウェイがワークロードを選択できるようにするために必要です。この例では、ゲートウェイの名前として
ingressgatewayを使用しています。apiVersion: v1 kind: Service metadata: name: istio-ingressgateway namespace: istio-ingress spec: type: ClusterIP selector: istio: ingressgateway ports: - name: http2 port: 80 targetPort: 8080 - name: https port: 443 targetPort: 8443 --- apiVersion: apps/v1 kind: Deployment metadata: name: istio-ingressgateway namespace: istio-ingress spec: selector: matchLabels: istio: ingressgateway template: metadata: annotations: inject.istio.io/templates: gateway labels: istio: ingressgateway sidecar.istio.io/inject: "true"1 spec: containers: - name: istio-proxy image: auto2 TLS の認証情報の読み取りを許可するロールを設定します。
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: istio-ingressgateway-sds namespace: istio-ingress rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: istio-ingressgateway-sds namespace: istio-ingress roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: istio-ingressgateway-sds subjects: - kind: ServiceAccount name: defaultspec.security.manageNetworkPolicyがtrueに設定されている場合は常に必要となる、クラスターの外部からの新しいゲートウェイへのアクセスを許可します。apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: gatewayingress namespace: istio-ingress spec: podSelector: matchLabels: istio: ingressgateway ingress: - {} policyTypes: - Ingressイングレストラフィックが増加すると、Pod を自動的にスケーリングします。この例では、最小レプリカ数を
2に、最大レプリカ数を5に設定します。また、使用率が 80% に達すると、別のレプリカが作成されます。apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: labels: istio: ingressgateway release: istio name: ingressgatewayhpa namespace: istio-ingress spec: maxReplicas: 5 metrics: - resource: name: cpu target: averageUtilization: 80 type: Utilization type: Resource minReplicas: 2 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: istio-ingressgatewayノードで実行する必要がある Pod の最小数を指定します。この例では、Pod が新しいノードで再起動した場合に、1 つのレプリカが実行していることを確認します。
apiVersion: policy/v1 kind: PodDisruptionBudget metadata: labels: istio: ingressgateway release: istio name: ingressgatewaypdb namespace: istio-ingress spec: minAvailable: 1 selector: matchLabels: istio: ingressgateway
2.14.1.3. Ingress トラフィックの管理 リンクのコピーリンクがクリップボードにコピーされました!
Red Hat OpenShift Service Mesh では、Ingress Gateway により、クラスターに入るトラフィックに、監視、セキュリティー、ルートルールなどの機能を適用できます。Service Mesh ゲートウェイを使用して Service Mesh 外のサービスを公開します。
2.14.1.3.1. Ingress IP およびポートの判別 リンクのコピーリンクがクリップボードにコピーされました!
Ingress 設定は、環境が外部ロードバランサーをサポートするかどうかによって異なります。外部ロードバランサーはクラスターの Ingress IP およびポートに設定されます。クラスターの IP およびポートが外部ロードバランサーに設定されているかどうかを判別するには、以下のコマンドを実行します。この例では、istio-system が Service Mesh コントロールプレーンプロジェクトの名前となります。
$ oc get svc istio-ingressgateway -n istio-system
このコマンドは、namespace のそれぞれの項目の NAME、TYPE、CLUSTER-IP、EXTERNAL-IP、PORT(S)、および AGE を返します。
EXTERNAL-IP 値が設定されている場合、環境には Ingress ゲートウェイに使用できる外部ロードバランサーがあります。
EXTERNAL-IP の値が <none> または永続的に <pending> の場合、環境は Ingress ゲートウェイの外部ロードバランサーを提供しません。
2.14.1.3.1.1. ロードバランサーを使用した Ingress ポートの判別 リンクのコピーリンクがクリップボードにコピーされました!
お使いの環境に外部ロードバランサーがある場合は、以下の手順に従います。
手順
以下のコマンドを実行して Ingress IP およびポートを設定します。このコマンドは、ターミナルに変数を設定します。
$ export INGRESS_HOST=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')以下のコマンドを実行して Ingress ポートを設定します。
$ export INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')以下のコマンドを実行してセキュアな Ingress ポートを設定します。
$ export SECURE_INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')以下のコマンドを実行して TCP Ingress ポートを設定します。
$ export TCP_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].port}')
一部の環境では、ロードバランサーは IP アドレスの代わりにホスト名を使用して公開される場合があります。この場合、Ingress ゲートウェイの EXTERNAL-IP 値は IP アドレスではありません。これはホスト名であり、直前のコマンドは INGRESS_HOST 環境変数の設定に失敗します。
失敗した場合は、以下のコマンドを使用して INGRESS_HOST 値を修正します。
$ export INGRESS_HOST=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
2.14.1.3.1.2. ロードバランサーのない Ingress ポートの判別 リンクのコピーリンクがクリップボードにコピーされました!
お使いの環境に外部ロードバランサーがない場合は、Ingress ポートを判別し、代わりにノードポートを使用します。
手順
Ingress ポートを設定します。
$ export INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')以下のコマンドを実行してセキュアな Ingress ポートを設定します。
$ export SECURE_INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')以下のコマンドを実行して TCP Ingress ポートを設定します。
$ export TCP_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].nodePort}')
2.14.1.4. Ingress ゲートウェイの設定 リンクのコピーリンクがクリップボードにコピーされました!
Ingress ゲートウェイは、受信 HTTP/TCP 接続を受信するメッシュのエッジで稼働するロードバランサーです。このゲートウェイは、公開されるポートおよびプロトコルを設定しますが、これにはトラフィックルーティングの設定は含まれません。Ingress トラフィックに対するトラフィックルーティングは、内部サービス要求の場合と同様に、ルーティングルールで設定されます。
以下の手順では、ゲートウェイを作成し、/productpage と /login のパスの外部トラフィックに、Bookinfo サンプルアプリケーションのサービスを公開するように、VirtualService を設定します。
手順
トラフィックを受け入れるゲートウェイを作成します。
YAML ファイルを作成し、以下の YAML をこれにコピーします。
ゲートウェイの例 (gateway.yaml)
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: bookinfo-gateway spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*"YAML ファイルを適用します。
$ oc apply -f gateway.yaml
VirtualServiceオブジェクトを作成し、ホストヘッダーを再作成します。YAML ファイルを作成し、以下の YAML をこれにコピーします。
仮想サービスの例
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: bookinfo spec: hosts: - "*" gateways: - bookinfo-gateway http: - match: - uri: exact: /productpage - uri: prefix: /static - uri: exact: /login - uri: exact: /logout - uri: prefix: /api/v1/products route: - destination: host: productpage port: number: 9080YAML ファイルを適用します。
$ oc apply -f vs.yaml
ゲートウェイと VirtualService が正しく設定されていることを確認してください。
ゲートウェイ URL を設定します。
export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath='{.spec.host}')ポート番号を設定します。この例では、
istio-systemが Service Mesh コントロールプレーンプロジェクトの名前となります。export TARGET_PORT=$(oc -n istio-system get route istio-ingressgateway -o jsonpath='{.spec.port.targetPort}')明示的に公開されているページをテストします。
curl -s -I "$GATEWAY_URL/productpage"想定される結果は
200です。