Red Hat Training

A Red Hat training course is available for OpenShift Container Platform

第5章 Networking

5.1. Networking

5.1.1. 概要

Kubernetes は、確実に Pod 間がネットワークで接続されるようにし、内部ネットワークから IP アドレスを各 Pod に割り当てます。こうすることで、Pod 内の全コンテナーが同じホスト上にいるかように動作します。各 Pod に IP アドレスを割り当てると、ポートの割り当て、ネットワーク、名前の指定、サービス検出、負荷分散、アプリケーション設定、移行などの点で、Pod を物理ホストや仮想マシンのように扱うことができます。

Pod 間のリンクを作成する必要はないので、この IP アドレスを使用して Pod 間で直接相互に通信することは推奨されません。代わりに、「サービス」を作成して、そのサービスと対話することを推奨します。

5.1.2. OpenShift Container Platform DNS

フロントエンドサービスやバックエンドサービスなど、複数の「サービス」を実行して複数の Pod で使用している場合には、フロントエンド Pod がバックエンドサービスと通信できるように、ユーザー名、サービス IP などの環境変数を作成します。サービスが削除され、再作成された場合には、新規の IP アドレスがサービスに割り当てられるので、サービス IP の環境変数の更新値を取得するには、フロントエンド Pod を再作成する必要があります。さらに、バックエンドサービスは、フロントエンド Pod を作成する前に作成し、サービス IP が正しく生成され、フロントエンド Pod に環境変数として提供できるようにする必要があります。

このような理由から、サービスの DNS やサービスの IP/ポートがサービスに到達できるように、OpenShift Container Platform には DNS が含まれています。OpenShift Container Platform は、サービスの DNS クエリーに応答するマスターで「SkyDNS」を実行することで、スプリット DNS をサポートします。マスターは、デフォルトで、ポート 53 をリッスンします。

ノードが起動すると、以下のメッセージで、Kubelet が正しくマスターに解決されていることが分かります。

0308 19:51:03.118430    4484 node.go:197] Started Kubelet for node
openshiftdev.local, server at 0.0.0.0:10250
I0308 19:51:03.118459    4484 node.go:199]   Kubelet is setting 10.0.2.15 as a
DNS nameserver for domain "local"

2 番目のメッセージが表示されない場合は、Kuernetes サービスが利用できない可能性があります。

ノードホストで、各コンテナーのネームサーバーのフロントにマスター名が追加され、コンテナーの検索ドメインはデフォルトでは、.<pod_namespace>.cluster.local になります。コンテナーは、ノード上の他のネームサーバーよりも先にネームサーバーのクエリーをマスターに転送します。これは、Docker 形式のコンテナーではデフォルトの動作です。マスターは、以下の形式の .cluster.local ドメインでクエリーに対応します

表5.1 DNS 名の例

オブジェクトタイプ

デフォルト

<pod_namespace>.cluster.local

Services

<service>.<pod_namespace>.svc.cluster.local

エンドポイント

<name>.<namespace>.endpoints.cluster.local

これにより、新しいサービスを取得するためにフロントエンドの pod を再起動し、サービスに対して新しい IP を作成せずに済みます。また、pod がサービスの DNS を使用するので、環境変数を使用する必要がなくなります。さらに、DNS は変更しないので、設定ファイルで db.local としてデータベースサービスを参照できます。また、検索はサービス IP に対して解決するため、ワイルドカードの検索もサポートされます。さらにサービス名 (つまり DNS) が事前に確立しているので、フロントエンド Pod の前にバックエンドサービスを作成する必要がなくなります。

この DNS 構造では、ポータル IP はサービスに割り当てられず、kube-proxy は負荷分散しないまたはエンドポイントのルーティングを提供するヘッドレスサービスに対応しています。サービス DNS は依然として使用でき、サービスの Pod 毎に 1 つずつある複数のレコードに対応し、クライアントによる Pod 間のラウンドロビンを可能にします。

5.2. OpenShift SDN

5.2.1. 概要

OpenShift Container Platform は、Software Defined Networking (SDN) アプローチを使用して、クラスターのネットワークを統合し、OpenShift Container Platform クラスターの Pod 間の通信を可能にします。OpenShift SDN により、このような Pod ネットワークが確立され、メンテナンスされます。OpenShift SDN は Open vSwitch (OVS) を使用してオーバーレイネットワークを設定します。

OpenShift SDN では以下のように、Pod ネットワークを構成するための SDN プラグインを 3 つ提供します。

  • ovs-subnet プラグインはオリジナルのプラグインで、Pod が他の Pod やサービスすべてと通信できる「フラットな」 Pod ネットワークを提供します。
  • ovs-multitenant プラグインは、pod とサービスをプロジェクトレベルと分離します。プロジェクト毎に、一意の Virtual Network ID (VNID) を受け取り、プロジェクトに割り当てられた Pod からのトラフィックを特定します。別のプロジェクトからの Pod は、別のプロジェクトの Pod やサービスからパケットの送信や受信ができません。

    ただし、VNID 0 を受け取るプロジェクトは、他の Pod すべてとの間で通信できるという面で、追加の特権があります。OpenShift Container Platform クラスターでは、default プロジェクトに VNID 0 が割り当てられています。これにより、ロードバランサーなど、特定のサービスがクラスター内の他の全 Pod との間でスムーズに通信できるようにします。

  • ovs-networkpolicy プラグインでは、プロジェクト管理者が NetworkPolicy オブジェクトを使用して分離ポリシーを設定できます。
注記

マスターおよびノードでの SDN の設定に関する情報は、「SDN の設定」を参照してください。

5.2.2. マスター上の設計

OpenShift Container Platform master では、OpenShift SDN が、etcd に保存されている、ノードのレジストリーを管理します。システム管理者がノードを登録すると、OpenShift SDN がクラスターネットワークから未使用のサブネットを割り当てて、レジストリーのこのサブネットを保存します。ノードが削除されると、OpenShift SDN はレジストリーからサブネットを削除し、このサブネットを割り当て可能とみなします。

デフォルトの設定では、クラスターネットワークは 10.128.0.0/14 ネットワーク (つまり 10.128.0.0 - 10.131.255.255) で、ノードには /23 サブネット (つまり 10.128.0.0/2310.128.2.0/2310.128.4.0/23 など) が割り当てられます。つまり、このクラスターネットワークには、512 個のサブネットをノードに割り当てることができ、特定のノードには 510 個のアドレスが割り当てられ、このノードで実行中のコンテナーに割り当てることができます。クラスターネットワークのサイズやアドレス範囲、さらにホストのサブネットサイズは、設定可能です。

注記

サブネットが次に大きい octet に拡張される場合には、共有の octet でサブネットのビットが 0 のものが先に割り当てられます。たとえば、ネットワークが 10.1.0.0/16 で hostsubnetlength=6 が指定されている場合には、10.1.0.0/26 および 10.1.1.0/26 から 10.1.255.0/26 が 10.1.0.64/26、10.1.1.64/26 が埋まる前に、割り当てられます。こうすることで、サブネットを把握しやすくなります。

マスター上の OpenShift SDN では、ローカル (マスター) ホストが、クラスターネットワークにアクセスできるように設定されないので、マスターホストは、ノードとして実行されない限り、クラスターネットワーク経由で Pod にアクセスできません。

ovs-multitenant プラグインを使用する場合には、OpenShift SDN マスターはプロジェクトの作成や削除を監視し、VXLAN VNID をプロジェクトに割り当てます。この VNID は後で、ノードが正しくトラフィックを分離するために使用します。

5.2.3. ノード上の設計

ノードでは OpenShift SDN は先に、前述のレジストリーに、SDN マスターを持つローカルホストを登録し、マスターがノードにサブネットを割り当てられるようにします。

次に OpenShift SDN は、3 つのネットワークデバイスを作成、設定します。

  • br0: Pod コンテナーが割り当てられる OVS ブリッジデバイスです。OpenShift SDN は、このブリッジにサブネット以外のフロールールも設定します。
  • tun0: OVS の内部ポート (br0 のポート 2) です。これには、クラスターサブネットゲートウェイアドレスが割り当てられ、外部のネットワークアクセスに使用されます。OpenShift SDN は クラスターサブネットから外部ネットワークに NAT 経由でアクセスできるように、netfilter およびルーティングルールを設定します。
  • vxlan_sys_4789: OVS VXLAN デバイス (br0 のポート 1) です。これはリモートノードのコンテナーへのアクセスを提供します。OVS ルールでは vxlan0 として参照されます。

Pod がホストで起動されるたびに、OpenShift SDN は以下を行います。

  1. 対象の Pod に、ノードのクラスターサブネットから、空いている IP アドレスを割り当てます。
  2. ホスト側の Pod の veth インターフェースペアを OVS ブリッジ br0 に割り当てます。
  3. OpenFlow ルールを OVS データベースに追加して、新規の Pod にアドレス指定されたトラフィックを正しい OVS ポートにルーティングします。
  4. ovs-multitenant プラグインの場合は、Pod からのトラフィックには、その Pod の VNID をタグ付けし、トラフィックの VNID が Pod の VNID (または特権のある VNID 0) と一致する場合にはその Pod にトラフィックを許可するという OpenFlow ルールを追加します。一致しないトラフィックは、一般的なルールで除外されます。

OpenShift SDN ノードは、SDN マスターからのサブネットの更新も監視します。新しいサブネットが追加された場合には、リモートサブネットの宛先 IP アドレスノードを持つパケットが vxlan0 (br0 のポート 1) に移動してネットワーク送信されるように、br0 に OpenFlow ルールを追加します。ovs-subnet プラグインは VNID 0 が指定された VXLAN に全パケットを送信しますが、ovs-multitenant プラグインは、ソースコンテナーに対して適切な VNID を使用します。

5.2.4. パケットフロー

A と B の 2 つのコンテナーがあり、コンテナー A の eth0 をベースにするピア仮想 Ethernet デバイスの名前が vethA、コンテナー B の eth0 のピア名が vethB とします。

注記

Docker サービスが使用するピアの仮想 Ethernet デバイスに慣れていない場合は、「Docker の高度なネットワークに関するドキュメント」を参照してください。

まず。コンテナー A がローカルホストにあり、コンテナー B もローカルホストにあると仮定します。コンテナー A からコンテナー B のパケットフローは以下のようになります。

eth0 (A の netns) → vethAbr0vethBeth0 (B の netns)

次に、コンテナー A がローカルホストに、コンテナー B がクラスターネットワーク上のリモートホストにあると想定します。その場合には、コンテナー A からコンテナー B のパケットフローは以下のようになります。

eth0 (A の netns) → vethAbr0vxlan0 → ネットワーク [1]vxlan0br0vethBeth0 (B の netns)

最後に、コンテナー A が外部ホストに接続すると、トラフィックは以下のようになります。

eth0 (A の netns) → vethAbr0tun0 → (NAT) → eth0 (物理デバイス) → インターネット

パケット配信の意思決定はほぼ、OVS ブリッジ br0 の OpenFlow ルールをもとに行われ、プラグインのネットワークアーキテクチャーを簡素化し、ルーティングを柔軟化します。ovs-multitenant プラグインの場合は、OpenFlow ルールを元にした意思決定により、強制的な「ネットワーク分離」が可能になります。

5.2.5. ネットワーク分離

ovs-multitenant プラグインを使用して、ネットワーク分離を実現できます。デフォルト以外のプロジェクトに割り当てられた Pod からパケットが送信される場合は、OVS ブリッジ br0 により、このパケットに、プロジェクトが割り当てた VNID のタグを付けます。パケットが、ノードのクラスターサブネットに含まれる別の IP アドレスに転送される場合には、OVS ブリッジは、VNID が一致する場合にのみ、宛先の Pod に対するこのパケットの配信を許可します。

パケットが別のノードから VXLAN トンネル経由で受信された場合には、トンネル ID を VNID として使用し、OVS ブリッジは、トンネル ID が宛先の Pod の VNID に一致する場合にのみ、ローカル Pod へのパケットの配信を許可します。

他のクラスターサブネットが宛先のパケットは、その VNID でタグ付けされ、クラスターサブネットを所有するノードのトンネルの宛先アドレスが指定された VXLAN トンネルに配信されます。

前述の通り、VNID 0 は、VNID 0 が割り当てられた pod には、VNID が指定されたトラフィックを送信できる点で特権があります。デフォルト の OpenShift Container Platform プロジェクトには VNID 0 が割り当てられています。他のプロジェクトにはすべて、一意の分離可能な VNID が割り当てられています。クラスター管理者はオプションで、管理者 CLI を使用してプロジェクトの「Pod ネットワークを管理」できます。

