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/23、10.128.2.0/23、10.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 は以下を行います。
- 対象の Pod に、ノードのクラスターサブネットから、空いている IP アドレスを割り当てます。
-
ホスト側の Pod の veth インターフェースペアを OVS ブリッジ
br0
に割り当てます。 - OpenFlow ルールを OVS データベースに追加して、新規の Pod にアドレス指定されたトラフィックを正しい OVS ポートにルーティングします。
- 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) → vethA → br0 → vethB → eth0 (B の netns)
次に、コンテナー A がローカルホストに、コンテナー B がクラスターネットワーク上のリモートホストにあると想定します。その場合には、コンテナー A からコンテナー B のパケットフローは以下のようになります。
eth0 (A の netns) → vethA → br0 → vxlan0 → ネットワーク [1] → vxlan0 → br0 → vethB → eth0 (B の netns)
最後に、コンテナー A が外部ホストに接続すると、トラフィックは以下のようになります。
eth0 (A の netns) → vethA → br0 → tun0 → (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 は、flannel を host-gw モードで実行し、コンテナー間のルートをマッピングします。ネットワーク内の各ホストは、flanneld と呼ばれるエージェントを実行します。このエージェントは以下を行います。
- ホスト毎に一意のサブネットを管理する
- ホスト上の各コンテナーに IP アドレスを割り当てる
- 別のホスト上であっても、コンテナー間のルートをマッピングする
各 flanneld エージェントは、この情報を中央の etcd ストアに提供し、ホスト上の他のエージェントがパケットを、flannel ネットワーク内の他のコンテナーにルーティングできるようにします。
以下の図は、flannel ネットワークを使用したコンテナー間のアーキテクチャーおよびデータフローを示します。
ノード 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 との統合
統合を行う固有のコンポーネントが 2 つあります。
- nuage-openshift-monitor サービス。OpenShift Container Platform マスターノードで個別のサービスとして実行されます。
- vsp-openshift プラグイン。クラスターの各ノードで OpenShift Container Platform ランタイムにより呼び出されます。
Nuage Virtual Routing and Switching ソフトウェア (VRS) は、オープンソースの Open vSwitch をベースにしており、データパス転送を行います。VRS は各ノードで実行され、コントローラーからポリシー設定を取得します。
Nuage VSP の用語
図5.2 Nuage VSP のビルディングブロック
- ドメイン: 組織には 1 つまたは複数のドメインが含まれます。ドメインは単一の「レイヤー 3」の領域を指します。標準のネットワーク用語では、ドメインは、VRF インスタンスと同じ位置づけです。
- ゾーン: ゾーンは、ドメインの配下に定義されます。ゾーンは、直接ネットワーク上のなにかにマッピングされるわけではなく、ゾーンの全エンドポイントが同じポリシーセットに準拠するなど、ポリシーが関連付けられているオブジェクトとして機能します。
- サブネット: サブネットはゾーンの配下に定義されます。サブネットは、ドメインインスタンス内の固有のレイヤー 2 サブネットを指します。サブネットは、ドメイン内で一意で他とは異なります。つまり、ドメイン内のサブネットは、重複したり、標準の IP サブネット定義に従って他のサブネットを含めたりすることもできません。
- VPorts: VPort は、ドメイン階層の新しいレベルで、より粒度の高い設定を可能にするために設計されました。コンテナーや VM に加え、ホストやブリッジインターフェースにアタッチには VPorts も使用し、ベアメタルサーバー、アプリケーション、レガシー VLAN に接続できるようにします。
- ポリシーグループ: ポリシーグループは VPorts のコレクションです。
コンストラクトのマッピング
OpenShift Container Platform のコンセプト の多くは、Nuage VSP のコンストラクトに直接マッピングできます。
図5.3 Nuage VSP および OpenShift Container Platform のマッピング
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 と統合します。
- nuage-openshift-monitor
- 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) は、CNI と OpenStack 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=1
の Deployment
としてモデル化されています。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 テンプレートルーターメトリクス
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 および要求パスで一致する unsecured、edge termination、re-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-IP は OpenShift 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 をベースにしてププールにルーティングするように設定する
いずれも scp
と ssh
コマンドを使用してカスタムの 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 コントローラー 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 アプライアンスの間でデータパスを正常に確立するには以下を行います。
- F5 は、Pod 向けの VxLAN パケットをカプセル化する必要があります。これには、sdn-services ライセンスアドオンが必要です。VxLAN デバイスを作成する必要があり、Pod オーバーレイネットワークはこのデバイス経由でルーティングする必要があります。
- F5 は Pod の VTEP IP アドレスを知る必要があります。これは、Pod が配置されているノードの IP アドレスです。
-
F5 は、Pod 向けのパケットをカプセル化する時に、オーバーレイネットワークに使用する
source-ip
を知っておく必要があります。これは ゲートウェイアドレス として知られています。 - OpenShift Container Platform ノードは、F5 ゲートウェイアドレスがなにか (戻りトラフィックの VTEP アドレス) を知っておく必要があります。このアドレスは、内部インターフェースのアドレスでなければなりません。クラスターの全ノードは、自動的にこれを学習する必要があります。
-
オーバーレイネットワークはマルチテナントに対応しているので、F5 は
admin
を代表する VxLAN ID を使用して F5 が全テナントに到達できるようにする必要があります。手動作成したhostsubnet
(pod.network.openshift.io/fixed-vnid-host: 0
) でアノテーションを指定することで、F5 によりvnid
が0
(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 アプライアンスによって実行されます。
- 宛先 Pod はパケットの F5 仮想サーバーで識別されます。
- VxLAN 動的 FDB は Pod の IP アドレスで検索されます。MAC アドレスが見つかる場合はステップ 5 に進みます。
- Pod の MAC アドレスを求める ARP 要求で、VTEP FDB の全エントリーをいっぱいにします。Pod の MAC アドレスと VTEP を値として使用して、VxLAN ダイナミック FDB にエントリーが追加されます。
- VxLAN ヘッダーで IP パケットをカプセル化します。Pod の MAC およびノードの VTEP が、VxLAN 動的 FDB からの値として指定されます。
- ARP を送信し、ホストの周辺にあるキャッシュを確認して、VTEP の MAC アドレスを計算します。
- F5 ホストの内部アドレスでパケットを送信します。
データフロー: トラフィックを F5 ホストに返す
以下のアクションは、ユーザーではなく F5 ルータープラグイン Pod および F5 アプライアンスによって実行されます。
- Pod は、宛先を F5 ホストの VxLAN ゲートウェイアドレスとしてパケットを戻します。
-
ノードの
openvswitch
は、このパケットの VTEP が F5 ホストの内部インターフェースアドレスであるかどうか判断します。これは、ghosthostsubnet
の作成時に分かります。 - 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 のポート間のデータをコピーします。ただし、カスタムの実装には、nsenter
と socat
のバイナリーをホストにインストールしなくていいように、これらのバイナリーを実行する「ヘルパー」 Pod の実行が含まれています。
5.6. リモートコマンド
5.6.1. 概要
OpenShift Container Platform は Kubernetes に内蔵されている機能を活用し、コンテナーでのコマンド実行をサポートします。これは、HTTP と SPDY または HTTP/2 などの多重化ストリーミングプロトコルを使用して実装されます。
開発者は「CLI を使用」して、コンテナーでリモートコマンドを実行します。
5.6.2. サーバー操作
Kubelet は、クライアントからのリモート実行要求を処理します。要求を受信すると応答をアップグレードして、要求ヘッダーを評価してどのストリーム (stdin
、stdout
および/または 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 ルーターの環境変数
変数 | デフォルト | 説明 |
---|---|---|
|
TLS サーバー証明書を公開しないルートに使用するデフォルトの証明書の内容。PEM 形式。 | |
|
tls.crt というファイルを含むディレクトリーへのパス。tls.crt が PEM ファイルでなく、秘密鍵も含む場合には、同じディレクトリー内の tls.key というファイルと先に統合されます。PEM 形式のコンテンツは、デフォルトの証明書として使用されます。これは、 | |
|
TLS サーバー証明書を公開しないルートに使用するデフォルト証明書へのパス。PEM 形式。 | |
|
|
|
|
|
|
|
監視する namespace に適用するラベルセレクターです。空はすべてを意味します。 | |
|
監視するプロジェクトに適用するラベルセレクターです。空はすべてを意味します。 | |
|
ルーターを再ロードするために使用する再ロードスクリプトのパスです。 | |
|
ルートのホスト名のみを含めることができるドメインのコンマ区切りの一覧。ドメインに含まれるサブドメインを使用できます。 | |
|
テンプレート関数 processEndpointsForAlias の使用時にエンドポイントをどのように処理すべきかを指定する文字列。有効な値は ["shuffle", ""] です。"shuffle" は、全呼び出し毎に要素を無作為に決定します。デフォルトの動作は、事前に決定した順番に、値が返されます。 | |
|
|
|
|
cookie 名を指定して、内部で生成したデフォルト名を上書きします。名前は、大文字、小文字、数字、"_" または "-" を任意に組み合わせて指定する必要があります。デフォルトは、ルートのハッシュ化された内部キー名です。 | |
|
"text/html text/plain text/css" |
圧縮するスペースで区切られた mime タイプの一覧です。 |
|
ルートのホスト名に含めることができないドメインのコンマ区切りの一覧。ドメインに含まれるサブドメインを使用できません。 | |
|
| |
|
0.0.0.0:1936 |
ルーターメトリクスのリッスンアドレスを設定します。 |
|
警告 |
syslog サーバーに送信するログレベルです。 |
|
20000 |
同時接続の最大数です。 |
|
500 | |
|
CSV 形式で収集されるメトリクスです。例: | |
|
5s | |
|
5s | |
|
haproxy |
HAProxy ルーターのメトリクスを生成します (haproxy のみがサポートされている値です)。 |
|
コンマ区切りのドメイン名リスト。ルーターのドメイン名がルートのホストと一致する場合には、ホスト名は無視され、 | |
|
| |
|
443 |
HTTPS 要求をリッスンするポートです。 |
|
80 |
HTTP 要求をリッスンするポートです。 |
|
パブリック |
ルーターがルートステータスで自らを識別する名前です。 |
|
ルーターステータスに表示されるルーターの (オプションの) ホスト名です。 | |
|
ルーターがルーターステータスで自らを識別する namespace です。 | |
|
10443 |
一部のフロントエンドからバックエンドへの通信に使用される内部ポートです (以下を参照してください)。 |
|
10444 |
一部のフロントエンドからバックエンドへの通信に使用される内部ポートです (以下を参照してください)。 |
|
spec.host なしでルートのホスト名を生成するために使用されるテンプレートです (例: ${name}-${namespace}.myapps.mycompany.com)。 | |
|
ログメッセージを送信するアドレスです。空の場合は無効になります。 | |
|
設定されている場合は、基盤のルーター実装で使用されるデフォルトのログ形式が上書きされます。この値は、基盤のルーター実装の仕様に従う必要があります。 | |
|
ソース |
パススルールートを行うための複数のエンドポイント用「負荷分散ストラテジー」。利用可能なオプションは |
|
leastconn |
複数のエンドポイントを持つルート用の「負荷分散エンドポイント」。利用可能なオプションは、 |
|
監視するルートに適用するラベルセレクターです。何も指定しない場合はすべてを意味します。 | |
|
ルーターの統計にアクセスするのに必要なパスワード (ルーターの実装がサポートする場合) | |
|
統計を公開するポート (ルーターの実装がサポートする場合)。設定されていない場合は統計は公開されません。 | |
|
ルーターの統計にアクセスするために必要なユーザー名 (ルーターの実装がこれをサポートしている場合)。 | |
|
|
HAProxy テンプレートへのパス (コンテナーイメージ内)。 |
|
| |
|
| |
|
namespace 所有権ポリシーを緩和するために | |
| ||
|
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)
|
5000ms |
バックエンドでの後続の liveness チェックの時間の長さ。 |
|
1s |
クライアントがルートに接続する場合の TCP FIN タイムアウトの期間を制御します。接続切断のために送信された FIN が指定の時間内に応答されない場合には、HAProxy が接続を切断します。小さい値を設定し、ルーターでリソースをあまり使用していない場合には、リスクはありません。 |
|
30s |
クライアントがデータを確認するか、送信するための時間の長さ。 |
|
5s |
最大接続時間。 |
|
1s |
ルーターからルートをバッキングする Pod の TCP FIN タイムアウトを制御します。 |
|
30s |
サーバーがデータを確認するか、送信するための時間の長さ。 |
|
1h |
TCP または WebSocket 接続が開放された状態で保つ時間数。websockets/tcp 接続がある場合 (および HAProxy が再読み込みされる度) に、以前の HAProxy プロセスが指定された時間分、開放された状態に保たれます。 |
|
300s |
新しい HTTP 要求が表示されるまで待機する最大時間を設定します。この値が低すぎる場合には、ブラウザーおよびアプリケーションの |
|
10s |
HTTP 要求の伝送にかかる時間。 |
|
5s |
新規の変更を許可するためにルーターの再ロードが許可される最小の頻度。 |
|
5s |
HAProxy メトリクスの収集タイムアウト。 |
有効なタイムアウト値には、想定した個別のタイムアウトではなく、特定の変数を合計した値に指定することができます。
例: ROUTER_SLOWLORIS_HTTP_KEEPALIVE
は timeout http-keep-alive
を調節し、デフォルトで 300s
に設定されていますが、haproxy は tcp-request inspect-delay
も待機し、値は 5s
に設定されているので、今回の場合には、合計のタイムアウトは 300s
に 5s
を加えた値になります。
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_CIPHERS
を modern
、intermediate
または 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 終端タイプを使用してクライアントに証明書を提供できます。ルーターは、edge、passthrough および 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-----
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 [ ... ]
例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 [ ... ]
パススルーの停止
passthrough termination では、暗号化されたトラフィックが TLS 終端を提供するルーターなしに宛先に直接送信されます。そのため、鍵や証明書は必要ありません。
例5.9 パススルーの停止を使用したセキュリティー保護されたルート
宛先 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 |
|
|
router-2 |
|
|
router-3 |
|
|
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: Service
の to:
トークンを使用したサービスと関連付けられます。ルートへの全要求は、「負荷分散ストラテジー」をベースに、サービス内のエンドポイントにより処理されます。
サービスは最大 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-name2
とservice-name3
はそれぞれ、要求の 1/4 を取得し、サービス毎に 1 または複数のエンドポイントが含まれると想定します。== ルート固有のアノテーション
環境変数を使用して、ルーターは、公開する全ルートにデフォルトオプションを設定できます。個別のルートは、アノテーションに個別の設定を指定して、デフォルトの一部を上書きできます。
ルートアノテーション
このセクションで説明されているすべての項目について、ルートがその設定を変更できるように ルート定義 にアノテーションを設定できます。
表5.5 ルートアノテーション
変数 | 説明 | デフォルトで使用される環境変数 |
---|---|---|
|
ロードバランシングアルゴリズムを設定します。使用できるオプションは |
passthrough ルートの |
|
関連の接続を追跡する cookie の使用を無効にします。 | |
|
このルートに使用するオプションの cookie を指定します。名前は、大文字、小文字、数字、"_" または "-" を任意に組み合わせて指定する必要があります。デフォルトは、ルートのハッシュ化された内部キー名です。 | |
|
ルーターからバッキングされる Pod に対して許容される接続最大数を設定します。 注意: Pod が複数ある場合には、それぞれに対応する接続数を設定できますが、ルーターが複数ある場合には、ルーター間の連携がなく、それぞれの接続回数はルーターの数と同じとなります。設定されていない場合または 0 に設定されている場合には制限はありません。 | |
|
レート制限機能を有効にするために | |
|
IP アドレスで共有される同時 TCP 接続の数を制限します。 | |
|
IP アドレスが HTTP 要求を実行できるレートを制限します。 | |
|
IP アドレスが TCP 接続を行うレートを制限します。 | |
|
ルートのサーバー側のタイムアウトを設定します。(TimeUnits) |
|
|
バックエンドのヘルスチェックの間隔を設定します。(TimeUnits) |
|
|
ルートのホワイトリストを設定します。 | |
|
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 サブドメインワイルドカードポリシーを指定するルート
5.7.15. ルートステータス
route status
フィールドは、ルーターでのみ設定されます。ルーターが特定のルーターへのサービス提供を停止するように、ルートに変更が加えられた場合には、スターテスが古くなってしまいますが、ルーターは、route status
フィールドは消去しません。ルートステータスの以前のエントリーを削除するには、clear-route-status script を使用してください。
5.7.16. ルート内の特定ドメインの拒否または許可
ルーターは、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.xyz
、bar.abc.xyz
、baz.abc.xyz
など) ワイルドカード以外の重複ホストを要求することも可能で、この要求は認められます。
別の namespace (例: ns2
) はルート r2
www.abc.xyz/p1/p2
を作成でき、許可されます。同様に、別の namespace (ns3
) は、サブドメインのワイルドカードポリシーでルート wildthing.abc.xyz
も作成でき、このワイルドカードを所有できます。
この例にあるように、ポリシー ROUTER_DISABLE_NAMESPACE_OWNERSHIP_CHECK=true
は制約がゆるく、namespace 全体の要求を許可します。ルーターが namespace の所有を無効にしているルートを許可できるのは、ホストとパスがすでに請求済みである場合だけです。
たとえば、新規ルート rx
が www.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