Kubernetes基礎 #3 - Load Balancers & Ingress

Last Edited: 3/22/2025

このブログ記事では、KubernetesにおけるLoad BalancerとIngressについて紹介します。

DevOps

前回の記事では、リソースの設定とkubectlを使用したクラスターの制御の基本について説明し、NordPortを使用してポッドを公開しました。 しかし、NordPortはノードのIPアドレスとポートを通じて誰でもポッドにアクセスできるようにするため、本番環境に使用するには理想的ではありません。 本番環境では、ワーカーノード内のポッド間で適切な負荷分散を行いながらクラスターを動的にスケーリングし、 限られたリバースプロキシのセットにのみアクセスを公開することでアクセスとエラーログを追跡する必要があります。 この記事では、本番環境により適した2つの代替方法について説明します。

LoadBalancerサービス

ここで使用できる代替サービスはLoadBalancerサービスです。これにより、通常クラウドプロバイダー(AWS、Google Cloud など)が提供する外部ロードバランサーを設定でき、 デプロイメントに静的なパブリックIPアドレスを提供します。また、TLS終端やヘルスチェック(選択したロードバランサーによって異なります)などの機能も提供し、 トラフィックをポッドにルーティングします。

apiVersion: v1
kind: Service
metadata:
  name: frontend-service
  annotations: 
    service.beta.kubernetes.io/aws-load-balancer-type: external
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
    service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
spec:
  type: LoadBalancer
  selector:
    app: frontend
  ports:
    - name: frontend-port
      protocol: TCP
      port: 3000
      targetPort: 3000
      #nodePort: 30000 # ロードバランサーによっては必要

上記はAWSのNLBを使用してLoadBalancerサービスを設定するためのYAMLファイルの例です。 AWS上でKubernetesクラスターをセットアップし、さまざまなロードバランサー(ELB、ALB、NLB)から選択する詳細については、 公式リソースを確認することをお勧めします。実装の詳細は異なりますが、多くのソリューションでは通常NodePortサービスの使用を避け、 本番環境においてノードのIPとポートを隠します。また、多くのトラフィックを効率的に捌くことができ、高可用性を確保できます。

Ingress

NodePortLoadBalancerなどの外部サービスタイプを使用する代わりに、Ingressを使用してクラスターのサービスを公開することができます。 YAMLファイルでIngressルールを定義でき、Ingressコントローラーの実装(クラウドプロバイダーからのロードバランサーまたは Kubernetes Nginx 実装)によって守られます。 以下は Ingress を設定するYAMLファイルの例です。

ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: http-example-ingress
  # example.com/<different-names>のように複数のサービスを提供する場合以下を使用
  # anotations:
  #   nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  # TLS終端には以下を使用
  # tls:
  #   - hosts:
  #     - example.com
  #     secretname: example-tls-secret
  rules: 
    # サブドメインを使用して複数のサービスを提供
    - host: www.example.com
      http:
        paths:
          backend:
            serviceName: web-service
            servicePort: 3000
    - host: api.example.com
      http:
        paths:
          backend:
            serviceName: api-service
            servicePort: 4000

上記からわかるように、TLS終端とドメインベースのルーティングを簡単に設定できます。 ただし、TLS証明書はexample-tls-secretという名前のシークレットとして保存する必要があり、 typeフィールドはkubernetes.io/tlsdataフィールドにはtls.crttls.keyというキーが含まれ、 それぞれbase64エンコードされたTLS証明書とキーにマッピングされていなくてはなりません。 MinikubeでIngressを実演するには、上記をkubectlで適用し、minikube addons enable ingressを実行して、IngressコントローラーのKubernetes Nginx実装を開始します。

ソリューションによっては、外部ロードバランサーまたはアクセスポイントをセットアップするためにLoadBalancerまたはNodePortサービスを作成するように設定されることが多く、 これによりトラフィックがIngressコントローラーにルーティングされ、内部サービスへのルーティングが行われます。 ただし、複数のロードバランサーやノードを直接公開する代わりに、Ingressコントローラーにトラフィックをリダイレクトする1つだけを公開することができるため、 ルーティングおよびTLS機能も含め、本番環境により理想的です。

結論

この記事では、クラスターを公開する代替方法としてLoadBalancerサービスとIngressを紹介しました。 高可用性のためにIngressを設定して LoadBalancer サービスにトラフィックをリダイレクトすることで、 これらを組み合わせて使用することができますが、これには公開されたサービスへのトラフィックを管理するための追加のネットワークポリシーの設定が必要になる可能性があります。 ここで紹介したもの以外にも、内部および外部トラフィックを管理するための他の(おそらくより良い)方法があり、それらは今後の記事で取り上げる予定です。

リソース