5.3. 利用可能な SDN プラグイン

OpenShift Container Platform は、OpenShift Container Platform と Kubernetes の間のインターフェースとして、Kubernetes Container Network Interface (CNI) をサポートします。Software Defined Network (SDN) プラグインを使用することで、ネットワーク機能がユーザーのネットワークのニーズに対応します。必要に応じて、CNI インターフェースをサポートするプラグインをさらに追加できます。

5.3.1. OpenShift SDN

OpenShift SDN は、デフォルトでAnsible ベースのインストール手順の一部としてインストール設定されます。詳細情報は、「OpenShift SDN」のセクションを参照してください。

5.3.2. サードパーティーの SDN プラグイン

5.3.2.1. Flannel SDN

flannel は、コンテナー専用に設計された仮想ネットワーク層です。OpenShift Container Platform は、デフォルトの Software-Defined Networking (SDN) コンポーネントの代わりに、ネットワークコンテナーとして flannel を使用できます。これは、OpenStack など、SDN にも依存するクラウドプロバイダープロット内で OpenShift Container Platform を実行している場合や、両プラットフォームを通してパケットを 2 回カプセル化しなくても良いようにする場合に便利です。

アーキテクチャー

OpenShift Container Platform は、flannelhost-gw モードで実行し、コンテナー間のルートをマッピングします。ネットワーク内の各ホストは、flanneld と呼ばれるエージェントを実行します。このエージェントは以下を行います。

  • ホスト毎に一意のサブネットを管理する
  • ホスト上の各コンテナーに IP アドレスを割り当てる
  • 別のホスト上であっても、コンテナー間のルートをマッピングする

flanneld エージェントは、この情報を中央の etcd ストアに提供し、ホスト上の他のエージェントがパケットを、flannel ネットワーク内の他のコンテナーにルーティングできるようにします。

以下の図は、flannel ネットワークを使用したコンテナー間のアーキテクチャーおよびデータフローを示します。

Flannel Communication

ノード 1 には以下のルートが含まれます。

default via 192.168.0.100 dev eth0 proto static metric 100
10.1.15.0/24 dev docker0 proto kernel scope link src 10.1.15.1
10.1.20.0/24 via 192.168.0.200 dev eth0

ノード 2 には以下のルートが含まれます。

default via 192.168.0.200 dev eth0 proto static metric 100
10.1.20.0/24 dev docker0 proto kernel scope link src 10.1.20.1
10.1.15.0/24 via 192.168.0.100 dev eth0

5.3.2.2. Nuage SDN

「Nuage Networks」の SDN ソリューションは、OpenShift Container Platform クラスターの Pod に対して、スケーラビリティーが高い、ポリシーベースのオーバーレイネットワークを提供します。Nuage SDN は、Ansible ベースのインストール手順の一部としてインストール、設定可能です。Nuage SDN での OpenShift Container Platform のインストールおよびデプロイ方法に関する情報は、「標準インストール」のセクションを参照してください。

Nuage Networks は、Virtualized Services Platform (VSP) と呼ばれる、スケーラビリティーの高い、ポリシーベースの SDN プラットフォームを提供します。Nuage VSP は、データプレーン用にオープンソースの Open vSwitch とともに、SDN Controller を使用します。

Nuage は、オーバーレイを使用して、OpenShift Container Platform と VM およびベアメタルサーバーからなる他の環境の間をポリシーベースで接続できるようにします。プラットフォームのリアルタイムアナリティクスエンジンでは、OpenShift Container Platform アプリケーションの可視化およびセキュリティー監視を実現します。

Nuage VSP は OpenShift Container Platform と統合し、DevOps チームが直面するネットワークのラグを取り除くことで、ビジネスアプリケーションがすばやく起動と更新ができるようにします。

図5.1 Nuage VSP と OpenShift Container Platform との統合

Nuage VSP Integration with OpenShift Container Platform

統合を行う固有のコンポーネントが 2 つあります。

  1. nuage-openshift-monitor サービス。OpenShift Container Platform マスターノードで個別のサービスとして実行されます。
  2. vsp-openshift プラグイン。クラスターの各ノードで OpenShift Container Platform ランタイムにより呼び出されます。

Nuage Virtual Routing and Switching ソフトウェア (VRS) は、オープンソースの Open vSwitch をベースにしており、データパス転送を行います。VRS は各ノードで実行され、コントローラーからポリシー設定を取得します。

Nuage VSP の用語

図5.2 Nuage VSP のビルディングブロック

Nuage VSP Building Blocks
  1. ドメイン: 組織には 1 つまたは複数のドメインが含まれます。ドメインは単一の「レイヤー 3」の領域を指します。標準のネットワーク用語では、ドメインは、VRF インスタンスと同じ位置づけです。
  2. ゾーン: ゾーンは、ドメインの配下に定義されます。ゾーンは、直接ネットワーク上のなにかにマッピングされるわけではなく、ゾーンの全エンドポイントが同じポリシーセットに準拠するなど、ポリシーが関連付けられているオブジェクトとして機能します。
  3. サブネット: サブネットはゾーンの配下に定義されます。サブネットは、ドメインインスタンス内の固有のレイヤー 2 サブネットを指します。サブネットは、ドメイン内で一意で他とは異なります。つまり、ドメイン内のサブネットは、重複したり、標準の IP サブネット定義に従って他のサブネットを含めたりすることもできません。
  4. VPorts: VPort は、ドメイン階層の新しいレベルで、より粒度の高い設定を可能にするために設計されました。コンテナーや VM に加え、ホストやブリッジインターフェースにアタッチには VPorts も使用し、ベアメタルサーバー、アプリケーション、レガシー VLAN に接続できるようにします。
  5. ポリシーグループ: ポリシーグループは VPorts のコレクションです。

コンストラクトのマッピング

OpenShift Container Platform のコンセプト の多くは、Nuage VSP のコンストラクトに直接マッピングできます。

図5.3 Nuage VSP および OpenShift Container Platform のマッピング

Nuage VSP and OpenShift Container Platform mapping

Nuage サブネットは、OpenShift Container Platform ノードにマッピングされませんが、特定のプロジェクトのサブネットは、OpenShift Container Platform 内の複数のノードに対応できます。

OpenShift Container Platform で起動する Pod は VSP で作成された仮想ポートに変換されます。vsp-openshift プラグインは、VRS と対話し、VSC 経由で VSD からその仮想ポートのポリシーを取得します。ポリシーグループは、複数の Pod をグループ化がサポートされていますが、同じポリシーが適用されている必要があります。現在、Pod は、「オペレーションワークフロー」を使用してポリシーグループに割り当てることができます。このワークフローでは、ポリシーグループは VSD の管理者ユーザーが作成します。ポリシーグループに含まれる Pod は、Pod の仕様で nuage.io/policy-group ラベルとして指定されます。

統合コンポーネント

Nuage VSP は、2 つの主要コンポーネントを使用して OpenShift Container Platform と統合します。

  1. nuage-openshift-monitor
  2. vsp-openshift plugin

nuage-openshift-monitor

nuage-openshift-monitor は、プロジェクト、サービス、ユーザー、ユーザーグループなどが作成されていないか、OpenShift Container Platform API サーバーを監視するサービスです。

注記

複数のマスターがある高可用性の (HA) OpenShift Container Platform クラスターの場合には、nuage-openshift-monitor プロセスは、機能性に変更を加えずに、全マスター上で個別に実行されます。

開発者のワークフローでは、nuage-openshift-monitor も、VSD REST API を実行して OpenShift Container Platform コンストラクトを VSP コンストラクトにマッピングすることで、VSD オブジェクトを自動作成します。各クラスターインスタンスは、Nuage VSP の単一ドメインにマッピングします。これにより、Nuage でエンタープライズのドメインインスタンス毎に 1 つ設定するなど、特定のエンタープライズで複数のクラスターをインストールできます。各 OpenShift Container Platform プロジェクトは、Nuage VSP のクラスターのドメインに含まれるゾーンにマッピングされます。nuage-openshift-monitor で、プロジェクトの追加、削除が検出された場合に、対象のプロジェクトに対応する VSDK API を使用してゾーンをインスタンス化し、そのゾーンにサブネットのブロックを割り当てます。さらに、nuage-openshift-monitor は、このプロジェクトのネットワークマクログループも作成します。同様に、nuage-openshift-monitor でサービスの追加や削除が検出された場合には、サービス IP に対応するネットワークマクロを作成して、そのネットワークマクロを該当のプロジェクトのネットワークマクログループに割り当てて (ラベルを使用したユーザー提供のネットワークマクログループもサポートされています)、対象のサービスへの通信を有効化します。

開発者のワークフローでは、ゾーン内で作成された pod はすべて、そのサブネットプールからの IP を取得します。nuage-openshift-monitor が、master-config ファイルのプラグイン固有のパラメーター 2 つをもとにして、サブネットプールを割り当て、管理します。ただし、実際の IP アドレスの解決および vport ポリシーの解決は、プロジェクトの作成時にインスタンス化されたドメイン/ゾーンをもとに、VSD が行います。最初のサブネットプールが足りなくなった場合には、nuage-openshift-monitor はクラスターの CIDR から追加のサブネットを検出し、特定のプロジェクトに割り当てます。

オペレーションのワークフローでは、アプリケーションまたは pod 仕様に Nuage が認識するラベルを指定して、Pod と固有のユーザー定義ゾーンやサブネットを解決します。ただし、これは、nuage-openshift-monitor を使用して開発者ワークフローで作成したゾーンやサブネットの Pod を解決するために使用できません。

注記

オペレーションワークフローでは、管理者は VSD コンストラクトを事前作成し、Pod を特定のゾーン/サブエンっとにマッピングして、OpenShift エンティティー (ACL ルール、ポリシーグループ、ネットワークマクロ、ネットワークマクログループ) 間の通信を可能にします。Nuage ラベルの使用方法に関する説明は『Nuage VSP Openshift Integration Guide』に記載されています。

vsp-openshift Plug-in

vsp-openshift ネットワークプラグインは、OpenShift Container Platform ランタイムが各 OpenShift Container Platform ノードで呼び出します。このプラグインは、ネットワークプラグイン init および Pod の設定、破棄、ステータスフックを実装します。vsp-openshift プラグインは、Pod に IP アドレスも割り当てます。特に、VRS (転送エンジン) と通信して、IP 情報を Pod に設定します。

5.3.3. Kuryr SDN と OpenShift Container Platform

Kuryr (具体的には Kuryr-Kubernetes) は、CNIOpenStack Neutron を使用して構築した SDN ソリューションです。Kuryr の利点として、幅広い Neutron SDN バックエンドを使用でき、Kubernetes Pod と OpenStack 仮想マシン (VM) の相互接続性が確保できる点が挙げられます。

Kuryr-Kubernetes と OpenShift Container Platform の統合は主に、OpenStack の仮想マシンで実行する OpenShift Container Platform クラスター用に設計されました。

5.3.3.1. OpenStack デプロイメント要件

Kuryr SDN では、使用する OpenStack 設定に関して要件があります。特に以下の要件が含まれます。

  • サービスには最低でも、Keystone と Neutron が含まれていること
  • Kuryr SDN は Octavia で機能すること
  • トランクポート拡張が有効化されていること
  • Neutron は Open vSwitch ファイアウォールドライバーを使用すること

5.3.3.2. kuryr-controller

kuryr-controller は、新しい Pod が起動され、その Pod 用に Neutron リソースが作成されていないかどうか、OpenShift Container Platform API を監視するサービスです。たとえば、Pod が作成されると、kuryr-controller はそれを認識し、新規ポートの作成のため、OpenStack Neutron を呼び出します。次に、そのポート (または VIF) に関する情報が Pod のアノテーションに保存されます。また、kuryr-controller は、作成済みのポートプールを使用して、Pod の作成時間を短縮することができます。

現在、kuryr-controller は単一のサービスインスタンスとして実行する必要があるおので、OpenShift Container Platform では、replicas=1Deployment としてモデル化されています。kuryr-controller では、OpenStack サービス API にアクセスできる必要があります。

5.3.3.3. kuryr-cni

kuryr-cni コンテナーは、Kuryr-Kubernetes デプロイメントで、OpenShift Container Platform ノードへの Kuryr CNI スクリプトのインストールおよび設定と、ホスト上の Pod をネットワーク接続する kuryr-daemon サービスの実行の 2 つの役割を果たします。つまり、kuryr-cni コンテナーはすべての OpenShift Container Platform ノードで実行する必要があるので、DaemonSet としてモデル化されます。

