ページの先頭です

ページ内を移動するためのリンク
本文へ (c)

ここから本文です。

Kubernetesクラスターにおけるロードバランサーの活用

ライター:奈良 昌紀
通信事業者のデータセンターにおいてネットワーク・サーバー運用を経験した後、ネットワンシステムズに入社。帯域制御やWAN高速化製品担当を経て、2008年から仮想化関連製品を担当。現在は主にクラウド、仮想インフラの管理、自動化、ネットワーク仮想化を担当。

目次

はじめに

以前、こちらのBlogで「Kubernetesネットワーク入門」を掲載させていただきました。今回はKubernetesクラスターにおいて、外部ロードバランサーがどの様に利用されるのかご紹介します。

Kubernetesクラスター内で起動するPodをクラスター外部に公開する方法として、Service (type: LoadBalancer)リソースを利用する方法と、Ingressリソースを利用する方法があります。いずれの方法も、クラスター外のロードバランサーを利用して、クラスター内のPodにリクエストを届ける必要があります。

クラウド環境でKubernetesを利用する場合、クラウドサービスが提供するロードバランサーを利用することが可能です。たとえばAWSであればElastic Load Balancer、AzureであればAzure Load Balancerが利用され、Amazon EKSやAKS等を構成すると利用可能になるため、ロードバランサーをあまり意識する必要は有りません。しかし、オンプレミス環境ではKubernetesクラスターの外部にロードバランサーを用意する必要があるため、ロードバランサーがどの様に利用されるのかを理解する必要があります。

Serviceリソースの役割

Serviceリソースは、クラスター内で起動するPodに対するL4負荷分散と名前解決を提供します。Kubernetesクラスター内部では、Podが動的に作成、削除されます。Serviceリソースがない場合、アクセス先のPod名やPodのIPアドレスを知らなければ、アクセスすることができません。また、PodのIPアドレスを認識できた場合も、多くのCNIではクラスター外部から直接Podに対して到達することができません。

そこで、Serviceリソースは負荷分散用の仮想IPアドレスを構成し、Kubernetes APIを参照して特定のラベルが付与されたPodを負荷分散対象として、動的に更新します。更に、クラスター内のDNSでこの仮想IPアドレスの名前解決を可能にします。

こうすることで、クラスター内のPodはService名を利用してPodにアクセスすることが可能になり、動的に作成・削除されるアクセス先のPodの情報を意識する必要がなくなります。クラスター外部からPodにアクセスしたい場合も、Serviceリソースが外部からアクセス可能なノード上のポート番号や、仮想IPアドレスを用意することで、クラスター内のPodに対してアクセスすることを実現します。

Serviceリソースのタイプ

このように、Serviceリソースを利用することによりPodに対するアクセスを抽象化し、Podとして実行されるアプリケーション同士を疎結合化することが容易になります。Serviceリソースには4種類のタイプがあり、用途に応じて使い分けます。今回は4種類のServiceのうち、ExternalNameを除く3種類をご説明します (ExternalNameは、Kubernetesクラスター内のPodから外部サービスの参照に利用されるServiceです) 。

ClusterIP

デフォルトのServiceタイプです。クラスター内のPodから、Podグループにアクセスするために利用されます。クラスター内でのみ利用されるIPアドレスが仮想IPとして利用され、各ノードはこのIPアドレス宛の通信をService配下のPodに負荷分散します。この負荷分散機能は各Linuxノード内のiptablesやIPVSによって実現され、VIPに対するアクセスをNATしてPodに負荷分散します。

負荷分散対象が異なるノードにも存在する場合、必ずしもノード内で通信は完結せず、CNI(Container Network Interface)によりノード間通信を介して、他ノード上のPodに負荷分散される可能性があります。

NodePort

クラスター外のクライアントから、Podグループにアクセスするために利用されます。クラスター外からアクセスするため、各ノード上のポート(デフォルトは30000-32767)を利用してServiceを公開します。クラスター内のいずれかのノードのこのポートにアクセスすると、Service配下のPodに負荷分散されます。