OpenShift Container Platform CNI は、新しい Pod が起動するか、Pod が OpenShift Container Platform ホストから削除されるたびに、Kuryr CNI スクリプトを呼び出します。このスクリプトは、ローカルの kuryr-cni のコンテナー ID を Docker API から取得して、CNI 呼び出し引数すべてを渡す Docker 実行ファイルを使用して、Kuryr CNI プラグインバイナリーを実行します。次に、このプラグインは、ローカルの HTTP ソケット経由で kuryr-daemon を呼び出し、再度すべてのパラメーターを渡します。

kuryr-daemon サービスは、このサービス用に作成された Neutron VIF に関する Pod のアノテーションを監視します。特定の Pod に対する CNI 要求が受信されると、デーモンのメモリーで VIF 情報がすでに認識されているか、Pod 定義にアノテーションが表示されるのを待ちます。VIF 情報を認識したら、すべてのネットワーク操作が行われます。

5.4. 利用可能なルータープラグイン

ルーターは、ノードに割り当てて OpenShift Container Platform クラスターのトラフィックを制御することができます。OpenShift Container Platform はデフォルトのルーターとして HAProxy を使用しますが、オプションも提供されています。

5.4.1. HAProxy テンプレートルーター

HAProxy テンプレートのルーター実装は、テンプレートルータープラグインの参照実装です。これは、openshift3/ose-haproxy-router リポジトリーを使用して、テンプレートルータープラグインとともに、HAProxy インスタンスを実行します。

テンプレートルーターには 2 つのコンポーネントがあります。

  • エンドポイントとルートを監視して変更をもとに HAProxy の再読み込みをトリガーするラッパー
  • ルートとエンドポイントをベースに HAProxy 設定ファイルをビルドするコントローラー
注記

HAProxy ルーター はバージョン 1.8.1 を使用します。

コントローラーおよび HAProxy は、Pod 内に常駐しており、デプロイメント設定で管理されます。ルーターの設定プロセスは、oc adm router コマンドで自動化されています。

コントローラーは、ルートとエンドポイントに変更がないか、また、HAProxy プロキシーを監視します。変更が検出されたら、新しい haproxy-config ファイルを作成して、HAProxy を再起動します。haproxy-config ファイルは、ルーターのテンプレートファイルと OpenShift Container Platform からの情報をベースに構築されます。

HAProxy テンプレートファイルは、必要に応じてカスタマイズして、OpenShift Container Platform で現在サポートされていない機能をサポートすることができます。HAProxy マニュアル では、HAProxy がサポートする全機能を説明しています。

以下の図では、データがプラグインを使用してマスターから最終的に HAProxy 設定にどのように移動するかが記載されています。

図5.4 HAProxy ルーターデータフロー

HAProxy Router Data Flow

HAProxy テンプレートルーターメトリクス

HAProxy ルーターは、外部のメトリクスコレクションや集計システム (例 Prometheus、statsd) で消費されるように、Prometheus 形式 のメトリクスを提供して公開します。ルーターは、HAProxy CSV 形式 のメトリクスを提供するように設定したり、まったくルーターメトリクスを提供しないように設定したりできます。

メトリクスは、ルーターコントローラーおよび HAProxy の両方から 5 秒毎に取得されます。ルーターメトリクスカウンターは、ルーターのデプロイ時に 0 から開始され、経時的に増加します。HAProxy メトリクスカウンターは、HAProxy が再読み込みされるたびに 0 にリセットされます。ルーターはフロントエンド、バックエンド、サーバー毎に HAProxy 統計を収集します。サーバーが 500 台以上ある場合に、リソースの使用量を減らすには、バックエンドでは複数のサーバーを利用できるので、サービスではなく、バックエンドをレポートします。

この統計は 利用可能な HAProxy 統計 のサブセットです。

以下の HAProxy メトリクスは定期的に収集され、Prometheus 形式に変換されます。フロントエンドはすべて、"F" カウンターが収集されます。バックエンド毎のカウンターを収集する場合には、サーバー毎の "S" サーバーカウンターが収集されます。それ以外の場合は、バックエンド毎に "B" カウンターが収集され、サーバーカウンターは収集されません。

詳細は、ルーター環境変数を参照してください。

以下の表を参照してください。

列 1 - HAProxy CSV 統計のインデックス

列 2

F

フロントエンドのメトリクス

b

サーバーのしきい値が原因でサーバーメトリクスを表示しない場合のバックエンドメトリクス

B

サーバーメトリクスを表示する場合のバックエンドメトリクス

S

サーバーメトリクス

列 3 - カウンター

列 4 - カウンターの説明

インデックス

使用法

カウンター

説明

2

bBS

current_queue

サーバーに割り当てられていないキューに入れられた要求の現在の数。

4

FbS

current_sessions

アクティブなセッションの現在の数。

5

FbS

max_sessions

アクティブなセッションの観察される最大数。

7

FbBS

connections_total

接続の合計数。

8

FbS

bytes_in_total

受信バイトの現在の合計。

9

FbS

bytes_out_total

送信バイトの現在の合計。

13

bS

connection_errors_total

接続エラーの合計。

14

bS

response_errors_total

応答エラーの合計。

17

bBS

アップ

現在のバックエンドのヘルスステータス (1 = UP、0 = DOWN)。

21

S

check_failures_total

失敗したヘルスチェックの合計数。

24

S

downtime_seconds_total

合計ダウンタイム (秒)。

33

FbS

current_session_rate

直近の 1 秒間で、1 秒あたりの現在のセッション数。

35

FbS

max_session_rate

1 秒あたりの最大セッション実数。

40

FbS

http_responses_total

HTTP 応答合計数、コード 2xx。

43

FbS

http_responses_total

HTTP 合計応答数、コード 5xx。

60

bS

http_average_response_latency_milliseconds

直近の要求 1024 件のうちの HTTP 応答 (ミリ秒単位)。

ルーターコントローラーは、以下のアイテムを収集します。これらは、Prometheus 形式のメトリクスでのみ提供されます。

名前

説明

template_router_reload_seconds

ルーターの再読み込みにかかる時間を秒単位で測定します。

template_router_write_config_seconds

ルーター設定のディスクへの書き込みにかかる時間を秒単位で測定します。

haproxy_exporter_up

最後に成功した haproxy の収集です。

haproxy_exporter_csv_parse_failures

CSV の解析時のエラー数です。

haproxy_exporter_scrape_interval

次の収集が許可されるまでの秒単位の時間です (データのサイズに比例します)。

haproxy_exporter_server_threshold

追跡したサーバー数と現在のしきい値です。

haproxy_exporter_total_scrapes

現在の合計 HAProxy 収集数です。

http_request_duration_microseconds

ミクロ秒単位の HTTP 要求のレイテンシーです。

http_request_size_bytes

バイト単位の HTTP 要求サイズです。

http_response_size_bytes

バイト単位の HTTP 応答サイズです。

openshift_build_info

OpenShift がビルドされた major、minor、git commit、git version でラベル付けされた定数値 '1' のメトリクスです。

ssh_tunnel_open_count

SSH トンネルを開放しようと試行した合計数です。

ssh_tunnel_open_fail_count

SSH トンネルを開放しようとして失敗した合計数です。

5.4.2. F5 BIG-IP® ルータープラグイン

F5 BIG-IP® ルータープラグインは、利用可能な 「ルータープラグイン」の 1 つです。

注記

F5 ルータープラグインは OpenShift Enterprise 3.0.2 以降で利用できます。

F5 ルータープラグインは、お使いの環境で既存の F5 BIG-IP® システムと統合します。F5 iControl REST API を使用するには、F5 BIG-IP バージョン 11.4 以降が必要です。F5 ルーターは、HTTP vhost および要求パスで一致する unsecurededge terminationre-encryption termination および passthrough termination ルートをサポートします。

F5 ルータープラグインは、HAProxy テンプレートルーター と同等機能を備えており、以下の機能を追加でサポートします。

  • パスベースのルーティング (ポリシールールを使用)
  • Re-encryption (クライアントおよびサーバーの SSL プロファイルを使用した実装)
  • 暗号化接続のパススルー (SNI プロトコルを解析し、サーバー名ルックアップ用に F5 ルーターが管理するデータグループを使用する iRule で実装)
注記

パススルールートは特別なケースです。F5 BIG-IP 自体が HTTP 要求を認識できず、パスを検証できないので、パスベースのルーティングは技術的に、パススルールートでは不可能です。同じ制限が、テンプレートルーターにも適用されます。これは、パススルー暗号化の技術的制限で、OpenShift Container Platform の技術的制限ではありません。

5.4.2.1. SDN 経由での Pod に対するトラフィックのルーティング

F5 BIG-IPOpenShift SDN 外にあるので、クラスター管理者は F5 BIG-IP と SDN 上にあるホスト (通常は OpenShift Container Platform ノードホスト) 間でピアツーピアトンネルを作成する必要があります。この ramp ノード は、pod に対して スケジュール不可 と設定して、F5 BIG-IP ホストのゲートウェイ以外として機能しないようにすることができます。また、このようなホストを複数設定して、冗長化のために OpenShift Container Platform ipfailover 機能を使用できます。F5 BIG-IP ホストは、トンネルのリモートエンドポイントに、ipfailover VIP を使用するように設定する必要があります。

5.4.2.2. F5 統合の詳細

F5 ルータープラグインの操作は、以前のバージョンで使用していた OpenShift Container Platform routing-daemon とよく似ています。いずれも REST API 呼び出しを使用して以下を行います。

  • プールを作成、削除する
  • これらのプールにエンドポイントを追加して、このプールからエンドポイントを削除する
  • ポリシールールが vhost をベースにしてププールにルーティングするように設定する

いずれも scpssh コマンドを使用してカスタムの TLS/SSL 証明書を F5 BIG-IP にアップロードします。

F5 ルータープラグインは、仮想サーバー上のプールとポリシールールを以下のように設定します。

  • ユーザーが OpenShift Container Platform でルートを作成、または削除すると、ルーターは F5 BIG-IP にルート用のプールを作成して (すでにプールが存在しない場合)、TLS 以外のルートの HTTP vserver またはエッジまたは再暗号化ルートの HTTPS vserver など、適切な vserver のポリシーに対してルールを追加/削除します。edge および re-encrypt ルートの場合には、ルーターも TLS 証明書と鍵をアップロードして設定します。ルーターは、ホストおよびパスベースのルートをサポートします。

    注記

    パススルーは特別なケースです。これをサポートするには、SNI ClientHello ハンドシェークレコードを解析して、F5 データグループでサーバー名をルックアップするための iRule を記述する必要があります。ルーターはこの iRule を作成して、この iRule と vserver を関連付け、パススルールートの作成/削除に伴い、F5 データグループを更新します。この実装の詳細以外は、パススルールートは、他のルートと同じように機能します。

  • OpenShift Container Platform でサービスを作成すると、ルートは F5 BIG-IP にプールを追加します (プールが存在しない場合)、このサービスにエンドポイントが作成/削除されると、ルーターは適切なプールメンバーを追加/削除します。
  • ユーザーがルートを削除と、特定のプールに関連付けられたエンドポイントをすべて削除すると、ルーターはそのプールを削除します。

5.4.2.3. F5 ルータープラグイン

F5 Big-IP と OpenShift Container Platform をネイティブで統合する場合に、ramp ノードの設定は OpenShift SDN で作成されるので、F5 Big-IP がオーバーレイネットワーク上の Pod に到達できるように ramp ノードを設定する必要はありません。

また、F5 BIG-IP アプライアンスのバージョン 12.x 以降のみが、このセクションに記載されている F5 ルータープラグインに対応しています。また、適切に統合を行うために sdn-services アドオンライセンスが必要になります。バージョン 11.x の場合は、ramp ノードを設定してください

接続

F5 アプライアンスは、L3 接続で OpenShift Container Platform クラスターに接続できます。OpenShift Container Platform のノード間では、L2 スイッチの接続性は必要ありません。F5 アプライアンスでは、複数のインターフェースを使用して統合を管理できます。

  • 管理インターフェース: F5 アプライアンスの Web コンソールに到達する
  • 外部インターフェース: 受信 Web トラフィック用に仮想サーバーを設定する
  • 内部インターフェース: アプライアンスをプログラムして、Pod に到達する
F5 and OpenShift Connection Diagram

F5 コントローラー Pod は、アプライアンスへの admin 権限があります。F5 イメージは、OpenShift Container Platform クラスター (ノード上にスケジュール) で起動して、iControl REST API を使用してポリシーで仮想サーバーをプログラムし、VxLAN デバイスを設定します。

データフロー: パケットから Pod へ
注記

このセクションでは、パケットが Pod に到達する方法および Pod がパケットに到達する方法について説明します。これらのアクションは、ユーザーではなく、F5 ルータープラグイン Pod と F5 アプライアンスにより実行されます。

ネイティブで統合されると、F5 アプライアンスは VxLAN のカプセル化を使用して直接 pod に到達します。この統合は、OpenShift Container Platform が openshift-sdn をネットワークプラグインとして使用している場合のみ機能します。openshift-sdn プラグインは、このプラグインが作成するオーバーレイネットワークに対して、VxLAN のカプセル化を採用します。

Pod と F5 アプライアンスの間でデータパスを正常に確立するには以下を行います。

  1. F5 は、Pod 向けの VxLAN パケットをカプセル化する必要があります。これには、sdn-services ライセンスアドオンが必要です。VxLAN デバイスを作成する必要があり、Pod オーバーレイネットワークはこのデバイス経由でルーティングする必要があります。
  2. F5 は Pod の VTEP IP アドレスを知る必要があります。これは、Pod が配置されているノードの IP アドレスです。
  3. F5 は、Pod 向けのパケットをカプセル化する時に、オーバーレイネットワークに使用する source-ip を知っておく必要があります。これは ゲートウェイアドレス として知られています。
  4. OpenShift Container Platform ノードは、F5 ゲートウェイアドレスがなにか (戻りトラフィックの VTEP アドレス) を知っておく必要があります。このアドレスは、内部インターフェースのアドレスでなければなりません。クラスターの全ノードは、自動的にこれを学習する必要があります。
  5. オーバーレイネットワークはマルチテナントに対応しているので、F5 は admin を代表する VxLAN ID を使用して F5 が全テナントに到達できるようにする必要があります。手動作成した hostsubnet (pod.network.openshift.io/fixed-vnid-host: 0) でアノテーションを指定することで、F5 により vnid0 (OpenShift Container Platform の admin namespace でデフォルトの vnid) の全パケットがカプセル化されるようにします。

ghost hostsubnet は、設定の一部として手動で作成します。これは、3 番目と 4 番目の要件を満たします。F5 ルータープラグインの起動時に、F5 アプライアンスが適切にプログラムされるように、この新しい ghost hostsubnet が提供されます。

注記

サブネットがクラスターのノードに割り当てられるので、ghost hostsubnet という用語が使用されます。ただし、実際には、クラスターの実際のノードではなく、外部のアプライアンスによりハイジャックされます。

1 番目の要件は、F5 コントローラー Pod の起動時に、F5 ルータープラグインが満たします。2 番目の要件は、F5 プラグイン Pod が対応しますが、継続プロセスです。クラスターに追加される新規ノードごとに、コントローラー Pod は VxLAN デバイスの VTEP FDB のエントリーを作成します。コントローラー Pod には、クラスターの nodes リソースへのアクセス権が必要ですが、これは、サービスアカウントに適切な権限を割り当てることで対応できます。以下のコマンドを使用してください。

$ oc adm policy add-cluster-role-to-user system:sdn-reader system:serviceaccount:default:router
F5 ホストからのデータフロー
注記

以下のアクションは、ユーザーではなく F5 ルータープラグイン Pod および F5 アプライアンスによって実行されます。

  1. 宛先 Pod はパケットの F5 仮想サーバーで識別されます。
  2. VxLAN 動的 FDB は Pod の IP アドレスで検索されます。MAC アドレスが見つかる場合はステップ 5 に進みます。
  3. Pod の MAC アドレスを求める ARP 要求で、VTEP FDB の全エントリーをいっぱいにします。Pod の MAC アドレスと VTEP を値として使用して、VxLAN ダイナミック FDB にエントリーが追加されます。
  4. VxLAN ヘッダーで IP パケットをカプセル化します。Pod の MAC およびノードの VTEP が、VxLAN 動的 FDB からの値として指定されます。
  5. ARP を送信し、ホストの周辺にあるキャッシュを確認して、VTEP の MAC アドレスを計算します。
  6. F5 ホストの内部アドレスでパケットを送信します。
データフロー: トラフィックを F5 ホストに返す
注記

以下のアクションは、ユーザーではなく F5 ルータープラグイン Pod および F5 アプライアンスによって実行されます。

  1. Pod は、宛先を F5 ホストの VxLAN ゲートウェイアドレスとしてパケットを戻します。
  2. ノードの openvswitch は、このパケットの VTEP が F5 ホストの内部インターフェースアドレスであるかどうか判断します。これは、ghost hostsubnet の作成時に分かります。
  3. VxLAN パケットは、F5 ホストの内部インターフェースに送信されます。
注記

マルチテナントを回避するように、VNID は予め、データフロー全体で 0 に固定されます。

5.5. ポート転送

5.5.1. 概要

OpenShift Container Platform は、Kubernetes に組み込まれている機能を活用して、Pod へのポート転送をサポートします。これは、HTTP と SPDY または HTTP/2 などの多重化ストリーミングプロトコルを使用して実装されます。

開発者は「CLI」を使用して pod にポート転送できます。CLI は、ユーザーが指定した各ローカルポートをリッスンし、「記載のプロトコル」を使用して転送します。

5.5.2. サーバー操作

Kubelet は、クライアントからのポート転送要求を処理します。要求を受信すると、応答をアップグレードし、クライアントがポート転送ストリームを作成するまで待機します。新規ストリームを受信したら、ストリームと Pod ポート間のデータをコピーします。

アーキテクチャー的には、Pod のポートに転送するオプションがあります。OpenShift Container Platform でサポートされる現在の実装はノードホストで直接 nsenter を呼び出し、Pod ネットワークの namespace に入り、socat を呼び出してストリームと Pod のポート間のデータをコピーします。ただし、カスタムの実装には、nsentersocat のバイナリーをホストにインストールしなくていいように、これらのバイナリーを実行する「ヘルパー」 Pod の実行が含まれています。

5.6. リモートコマンド

5.6.1. 概要

OpenShift Container Platform は Kubernetes に内蔵されている機能を活用し、コンテナーでのコマンド実行をサポートします。これは、HTTP と SPDY または HTTP/2 などの多重化ストリーミングプロトコルを使用して実装されます。

開発者は「CLI を使用」して、コンテナーでリモートコマンドを実行します。

5.6.2. サーバー操作

Kubelet は、クライアントからのリモート実行要求を処理します。要求を受信すると応答をアップグレードして、要求ヘッダーを評価してどのストリーム (stdinstdout および/または stderr) を受信するか判断し、クライアントがストリームを作成するまで待機します。

Kubelet が全ストリームを受信したら、コンテナーでコマンドを実行して、ストリームとコマンドの stdin、stdout および stderr を適切にコピーします。コマンドが中断されたら、Kubelet はアップグレードされた接続と基盤の接続を終了します。

アーキテクチャー的に、コンテナーでコマンドを実行するオプションがあります。OpenShift Container Platform で現在サポートされている実装では、ノードホストで nsenter を直接呼び出して、コマンド実行前に、ノードホストがコンテナーの namespace に入ることができるようにします。ただし、カスタム実装には docker exec の使用や、ホストでインストールする必要のある nsenter バイナリーが必須とならないように nsenter を実行する「ヘルパー」コンテナーの実行が含まれる場合があります。

5.7. ルート

5.7.1. 概要

OpenShift Container Platform ルートは、外部クライアントが名前でサービスに到達できるように、www.example.com などのホスト名で サービス を公開します。

ホスト名の DNS 解決はルーティングとは別に処理されます。管理者が、OpenShift Container Platform ルーターを実行する OpenShift Container Platform ノードを解決するように「DNS ワイルドカードエントリー」を設定している場合があります。異なるホスト名を使用している場合には、DNS レコードを個別に変更して、ルーターを実行するノードを解決する必要があります。

各ルーターは名前 (63 文字に制限)、サービスセレクター、およびオプションのセキュリティー設定で構成されています。

5.7.2. ルーター

OpenShift Container Platform 管理者は、OpenShift Container Platform のノードに ルーター をデプロイできるので、「開発者が作成した」ルートを外部クライアントが利用できるようになります。OpenShift Container Platform のルーティング層はプラグ可能で、複数の「ルータープラグイン」がデフォルトで提供、サポートされています。

注記

ルーターのデプロイに関する情報は、『クラスター設定ガイド』を参照してください。

ルーターは、サービスセレクターを使用して、「サービス」と、サービスをバッキングするエンドポイントを検索します。ルーターとサービス両方が負荷分散を提供する場合には、OpenShift Container Platform はルーターの負荷分散を使用します。ルーターはサービスの IP アドレスに関連の変更がないかを検出して、その設定に合わせて変化します。これは、カスタムルーターが API オブジェクトの変更を外部のルーティングソリューションに通信できるので、便利です。

要求のパスは、1 つまたは複数のルーターに対して、ホスト名の DNS を解決することから始まります。推奨の方法は、複数のルーターインスタンスでバックされる 1 つまたは複数の仮想 IP (VIP) アドレスを参照するワイルドカード DNS エントリーでクラウドドメインを定義する方法です。クラウドドメイン外の名前とアドレスを使用するルートには、個別の DNS エントリー設定が必要です。

VIP アドレスがルーターよりも少ない場合には、アドレス分のルーターが active で、残りは passive になります。passive ルーターは ホットスタンバイ ルーターとして知られています。たとえば、VIP アドレスが 2 つ、ルーターが 3 つの場合には、「active-active-passive」構成になります。ルーターの VIP 設定に関する詳細情報は、「高可用性」を参照してください。

ルートは、ルーターセット間で シャード化 されます。管理者は、クラスター全体でシャード化を設定し、ユーザーはプロジェクトに含まれる namespace にシャード化を設定できます。オペレーターは、シャード化すると、複数のルーターグループを定義できるようになります。このグループ内の各ルーターはトラフィックのサブネット 1 つにのみ対応できます。

OpenShift Container Platform ルーターは、外部のホスト名マッピングと、ルーターに区別情報を直接渡すプロトコルを使用して サービス エンドポイントの負荷分散を行います。ルーターは、送信先を判断できるように、プロトコルにホスト名が存在している必要があります。

ルータープラグインはデフォルトで、ホストポート 80 (HTTP) および 443 (HTTPS) にバインドできます。つまり、配置されていないと、これらのポートは使用されないので、ルーターはノードに配置されている必要があります。または、ルーターは、ROUTER_SERVICE_HTTP_PORT および ROUTER_SERVICE_HTTPS_PORT 環境変数を設定して、他のポートをリッスンするように設定してください。

ルーターは、ホストノードのポートにバインドされるので、ルーターがホストネットワークを使用している場合には (デフォルト)、各ノードに 1 つしかこれらのポートをリッスンするルーターを配置できません。クラスターネットワークは、全ルーターがクラスター内のすべての Pod にアクセスできるように設定します。

ルーターは以下のプロトコルをサポートします。

  • HTTP
  • HTTPS (SNI あり)
  • WebSockets
  • SNI 付きの TLS
注記

WebSocket トラフィックは、同じルート規則を使用し、他のトラフィックと同じ TLS 終端タイプをサポートします。

セキュアな接続を確立するには、クライアントとサーバーに共通する 暗号化 を取り決める必要があります。時間が経つにつれ、よりセキュリティーの高く、新しい暗号化が利用でき、クライアントソフトウェアに統合されます。以前のクライアントは陳腐化し、セキュリティーの低い、以前の暗号化は使用が停止されます。デフォルトでは、ルーターは、一般的に入手できる、幅広いクライアントに対応します。ルーターは、任意のクライアントをサポートする暗号化の中で選択したものを使用し、セキュリティーが低い暗号化を使用しないように設定できます。

5.7.2.1. テンプレートルーター

テンプレートルーター は、ルーターの一種で、特定のインフラストラクチャー情報を基盤のルーター実装に提供します。以下に例を示します。

  • エンドポイントおよびルートを監視するラッパーです。
  • 消費可能なフォームに保存されるエンドポイントとルートデータ。
  • 内部の状態を設定可能なテンプレートに渡し、テンプレートを実行します。
  • 再ロードスクリプトを呼び出します。

5.7.3. 利用可能なルータープラグイン

検証された利用可能なルータープラグインについては、「利用可能なプラグイン」のセクションを参照してください。

これらのルーターのデプロイ方法については、「ルーターのデプロイ」を参照してください。

5.7.4. スティッキーセッション