アクセス先のノード内にはClusterIPの設定が存在し、ノード内でClusterIPと同じ方法でPodに負荷分散を行います。従ってClusterIPと同様に、Node1で受信したトラフィックが、内部でNode2上のPodに負荷分散される可能性があります。また、クライアントがNode1のポートにアクセスしていて、Node1で障害が発生した場合、クライアントはアクセス先をNode2の同じポートに変更する必要があります。

LoadBalancer

クラスター外のクライアントから、Podグループにアクセスするために利用されます。NodePortと異なり外部のロードバランサーを利用してServiceを公開するため、ノードのIPアドレスやポート番号を意識する必要はなく、外部ロードバランサーに構成された仮想IPアドレスでアクセスすることが可能です。ロードバランサーに登録される負荷分散対象は、利用するCNIによって異なります。

ロードバランサーの負荷分散対象としてNodePortが利用される場合、ロードバランサーは受信したトラフィックをクラスターのNodePortに転送します。NodePortは受信したトラフィックを負荷分散してPodに届けます。この構成では、外部ロードバランサーで負荷分散が行われた後、クラスター内のiptablesによって再度負荷分散が行われることになります。

ロードバランサーがPodに対して直接アクセスできる場合、負荷分散対象としてPodのIPアドレスが直接登録されます。クラスター内にClusterIPが構成されますが、クラスター内で利用するためだけに利用され、クラスター外部からのアクセスに対しては介入しません。NodePortを利用する場合と比べてシンプルな構成になりますが、ロードバランサーとPodが直接通信できるようCNIが構成されている必要があります。

Ingressリソース

Ingressリソースは、クラスター内で起動するPodに対するL7負荷分散を提供します。Ingressに登録される負荷分散対象は前述のServiceが利用されます。ルーティングルールを作成することができるため、アクセス先のFQDNやパスに応じて異なるサービスにルーティングすることが可能です。

以下のマニフェストではwww.example.comというFQDN向けのアクセスの中で、www.example.com/web1に対するアクセスをweb1サービスリソースに、www.example.com/web2に対するアクセスをweb2サービスリソースにルーティングします。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: website
spec:
  rules:
  - host: www.example.com
    http:
      paths:
      - backend:
          service:
            name: web1
            port:
              number: 80
        path: /web1
        pathType: Prefix
      - backend:
          service:
            name: web2
            port:
              number: 80
        path: /web2
        pathType: Prefix

Ingressは、Kubernetes上にIngress Controllerを構成することで利用可能になります。Ingress Controllerは多数開発されており、これらを利用することでIngressリソースのマニフェストに基づいてロードバランサーの構成が可能になります。

Ingress Controllerにはいくつかの実装方法がありますが、オンプレミス環境で一般的なのは、Ingress機能を提供するL7ロードバランサーがPod(LB pod)として起動し、このPodをService (type: LoadBalancer)として外部に公開する方法です。Service type:LoadBalancerとして公開され、L4ロードバランサーによって処理された通信がNodePortやClusterIPによって、L7ロードバランサーPodに転送し、L7ロードバランサーPodがHTTP/HTTPSのリクエスト内容を認識し、トラフィックを宛先のServiceに転送します(以下のイメージではtype:LoadBalancerを可能にするためにNodePortを利用しています)。

まとめ

Kubernetes環境で、クラスター外部にPodを公開する方法であるServiceとIngressの実装に関してご紹介しました。オンプレミス環境において、これらの機能を柔軟に利用するには、Kubernetes環境の外部にロードバランサーを配置する必要があります。ネットワンシステムズでは、複数のロードバランサー製品を取り扱っており、すでにKubernetesと組み合わせた検証を実施しております。今回ご紹介した機能を、弊社取扱製品でどの様に実装するのかをご紹介していく予定です。

※本記事の内容は執筆者個人の見解であり、所属する組織の見解を代表するものではありません。

RECOMMEND