スティッキーセッションの実装は、基盤のルーター設定により異なります。デフォルトの HAProxy テンプレートは、balance source ディレクティブを使用してスティッキーセッションを実装し、ソース IP をもとに分散されます。さらに、このテンプレートルータープラグインは、サービス名と namespace を基盤の実装に渡します。これは、ピア間で同期させるスティックテーブルの実装など、より高度な設定に使用できます。

スティッキーセッションは、ユーザー体験の向上のため、ユーザーのセッションからの全トラフィックが確実に同じ Pod に移動されるようにします。ユーザーの要求を満たしながら、Pod は後続の要求で使用できるように、データをキャッシュします。たとえば、バックエンド Pod が 5 つと負荷分散ルーターが 2 つあるクラスターでは、要求を処理するルーターがどれであっても、同じ Pod で、同じ Web ブラウザーからの web トラフィックを受信できるように確保できます。

ルーティングトラフィックを同じ Pod に返すことが望まれる場合でも、保証はできませんが、HTTP ヘッダーを使用して、cookie を設定し、最後の接続で使用した Pod を判断できます。ユーザーがアプリケーに別の要求を送信した場合には、ブラウザーが cookie を再送することで、ルーターでトラフィックの送信先が分かります。

クラスター管理者は、スティッキネスをオフにして、他の接続とパススルールートを分割することも、完全にスティッキネスをオフにすることもできます。

デフォルトでは、パススルールートのスティッキーセッションは、source 「負荷分散ストラテジー」を使用して実装します。すべてのパスルート用には、ROUTER_TCP_BALANCE_SCHEME 「環境変数」で、個別ルート用には、haproxy.router.openshift.io/balance 「ルート固有のアノテーション」で、デフォルトを変更することができます。

他の種類のルートはデフォルトで leastconn 「負荷分散ストラテジー」を使用しますが、これは ROUTER_LOAD_BALANCE_ALGORITHM 「環境変数」を使用して変更できます。また、個別ルートにはhaproxy.router.openshift.io/balance 「ルート固有のアノテーション」を使用して変更することができます。

注記

cookie は、HTTP トラフィックを表示できないので、パススルールートで設定できません。代わりに、ソース IP アドレスをベースに数が計算され、バックエンドを判断します。

バックエンドが変わった場合には、トラフィックは誤ったサーバーに送られ、スティッキネスが低くなります。ロードバランサーを使用する場合は (ソース IP が表示されない)、同じ番号が全接続に設定され、トラフィックが同じ Pod に送信されます。

さらに、このテンプレートルータープラグインは、サービス名と namespace を基盤の実装に渡します。これは、ピア間で同期させるスティックテーブルの実装など、より高度な設定に使用できます。

このルーター実装固有の設定は、ルーターコンテナーの /var/lib/haproxy/conf ディレクトリーにある haproxy-config.template ファイルに保存されます。ファイルは「カスタマイズ可能です」

注記

source負荷分散ストラテジー は、NAT の設定が原因で、外部のクライアント IP アドレスを区別しないので、送信元の IP アドレス (HAProxy リモート) は同じです。HAProxy ルーターが hostNetwork: true で実行されない限り、すべての外部クライアントは単一の Pod にルーティングされます。

5.7.5. ルーターの環境変数

このセクションで説明されているアイテムはすべて、ルーターの デプロイメント設定 に環境変数を指定して設定を変更するか、oc set env コマンドを使用します。

$ oc set env <object_type>/<object_name> KEY1=VALUE1 KEY2=VALUE2

以下に例を示します。

$ oc set env dc/router ROUTER_SYSLOG_ADDRESS=127.0.0.1 ROUTER_LOG_LEVEL=debug

表5.2 ルーターの環境変数

変数デフォルト説明

DEFAULT_CERTIFICATE

 

TLS サーバー証明書を公開しないルートに使用するデフォルトの証明書の内容。PEM 形式。

DEFAULT_CERTIFICATE_DIR

 

tls.crt というファイルを含むディレクトリーへのパス。tls.crt が PEM ファイルでなく、秘密鍵も含む場合には、同じディレクトリー内の tls.key というファイルと先に統合されます。PEM 形式のコンテンツは、デフォルトの証明書として使用されます。これは、DEFAULT_CERTIFICATE または DEFAULT_CERTIFICATE_PATH が指定されていない場合のみ使用されます。

DEFAULT_CERTIFICATE_PATH

 

TLS サーバー証明書を公開しないルートに使用するデフォルト証明書へのパス。PEM 形式。DEFAULT_CERTIFICATE が指定されていない場合のみ使用されます。

DROP_SYN_DURING_RESTART

false

true に設定されている場合は、iptables ルールを有効にして、再起動中に特定のパケットをドロップして、シームレスに再起動できるようにします。詳細は、『インストールガイド』を参照してください。

EXTENDED_VALIDATION

true

true の場合は、ルーターにより、証明書が構造的に正しいことを確認します。CA に対して証明書は検証されません。テストをオフにするには、false に設定します。

NAMESPACE_LABELS

 

監視する namespace に適用するラベルセレクターです。空はすべてを意味します。

PROJECT_LABELS

 

監視するプロジェクトに適用するラベルセレクターです。空はすべてを意味します。

RELOAD_SCRIPT

 

ルーターを再ロードするために使用する再ロードスクリプトのパスです。

ROUTER_ALLOWED_DOMAINS

 

ルートのホスト名のみを含めることができるドメインのコンマ区切りの一覧。ドメインに含まれるサブドメインを使用できます。ROUTER_DENIED_DOMAINS オプションは、このオプションに指定されている値を上書きします。これが設定されている場合は、許可されているドメイン以外はすべて拒否されます。

ROUTER_BACKEND_PROCESS_ENDPOINTS

 

テンプレート関数 processEndpointsForAlias の使用時にエンドポイントをどのように処理すべきかを指定する文字列。有効な値は ["shuffle", ""] です。"shuffle" は、全呼び出し毎に要素を無作為に決定します。デフォルトの動作は、事前に決定した順番に、値が返されます。

ROUTER_BIND_PORTS_AFTER_SYNC

false

true または TRUE に設定されている場合には、ルーターは、完全な同期状態になるまでポートにバインドされません。'true' または 'TRUE' に設定されていない場合は、ルーターはポートにバインドされ、即座に要求処理を開始しますが、ルートで読み込まれないものもあります。

ROUTER_COOKIE_NAME

 

cookie 名を指定して、内部で生成したデフォルト名を上書きします。名前は、大文字、小文字、数字、"_" または "-" を任意に組み合わせて指定する必要があります。デフォルトは、ルートのハッシュ化された内部キー名です。

ROUTER_COMPRESSION_MIME

"text/html text/plain text/css"

圧縮するスペースで区切られた mime タイプの一覧です。

ROUTER_DENIED_DOMAINS

 

ルートのホスト名に含めることができないドメインのコンマ区切りの一覧。ドメインに含まれるサブドメインを使用できません。ROUTER_ALLOWED_DOMAINS オプションを上書きします。

ROUTER_ENABLE_COMPRESSION

 

true または TRUE の場合、可能な場合には応答を圧縮します。

ROUTER_LISTEN_ADDR

0.0.0.0:1936

ルーターメトリクスのリッスンアドレスを設定します。

ROUTER_LOG_LEVEL

警告

syslog サーバーに送信するログレベルです。

ROUTER_MAX_CONNECTIONS

20000

同時接続の最大数です。

ROUTER_METRICS_HAPROXY_SERVER_THRESHOLD

500

 

ROUTER_METRICS_HAPROXY_EXPORTED

 

CSV 形式で収集されるメトリクスです。例: defaultSelectedMetrics = []int{2, 4, 5, 7, 8, 9, 13, 14, 17, 21, 24, 33, 35, 40, 43, 60}

ROUTER_METRICS_HAPROXY_BASE_SCRAPE_INTERVAL

5s

 

ROUTER_METRICS_HAPROXY_TIMEOUT

5s

 

ROUTER_METRICS_TYPE

haproxy

HAProxy ルーターのメトリクスを生成します (haproxy のみがサポートされている値です)。

ROUTER_OVERRIDE_DOMAINS

 

コンマ区切りのドメイン名リスト。ルーターのドメイン名がルートのホストと一致する場合には、ホスト名は無視され、ROUTER_SUBDOMAIN に定義されているパターンが使用されます。

ROUTER_OVERRIDE_HOSTNAME

 

true に設定されている場合、ROUTER_SUBDOMAIN のテンプレートのあるルートの spec.host 値を上書きします。

ROUTER_SERVICE_HTTPS_PORT

443

HTTPS 要求をリッスンするポートです。

ROUTER_SERVICE_HTTP_PORT

80

HTTP 要求をリッスンするポートです。

ROUTER_SERVICE_NAME

パブリック

ルーターがルートステータスで自らを識別する名前です。

ROUTER_CANONICAL_HOSTNAME

 

ルーターステータスに表示されるルーターの (オプションの) ホスト名です。

ROUTER_SERVICE_NAMESPACE

 

ルーターがルーターステータスで自らを識別する namespace です。ROUTER_SERVICE_NAME が使用されている場合は必須です。

ROUTER_SERVICE_NO_SNI_PORT

10443

一部のフロントエンドからバックエンドへの通信に使用される内部ポートです (以下を参照してください)。

ROUTER_SERVICE_SNI_PORT

10444

一部のフロントエンドからバックエンドへの通信に使用される内部ポートです (以下を参照してください)。

ROUTER_SUBDOMAIN

 

spec.host なしでルートのホスト名を生成するために使用されるテンプレートです (例: ${name}-${namespace}.myapps.mycompany.com)。

ROUTER_SYSLOG_ADDRESS

 

ログメッセージを送信するアドレスです。空の場合は無効になります。

ROUTER_SYSLOG_FORMAT

 

設定されている場合は、基盤のルーター実装で使用されるデフォルトのログ形式が上書きされます。この値は、基盤のルーター実装の仕様に従う必要があります。

ROUTER_TCP_BALANCE_SCHEME

ソース

パススルールートを行うための複数のエンドポイント用「負荷分散ストラテジー」。利用可能なオプションは sourceroundrobin または leastconn です。

ROUTER_LOAD_BALANCE_ALGORITHM

leastconn

複数のエンドポイントを持つルート用の「負荷分散エンドポイント」。利用可能なオプションは、sourceroundrobin および leastconn です。

ROUTE_LABELS

 

監視するルートに適用するラベルセレクターです。何も指定しない場合はすべてを意味します。

STATS_PASSWORD

 

ルーターの統計にアクセスするのに必要なパスワード (ルーターの実装がサポートする場合)

STATS_PORT

 

統計を公開するポート (ルーターの実装がサポートする場合)。設定されていない場合は統計は公開されません。

STATS_USERNAME

 

ルーターの統計にアクセスするために必要なユーザー名 (ルーターの実装がこれをサポートしている場合)。

TEMPLATE_FILE

/var/lib/haproxy/conf/custom/ haproxy-config-custom.template

HAProxy テンプレートへのパス (コンテナーイメージ内)。

ROUTER_USE_PROXY_PROTOCOL

 

true または TRUE に設定されている場合には、HAProxy は受信接続がポート 80 と 443 上で PROXY プロトコルを使用していることを想定します。ソース IP アドレスは、ロードバランサーが Amazon ELB などのプロトコルをサポートする場合には、ロードバランサーをパススルーすることができます。

ROUTER_ALLOW_WILDCARD_ROUTES

 

true または TRUE が設定されている場合には、ルーターの受付チェックを合格するという Subdomain のワイルドカードポリシーが指定されたルートは、HAProxy ルーターがサービスを提供します。

ROUTER_DISABLE_NAMESPACE_OWNERSHIP_CHECK

 

namespace 所有権ポリシーを緩和するために true に設定されます。

ROUTER_STRICT_SNI

 

strict-sni

ROUTER_CIPHERS

intermediate

バインドでサポートされる暗号のセットを指定します。

注記

同じマシンで複数のルーターを実行する場合には、ルーターがリッスンするポート (ROUTER_SERVICE_SNI_PORT および ROUTER_SERVICE_NO_SNI_PORT) を変更する必要があります。これらのポートは、マシン上で一意であれば、何でも指定できます。また、これらのポートは外部には公開されません。

ルータータイムアウト変数

TimeUnits は数字、その後に単位を指定して表現します。us *(マイクロ秒)、ms (ミリ秒、デフォルト)、s (秒)、m (分)、h *(時間)、d (日)

正規表現: [1-9][0-9]*(us\|ms\|s\|m\|h\|d)

ROUTER_BACKEND_CHECK_INTERVAL

5000ms

バックエンドでの後続の liveness チェックの時間の長さ。

ROUTER_CLIENT_FIN_TIMEOUT

1s

クライアントがルートに接続する場合の TCP FIN タイムアウトの期間を制御します。接続切断のために送信された FIN が指定の時間内に応答されない場合には、HAProxy が接続を切断します。小さい値を設定し、ルーターでリソースをあまり使用していない場合には、リスクはありません。

ROUTER_DEFAULT_CLIENT_TIMEOUT

30s

クライアントがデータを確認するか、送信するための時間の長さ。

ROUTER_DEFAULT_CONNECT_TIMEOUT

5s

最大接続時間。

ROUTER_DEFAULT_SERVER_FIN_TIMEOUT

1s

ルーターからルートをバッキングする Pod の TCP FIN タイムアウトを制御します。

ROUTER_DEFAULT_SERVER_TIMEOUT

30s

サーバーがデータを確認するか、送信するための時間の長さ。

ROUTER_DEFAULT_TUNNEL_TIMEOUT

1h

TCP または WebSocket 接続が開放された状態で保つ時間数。websockets/tcp 接続がある場合 (および HAProxy が再読み込みされる度) に、以前の HAProxy プロセスが指定された時間分、開放された状態に保たれます。

ROUTER_SLOWLORIS_HTTP_KEEPALIVE

300s

新しい HTTP 要求が表示されるまで待機する最大時間を設定します。この値が低すぎる場合には、ブラウザーおよびアプリケーションの keepalive 値が低くなりすぎて、問題が発生する可能性があります。詳しい情報は以下の注記セクションを参照してください。

ROUTER_SLOWLORIS_TIMEOUT

10s

HTTP 要求の伝送にかかる時間。

RELOAD_INTERVAL

5s

新規の変更を許可するためにルーターの再ロードが許可される最小の頻度。

ROUTER_METRICS_HAPROXY_TIMEOUT

5s

HAProxy メトリクスの収集タイムアウト。

注記

有効なタイムアウト値には、想定した個別のタイムアウトではなく、特定の変数を合計した値に指定することができます。

例: ROUTER_SLOWLORIS_HTTP_KEEPALIVEtimeout http-keep-alive を調節し、デフォルトで 300s に設定されていますが、haproxy は tcp-request inspect-delay も待機し、値は 5s に設定されているので、今回の場合には、合計のタイムアウトは 300s5s を加えた値になります。

5.7.6. ロードバランシングストラテジー

ルートに複数のエンドポイントがある場合には、HAProxy は選択した負荷分散ストラテジーをもとに、エンドポイント間に要求を分散します。これは、セッションの最初の要求など、永続情報が利用できない場合に適用されます。

ストラテジーには以下のいずれか使用できます。

  • roundrobin: 各エンドポイントは、加重に従い、順番に使用されます。これは、サーバーの処理が均等に分散される場合に最もスムーズで公平なアルゴリズムです。
  • leastconn: 接続数が最も少ないエンドポイントが要求を受信します。接続数が最も少ないエンドポイントが複数ある場合には、ラウンドロビンが実行されます。LDAP、SQL、TSE など、セッションが非常に長い場合にこのアルゴリズムを使用してください。HTTP など、短いセッションを通常使用するプロトコルでの使用を目的とはしていません。
  • source: ソース IP アドレスは、ハッシュ化され、実行中サーバーの合計加重で分割されて、どのサーバーが要求を受信するか指定します。これにより、サーバーが終了/起動しない限り、同じクライアント IP アドレスは常に同じサーバーに到達します。実行中のサーバー数が変化したことで、ハッシュの結果が変化した場合には、多くのクライアントが異なるサーバーに転送されます。このアルゴリズムは一般的にパススルールートで使用されます。

ROUTER_TCP_BALANCE_SCHEME 環境変数 はパススルールートのデフォルトストラテジーを設定します。ROUTER_LOAD_BALANCE_ALGORITHM 環境変数 は、残りのルートに対してルーターのデフォルトストラテジーを設定します。ルート固有のアノテーションhaproxy.router.openshift.io/balance を使用して、個別のルートを制御できます。

5.7.7. HAProxy Strict SNI

デフォルトでは、ホストは HTTPS または TLS SNI 要求のルートを解決しないので、デフォルト証明書が 503 応答の一部として、呼び出し元に返されます。これにより、デフォルト証明書が公開され、不正な証明書がサイトに提供されるので、セキュリティーの問題を引き起こす可能性があります。バインド用の HAProxy strict-sni オプションを使用するとデフォルト証明書の使用が抑制されます。

ROUTER_STRICT_SNI 環境変数はバインド処理を制御します。true または TRUE に設定されている場合には、strict-sni が HAProxy バインドに追加されます。デフォルト設定は false です。

このオプションは、ルーターの作成時または後の追加時に設定できます。

$ oc adm router --strict-sni

これは、ROUTER_STRICT_SNI=true を設定できます。

5.7.8. ルーターの暗号スイート

各クライアント (例: Chrome 30 または Java8) には、ルーターにセキュアに接続するために使用する暗号スイートが含まれます。ルーターには、接続を完了させるには、暗号化が最低でも 1 つ必要です。

表5.3 ルーター暗号プロファイル

プロファイル互換性のある最も古いクライアント

modern

Firefox 27, Chrome 30, IE 11 on Windows 7, Edge, Opera 17, Safari 9, Android 5.0, Java 8

intermediate

Firefox 1, Chrome 1, IE 7, Opera 5, Safari 1, Windows XP IE8, Android 2.3, Java 7

old

Windows XP IE6, Java 6

詳細は、Security/Server Side TLS リファレンスガイドを参照してください。

ルーターは intermediate プロファイルにデフォルト設定されています。ルートを作成する時または、既存のルーターの ROUTER_CIPHERSmodernintermediate または old に変更する時に、--ciphers オプションを使用して別のプロジェクトを選択します。または、":" 区切りで暗号化を指定することも可能です。暗号化は、以下のコマンドで表示されたセットの中から選択する必要があります。

openssl ciphers

5.7.9. ルートホスト名

OpenShift Container Platform ルートを使用してサービスと外部に到達可能なホスト名を関連付けることで、サービスを外部に公開することができます。このエッジホスト名は次に、サービスにトラフィックをルーティングするのに使用します。

異なる namespace から複数のルートが同じホストを要求する場合に、一番古いルートが優先され、その namespace にホストを獲得します。同じ namespace 内に、追加のルートが異なるパスフィールドで定義されている場合には、これらのパスが追加されます。複数のルートに同じパスが使用されている場合には、一番古いものが優先されます。

あるユーザーがホスト名にルート 2 つ (1 つが新しく、1 が古い) を指定しようとしていると仮定します。このユーザーがホスト名に他の 2 つのルートを指定する前に、別のユーザーが同じホスト名にルートを指定したうえに、元のユーザーにより作成済みのルートが削除された場合に、このホスト名への要求は効果がなくなります。他の namespace がこのホスト名を要求し、最初のユーザーの要求はなくなります。

例5.1 指定されたホストを持つルート:

apiVersion: v1
kind: Route
metadata:
  name: host-route
spec:
  host: www.example.com  1
  to:
    kind: Service
    name: service-name
1
サービスを公開するために使用される外部から到達可能なホスト名を指定します。

例5.2 ホスト内のルート:

apiVersion: v1
kind: Route
metadata:
  name: no-route-hostname
spec:
  to:
    kind: Service
    name: service-name

ホスト名がルート定義の一部として指定されていない場合には、OpenShift Container Platform が自動的に生成します。生成されたホスト名は以下のような形式をとります。

<route-name>[-<namespace>].<suffix>

以下の例では、namespace mynamespace にホストを追加せずに、上記のルート設定に対して OpenShift Container Platform が生成したホスト名を示します。

例5.3 生成されるホスト名

no-route-hostname-mynamespace.router.default.svc.cluster.local 1
1
生成されたホスト名のサフィックスは、デフォルトのルーティングサブドメイン router.default.svc.cluster.local です。

クラスター管理者は、環境に合わせて「デフォルトのルーティングサブドメインとして使用するサフィックスをカスタマイズ」することもできます。

5.7.10. ルートタイプ

ルートにセキュリティーを設定してもしなくても構いません。セキュアなルートは、複数の TLS 終端タイプを使用してクライアントに証明書を提供できます。ルーターは、edgepassthrough および re-encryption 終端をサポートします。

例5.4 セキュリティー保護されていないルートオブジェクト YAML 定義

apiVersion: v1
kind: Route
metadata:
  name: route-unsecured
spec:
  host: www.example.com
  to:
    kind: Service
    name: service-name

セキュリティー保護されていないルートは、鍵や証明書が必要でないので、設定が最も単純ですが、セキュリティー保護されているルートは、接続を非公開のままにできるのでセキュリティーを確保できます。

Secured ルートは、ルートの TLS 終端が指定されたルートです。利用可能な終端タイプは、以下で説明されています

5.7.10.1. パスベースのルート

パスベースのルートは、同じホスト名で、それぞれ異なるパスを使用して複数のルートにサービスを提供できるように、URL と比較可能なパスコンポーネントを指定します (ルートのトラフィックが HTTP ベースでなければならない)。ルーターは、最も限定的なものから順に、ルートを照合する必要がありますが、これはルーターの実装により左右されます。ホスト名とパスは、正常に要求に応答できるように、バックエンドサーバーにパススルーされます。たとえば、http://example.com/foo/ への要求がルーターに移動すると、Pod に http://example.com/foo/ への要求が表示されます。

以下の表は、ルートのサンプルおよびそれらのアクセシビリティーを示しています。

表5.4 ルートの可用性

ルート比較対象アクセス可能

www.example.com/test

www.example.com/test

Yes

www.example.com

No

www.example.com/test and www.example.com

www.example.com/test

Yes

www.example.com

Yes

www.example.com

www.example.com/test

はい (ルートではなく、ホストにマッチ)

www.example.com

Yes

例5.5 パスが 1 つでセキュリティー保護されていないルート

apiVersion: v1
kind: Route
metadata:
  name: route-unsecured
spec:
  host: www.example.com
  path: "/test"   1
  to:
    kind: Service
    name: service-name
1
パスは、パスベースのルートに唯一追加される属性です。
注記

ルーターは TLS を終了させず、要求のコンテンツを読み込みことができないので、パスベースのルーティングは、パススルー TLS を使用する場合には利用できません。

5.7.10.2. セキュリティー保護されたルート

セキュリティー保護されたルートは、ルートの TLS 終端を指定し、オプションで鍵と証明書を提供します。

注記

OpenShift Container Platform の TLS 終端は、カスタム証明書を提供する SNI に依存します。ポート 443 で受信する SNI 以外のトラフィックは、TLS 終端およびデフォルトの証明書で処理されます (要求のホスト名と一致せず、バリデーションエラーが発生する可能性があります)。

セキュリティー保護されたルートは、以下の 3 種類のセキュアな TLS 終端を使用できます。

Edge Termination

edge termination では、TLS 終端は、宛先にトラフィックをプロキシ化する前に、ルーターで発生します。TLS 証明書は、ルーターのフロントエンドで提供されるので、ルートに設定する必要があります。設定されていない場合には、「ルーターのデフォルトの証明書」が TLS 終端に使用されます。

例5.6 Edge Termination を使用したセキュリティー保護されたルート

apiVersion: v1
kind: Route
metadata:
  name: route-edge-secured 1
spec:
  host: www.example.com
  to:
    kind: Service
    name: service-name 2
  tls:
    termination: edge            3
    key: |-                      4
      -----BEGIN PRIVATE KEY-----
      [...]
      -----END PRIVATE KEY-----
    certificate: |-              5
      -----BEGIN CERTIFICATE-----
      [...]
      -----END CERTIFICATE-----
    caCertificate: |-            6
      -----BEGIN CERTIFICATE-----
      [...]
      -----END CERTIFICATE-----
1 2
オブジェクトの名前で、63 文字に制限されます。
3
termination フィールドは edge termination の edge です。
4
key フィールドは PEM 形式のキーファイルのコンテンツです。
5
certificate フィールドは PEM 形式の証明書ファイルのコンテンツです。
6
オプションの CA 証明書は、検証用に証明書チェーンを確立するために必要になる場合があります。

TLS がルーターで終端されるので、内部ネットワークを使用したルーターからエンドポイントへの接続は暗号化されません。

Edge termination ルートは insecureEdgeTerminationPolicy を指定して、セキュアでないスキーム (HTTP) 上にあるトラフィックを無効化、許可、リダイレクトすることができます。insecureEdgeTerminationPolicy で使用できる値は None または空 (無効化する場合)、Allow または Redirect です。デフォルトの insecureEdgeTerminationPolicy は、セキュアでないスキーム上のトラフィックを無効にします。一般的なユースケースは、セキュアなスキームを使用してコンテンツを、セキュアでないスキームを使用してアセット (例のイメージ、スタイルシート、javascript) を提供できるようにします。

例5.7 Edge Termination を使用したセキュリティー保護されたルートでの HTTP トラフィックの許可

apiVersion: v1
kind: Route
metadata:
  name: route-edge-secured-allow-insecure 1
spec:
  host: www.example.com
  to:
    kind: Service
    name: service-name 2
  tls:
    termination:                   edge   3
    insecureEdgeTerminationPolicy: Allow  4
    [ ... ]
1 2
オブジェクトの名前で、63 文字に制限されます。
3
termination フィールドは edge termination の edge です。
4
セキュアでないスキーム HTTP で送信される要求を許可するセキュアでないポリシー

例5.8 Edge Termination を使用したセキュリティー保護されたルートでの HTTP トラフィックのリダイレクト

apiVersion: v1
kind: Route
metadata:
  name: route-edge-secured-redirect-insecure 1
spec:
  host: www.example.com
  to:
    kind: Service
    name: service-name 2
  tls:
    termination:                   edge      3
    insecureEdgeTerminationPolicy: Redirect  4
    [ ... ]
1 2
オブジェクトの名前で、63 文字に制限されます。
3
termination フィールドは edge termination の edge です。
4
セキュアでないスキーム HTTP で送信される要求をセキュアなスキーム HTTPS にリダイレクトするセキュアでないポリシー

パススルーの停止

passthrough termination では、暗号化されたトラフィックが TLS 終端を提供するルーターなしに宛先に直接送信されます。そのため、鍵や証明書は必要ありません。

例5.9 パススルーの停止を使用したセキュリティー保護されたルート

apiVersion: v1
kind: Route
metadata:
  name: route-passthrough-secured 1
spec:
  host: www.example.com
  to:
    kind: Service
    name: service-name 2
  tls:
    termination: passthrough     3
1 2
オブジェクトの名前で、63 文字に制限されます。
3
termination フィールド passthrough に設定します。他の暗号化フィールドは必要ありません。

宛先 Pod は、エンドポイントでトラフィックに証明書を提供します。これは、必須となるクライアント証明書をサポートするための唯一の方法です (相互認証とも呼ばれる)。

注記

Passthrough ルートには insecureEdgeTerminationPolicy を指定できます。唯一有効な値はNone (無効化する場合は空) または Redirect です。

Re-encryption の停止

Re-encryption は、edge termination の一種で、ルーターが証明書を使用して TLS を終端し、異なる証明書が設定されている可能性のあるエンドポイントへの接続を再暗号化します。そのため、内部ネットワーなどを含め、接続の全パスが暗号化されています。 ルーターは、ヘルスチェックを使用して、ホストの信頼性を判断します。

例5.10 Re-Encrypt の停止を使用したセキュリティー保護されたルート

apiVersion: v1
kind: Route
metadata:
  name: route-pt-secured 1
spec:
  host: www.example.com
  to:
    kind: Service
    name: service-name 2
  tls:
    termination: reencrypt        3
    key: [as in edge termination]
    certificate: [as in edge termination]
    caCertificate: [as in edge termination]
    destinationCACertificate: |-  4
      -----BEGIN CERTIFICATE-----
      [...]
      -----END CERTIFICATE-----
1 2
オブジェクトの名前で、63 文字に制限されます。
3
termination フィールドは reencrypt に設定あれます。他のフィールドは edge termination の場合と同じです。
4
re-encryption には必須です。destinationCACertificate は、エンドポイント証明書を検証する CA 証明書を指定して、ルーターから宛先 Pod への接続のセキュリティーを確保します。サービスがサービス署名証明書を使用する場合または、管理者がデフォルトの CA 証明書をルーターに指定し、サービスにその CA により署名された証明書がある場合には、このフィールドは省略可能です。

destinationCACertificate フィールドが空の場合は、ルーターは自動的に証明書を提供するサービス用に生成される証明局を自動的に活用し、すべての Pod に /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt として注入します。これにより、ルートの証明書を生成する必要なしに、新しいルートがエンドツーエンドの暗号化を活用できるようになります。これは、管理者が許可しない限り、destinationCACertificate が使用できない、カスタムのルーターまたは F5 ルーターの場合に有用です。

注記

Re-encrypt ルートでは insecureEdgeTerminationPolicy に、edge termination ルートと同じ値にすべて指定することができます。

5.7.11. ルーターのシャード化

OpenShift Container Platform では、各ルートは metadata フィールドにいくつでも「labels」を指定できます。ルーターは selectors (選択式 とも呼ばれる) を使用して、サービスを提供するルートの全プールからルートのサブセットを選択します。選択式でも、ルートの namespace でラベルを使用できます。選択したルートは、ルーターのシャード を形成します。ルートと分けて、ルーターシャードだけを「作成」して、「変更」できます。

この設計では、従来の シャード化も、重複 シャード化をサポートします。従来のシャード化では、選択した内容が重複セットにならず、ルートはシャード 1 つのみに所属します。重複シャード化では、選択した内容は重複セットに含まれ、ルートは多数の異なるシャードに所属できます。たとえば、あるルートは SLA=high シャード (SLA=medium または SLA=low シャードではない) や geo=west シャード (geo=east シャードではない)に所属することができます。

重複シャード化の他の例には、ルートの namespace をベースに選択するルーターセットなどがあります。

ルーター選択Namespace

router-1

A* — J*

A*, B*, C*, D*, E*, F*, G*, H*, I*, J*

router-2

K* — T*

K*, L*, M*, N*, O*, P*, Q*, R*, S*, T*

router-3

Q* — Z*

Q*, R*, S*, T*, U*, V*, W*, X*, Y*, Z*

router-2 および router-3 は、namespaces Q*R*S*T* のルートにサービスを提供します。この例を重複から従来のシャード化に変更するには、router-2 の選択肢を K* — P* に変更して、重複をなくすことができます。

ルートがシャード化されている場合には、指定のルートはこのグループのルーター 0 個以上にバインドされます。ルートをバインドすることで、シャード全体でルートを一意に保つことができます。一意に保つことで、単一のシャード内に、同じルートでもセキュアなバージョンと、セキュアでないバージョンを存在させることができます。つまり、ルートは、作成、バインド、アクティブ化のライフサイクルが可視化されたことになります。

シャード化の環境では、シャードに到達する最初のルートが再起動の有無に拘わらず、期限なしに存在できる権利を持ちます。

green/blue デプロイメント時には、ルートは複数のルーターに選択される場合があります。OpenShift Container Platform のアプリケーション管理者は、別のバージョンのアプリケーションにトラフィックをフラッシュして、以前のバージョンをオフに設定する場合があります。

シャーディングは、管理者によりクラスターレベルで、ユーザーにより、プロジェクト/namespace レベルで実行できます。namespace ラベルを使用する場合には、ルーターのサービスアカウントには、 cluster-reader パーミッションを設定して、ルーターが namespace 内のラベルにアクセスできるようにします。

注記

同じホスト名を要求するルートが 2 つ以上ある場合には、解決する順番は、ルートの存在期間をもとにし、一番古いルートがホストの要求を優先的に取得します。シャード化されたルーターの場合には、ルートは、ルーターの選択基準にあったラベルをベースに選択されます。ラベルがルートに追加されるタイミングを判断する方法に一貫性はありません。そのため、既存のホスト名を要求する以前のルートが「再度ラベル化されて」、ルーターの選択基準と照合させる場合には、上述の解決順に基づき既存のルートを置き換えます (最も古いルートが優先される)。

5.7.12. 他のバックエンドおよび重み

ルートは通常、kind: Serviceto: トークンを使用したサービスと関連付けられます。ルートへの全要求は、「負荷分散ストラテジー」をベースに、サービス内のエンドポイントにより処理されます。

サービスは最大 4 つまでルートをサポートすることができます。各サービスが処理する要求の大きさは、サービスの weight により統制されます。

最初のサービスは、以前と同様に to: トークンを使用して入り、サービスは 3 つまで alternateBackend: トークンを使用して入ることができます。各サービスは、デフォルトの kind: Service が指定されている必要があります。

各サービスには、weight が関連付けられています。サービスが処理する要求の大きさは、weight / sum_of_all_weights で算出されます。サービスにエンドポイントが複数ある場合には、サービスの加重が 1 以上、各エンドポイントに割り当てられるように、エンドポイント全体に分散されます。サービスの weight が 0 の場合は、サービスの各エンドポイントには 0 が割り当てられます。

weight は、0-256 の範囲内で指定してください。デフォルトは 1 です。weight が 0 の場合は、サービスに要求は渡されません。全サービスの weight が 0 の場合は、要求に対して 503 エラーが返されます。サービスにエンドポイントがない場合には、加重は実際には 0 となります。

alternateBackends を使用すると、roundrobin 負荷分散ストラテジーを使用して、要求が想定どおりに weight をもとにサービスに分散されるようになります。ルートに roundrobin を設定する場合は、「ルートアノテーション」を使用するか、一般的なルーターには環境変数を使用します。

以下は、「A/B デプロイメント」向けに別のバックエンドを使用したルート設定例です。

alternateBackends および加重が指定されたルート

apiVersion: v1
kind: Route
metadata:
  name: route-alternate-service
  annotations:
    haproxy.router.openshift.io/balance: roundrobin  1
spec:
  host: www.example.com
  to:
    kind: Service
    name: service-name  2
    weight: 20          3
  alternateBackends:
  - kind: Service
    name: service-name2 4
    weight: 10          5
    kind: Service
    name: service-name3 6
    weight: 10          7

1
このルートはroundrobin 「負荷分散ストラテジー」を使用します。
2
最初のサービス名は service-name であり、0 以上の Pod が含まれる可能性があります。
4 6
alternateBackend サービスにも 0 以上の Pod が含まれる場合があります。
3 5 7
weight の合計は 40 で、service-name は要求の 20/40 または 1/2を、service-name2service-name3 はそれぞれ、要求の 1/4 を取得し、サービス毎に 1 または複数のエンドポイントが含まれると想定します。

== ルート固有のアノテーション

環境変数を使用して、ルーターは、公開する全ルートにデフォルトオプションを設定できます。個別のルートは、アノテーションに個別の設定を指定して、デフォルトの一部を上書きできます。

ルートアノテーション

このセクションで説明されているすべての項目について、ルートがその設定を変更できるように ルート定義 にアノテーションを設定できます。

表5.5 ルートアノテーション

変数説明デフォルトで使用される環境変数

haproxy.router.openshift.io/balance

ロードバランシングアルゴリズムを設定します。使用できるオプションは sourceroundrobin、および leastconn です。

passthrough ルートの ROUTER_TCP_BALANCE_SCHEME です。それ以外の場合は ROUTER_LOAD_BALANCE_ALGORITHM を使用します。

haproxy.router.openshift.io/disable_cookies

関連の接続を追跡する cookie の使用を無効にします。true または TRUE に設定する場合は、分散アルゴリズムを使用して、受信する HTTP 要求ごとに、どのバックエンドが接続を提供するかを選択します。

 

haproxy.router.openshift.io/cookie_name

このルートに使用するオプションの cookie を指定します。名前は、大文字、小文字、数字、"_" または "-" を任意に組み合わせて指定する必要があります。デフォルトは、ルートのハッシュ化された内部キー名です。

 

haproxy.router.openshift.io/pod-concurrent-connections

ルーターからバッキングされる Pod に対して許容される接続最大数を設定します。 注意: Pod が複数ある場合には、それぞれに対応する接続数を設定できますが、ルーターが複数ある場合には、ルーター間の連携がなく、それぞれの接続回数はルーターの数と同じとなります。設定されていない場合または 0 に設定されている場合には制限はありません。

 

haproxy.router.openshift.io/rate-limit-connections

レート制限機能を有効にするために true または TRUE を設定します。

 

haproxy.router.openshift.io/rate-limit-connections.concurrent-tcp

IP アドレスで共有される同時 TCP 接続の数を制限します。

 

haproxy.router.openshift.io/rate-limit-connections.rate-http

IP アドレスが HTTP 要求を実行できるレートを制限します。

 

haproxy.router.openshift.io/rate-limit-connections.rate-tcp

IP アドレスが TCP 接続を行うレートを制限します。

 

haproxy.router.openshift.io/timeout

ルートのサーバー側のタイムアウトを設定します。(TimeUnits)

ROUTER_DEFAULT_SERVER_TIMEOUT

router.openshift.io/haproxy.health.check.interval

バックエンドのヘルスチェックの間隔を設定します。(TimeUnits)

ROUTER_BACKEND_CHECK_INTERVAL

haproxy.router.openshift.io/ip_whitelist

ルートのホワイトリストを設定します。

 

haproxy.router.openshift.io/hsts_header

edge terminated または re-encrypt ルートの Strick-Transport-Security ヘッダーを設定します。

 

例5.11 ルート設定のカスタムタイムアウト

apiVersion: v1
kind: Route
metadata:
  annotations:
    haproxy.router.openshift.io/timeout: 5500ms 1
[...]
1
HAProxy 対応の単位 (us、ms、s、m、h、d) で新規のタイムアウトを指定します。単位が指定されていない場合は、ms がデフォルトになります。
注記

passthrough ルートのサーバー側のタイムアウトを低く設定し過ぎると、WebSocket 接続がそのルートで頻繁にタイムアウトする可能性があります。

5.7.13. ルート固有の IP ホワイトリスト

選択した IP アドレスだけにルートへのアクセスを制限するには、ルートに haproxy.router.openshift.io/ip_whitelist アノテーションを追加します。ホワイトリストは、承認したソースアドレスの IP アドレスまたは/および CIDR をスペース区切りにします。ホワイトリストに含まれていない IP アドレスからの要求は破棄されます。

例:

ルートの編集時に、以下のアノテーションを追加して必要なソース IP を定義します。または、oc annotate route <name> を使用します。

唯一の特定の IP アドレスのみを許可します。

metadata:
  annotations:
    haproxy.router.openshift.io/ip_whitelist: 192.168.1.10

複数の IP アドレスを許可します。

metadata:
  annotations:
    haproxy.router.openshift.io/ip_whitelist: 192.168.1.10 192.168.1.11 192.168.1.12

IP CIDR ネットワークを許可します。

metadata:
  annotations:
    haproxy.router.openshift.io/ip_whitelist: 192.168.1.0/24

混在した IP アドレスおよび IP CIDR ネットワークを許可します。

metadata:
  annotations:
    haproxy.router.openshift.io/ip_whitelist: 180.5.61.153 192.168.1.0/24 10.0.0.0/8

5.7.14. ワイルドカードサブドメインポリシーを指定するルートの作成

ワイルドカードポリシーでは、(許可できるようにルーターを設定する場合) ドメイン内の全ホストに対応するルートを定義できます。ルートは、wildcardPolicy フィールドを使用して、設定の一部としてワイルドカードポリシーを指定できます。ワイルドカードルートを許可するポリシーが指定されたルーターは、ワイルドカードポリシーをもとに適切にルートを公開します。

「ワイルドカードルートを許可するように HAProxy ルートを設定する方法についてはこちら」を参照してください。

例5.12 サブドメインワイルドカードポリシーを指定するルート

apiVersion: v1
kind: Route
spec:
  host: wildcard.example.com  1
  wildcardPolicy: Subdomain   2
  to:
    kind: Service
    name: service-name
1
サービスを公開するために使用される外部から到達可能なホスト名を指定します。
2
外部から到達可能なホスト名は、サブドメイン example.com 内の全ホストを許可するように指定します。*.example.com は、公開されたサービスに到達するためのホスト名 wildcard.example.com のサブドメインです。

5.7.15. ルートステータス

route status フィールドは、ルーターでのみ設定されます。ルーターが特定のルーターへのサービス提供を停止するように、ルートに変更が加えられた場合には、スターテスが古くなってしまいますが、ルーターは、route status フィールドは消去しません。ルートステータスの以前のエントリーを削除するには、clear-route-status script を使用してください。

5.7.16. ルート内の特定ドメインの拒否または許可

ルーターは、ROUTER_DENIED_DOMAINS および ROUTER_ALLOWED_DOMAINS 環境変数を使用して、ルート内のホスト名からのドメインサブセットを限定して拒否または許可するように設定できます。

ROUTER_DENIED_DOMAINS

一覧表示されるドメインは指定のルートで許可されません。

ROUTER_ALLOWED_DOMAINS

一覧表示されるドメインのみが指定のルートで許可されます。

拒否ドメインの一覧に含まれるドメインは、許可ドメイン一覧よりも優先されます。つまり、OpenShift Container Platform は先に、拒否リスト (該当する場合) をチェックして、ホスト名が拒否ドメイン一覧に含まれていない場合に、許可ドメインをチェックします。ただし、許可ドメインの一覧はより制限されており、ルーターは、その一覧に所属するホストが含まれるルートのみを許可します。

たとえば、myrouter ルートの [*.]open.header.test[*.]openshift.org および [*.]block.it ルートを拒否するには、以下を実行します。

$ oc adm router myrouter ...
$ oc set env dc/myrouter ROUTER_DENIED_DOMAINS="open.header.test, openshift.org, block.it"

これは、myrouter がルートの名前に基づいて以下を許可することを意味します。

$ oc expose service/<name> --hostname="foo.header.test"
$ oc expose service/<name> --hostname="www.allow.it"
$ oc expose service/<name> --hostname="www.openshift.test"

ただし、myrouter は以下を拒否します。

$ oc expose service/<name> --hostname="open.header.test"
$ oc expose service/<name> --hostname="www.open.header.test"
$ oc expose service/<name> --hostname="block.it"
$ oc expose service/<name> --hostname="franco.baresi.block.it"
$ oc expose service/<name> --hostname="openshift.org"
$ oc expose service/<name> --hostname="api.openshift.org"

または、ホスト名が [*.]stickshift.org または [*.]kates.net に設定されて いない ルートをブロックするには、以下を実行します。

$ oc adm router myrouter ...
$ oc set env dc/myrouter ROUTER_ALLOWED_DOMAINS="stickshift.org, kates.net"

これは、myrouter ルートが以下を許可することを意味します。

$ oc expose service/<name> --hostname="stickshift.org"
$ oc expose service/<name> --hostname="www.stickshift.org"
$ oc expose service/<name> --hostname="kates.net"
$ oc expose service/<name> --hostname="api.kates.net"
$ oc expose service/<name> --hostname="erno.r.kube.kates.net"

ただし、myrouter は以下を拒否します。

$ oc expose service/<name> --hostname="www.open.header.test"
$ oc expose service/<name> --hostname="drive.ottomatic.org"
$ oc expose service/<name> --hostname="www.wayless.com"
$ oc expose service/<name> --hostname="www.deny.it"

両方のシナリオを実装するには、以下を実行します。

$ oc adm router adrouter ...
$ oc env dc/adrouter ROUTER_ALLOWED_DOMAINS="openshift.org, kates.net" \
    ROUTER_DENIED_DOMAINS="ops.openshift.org, metrics.kates.net"

これにより、ホスト名が [*.]openshift.org または [*.]kates.net に設定されているルートを許可し、ホスト名が [*.]ops.openshift.org または [*.]metrics.kates.net に設定されているルートは拒否します。

そのため、以下は拒否されます。

$ oc expose service/<name> --hostname="www.open.header.test"
$ oc expose service/<name> --hostname="ops.openshift.org"
$ oc expose service/<name> --hostname="log.ops.openshift.org"
$ oc expose service/<name> --hostname="www.block.it"
$ oc expose service/<name> --hostname="metrics.kates.net"
$ oc expose service/<name> --hostname="int.metrics.kates.net"

しかし、以下は許可されます。

$ oc expose service/<name> --hostname="openshift.org"
$ oc expose service/<name> --hostname="api.openshift.org"
$ oc expose service/<name> --hostname="m.api.openshift.org"
$ oc expose service/<name> --hostname="kates.net"
$ oc expose service/<name> --hostname="api.kates.net"

5.7.17. Kubernetes Ingress オブジェクトのサポート

Kubernetes Ingress オブジェクトは受信接続が内部サービスに到達する方法を判別する設定オブジェクトです。OpenShift Container Platform では OpenShift Container Platform のバージョン 3.10 より、Ingress コントローラー設定ファイルを使用したこれらのオブジェクトのサポートがあります。

コントローラーは、Ingress オブジェクトを監視して、1 つまたは複数のルートを作成し、Ingress オブジェクトの条件を満たします。コントローラーは、Ingress オブジェクトと、生成されたルートオブジェクトが常に同期されるようにします。たとえば、Ingress オブジェクトに関連付けられたシークレットで生成されたルートパーミッションを付与するなどです。

たとえば、以下のように設定された Ingress オブジェクトの場合:

kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: test
spec:
  rules:
  - host: test.com
    http:
     paths:
     - path: /test
       backend:
        serviceName: test-1
        servicePort: 80

以下のルートオブジェクトが生成されます。

kind: Route
apiVersion: route.openshift.io/v1
metadata:
  name: test-a34th 1
  ownerReferences:
  - apiVersion: extensions/v1beta1
    kind: Ingress
    name: test
    controller: true
spec:
  host: test.com
  path: /test
  to:
    name: test-1
  port:
     targetPort: 80
1
名前は、Ingress 名をプレフィックスとして使用して、ルートオブジェクトにより生成されます。
注記

ルートを作成するには、Ingress オブジェクトにホスト、サービス、パスが含まれる必要があります。

5.7.18. Namespace 所有権チェックの無効化

ホストとサブドメインは、最初に要求を作成したルートの namespace が所有します。その namespace で作成された他のルートは、サブドメイン上で要求を作成できます。他の namespace はすべて、請求済みのホストおよびサブドメインに要求を作成することはできません。ホストを所有する namespace は、www.abc.xyz/path1 など、そのホストに関連付けられている全パスも所有します。

たとえば、ホスト www.abc.xyz がどのルートからも要求されていない場合に、ns1 namespace にホストが www.abc.xyz のルート r1 を作成すると、ns1 の namespace が、ワイルドカードルートのホスト www.abc.xyz と サブドメイン abc.xyz を所有します。別の namespace ns2 が異なるパス www.abc.xyz/path1/path2 で、ルートを作成しようとすると、別の namespace (今回は ns1) のルートがこのホストを所有するので失敗してしまいます。

「ワイルドカードルート」では、サブドメインを所有する namespace はそのサブドメインに含まれるホストすべてを所有します。上記の例のように、namespace が abc.xyz というサブドメインを所有する場合には、別の namespace は z.abc.xyz を要求できません。

namespace の所有権ルールを無効にするには、これらの制限を無効にして、namespace すべてでホスト (およびサブドメイン) を要求できるようにします。

警告

ルーターで namespace の所有権チェックを無効にする場合には、エンドユーザーが namespace に含まれるホストの所有権を要求できるようになる点に注意してください。この設定の変更は、特定の開発環境で価値がありますが、実稼働環境では慎重にこの機能を使用し、クラスターポリシーで、信頼されないエンドユーザーがルートを作成できないようにロックしてください。

たとえば、 ROUTER_DISABLE_NAMESPACE_OWNERSHIP_CHECK=true では、namespace ns1 が最も古い r1 www.abc.xyz を作成する場合に、このホスト名 (+ パス) のみを所有します。別の namespace は、このサブドメイン (abc.xyz) に最も古いルートがなくても、ワイルドカードルートを作成することができ、別の namespace が (foo.abc.xyzbar.abc.xyzbaz.abc.xyz など) ワイルドカード以外の重複ホストを要求することも可能で、この要求は認められます。

別の namespace (例: ns2) はルート r2 www.abc.xyz/p1/p2 を作成でき、許可されます。同様に、別の namespace (ns3) は、サブドメインのワイルドカードポリシーでルート wildthing.abc.xyz も作成でき、このワイルドカードを所有できます。

この例にあるように、ポリシー ROUTER_DISABLE_NAMESPACE_OWNERSHIP_CHECK=true は制約がゆるく、namespace 全体の要求を許可します。ルーターが namespace の所有を無効にしているルートを許可できるのは、ホストとパスがすでに請求済みである場合だけです。

たとえば、新規ルート rxwww.abc.xyz/p1/p2 を要求しようとする場合に、ルート r2 はホストとパスの組み合わせを所有しているので拒否されます。まったく同じホストとパスがすでに請求済みなので、これは、ルート rx が同じ namespace にある場合も、別の namespace にある場合でも同じです。

この機能は、ルーターの作成時か、またはルーターのデプロイメント設定に環境変数を設定して設定できます。

$ oc adm router ... --disable-namespace-ownership-check=true
$ oc env dc/router ROUTER_DISABLE_NAMESPACE_OWNERSHIP_CHECK=true


[1] これ以降は、デバイス名は、コンテナー B のホストのデバイスを参照します。