Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

KubeIP v2:Kubernetesノードに静的パブリックIPをマルチクラウドで割り当てる

By Alexei LedenevMay 23, 202411 min read

このページはEnglishDeutschEspañolFrançaisItalianoPortuguêsでもご覧いただけます。

TL;DR

Kubernetesノードに専用の静的パブリックIPアドレスを割り当てると効果を発揮するシナリオがあります。

オープンソースのユーティリティ KubeIP は、Kubernetesノードに静的パブリックIPを割り当てることで、こうしたニーズに応えます。最新版のKubeIP v2では、Google CloudのGKEに加えてAmazonのEKSもサポートし、他のクラウドプロバイダーへの拡張も視野に入れた設計となっています。DaemonSetとして動作し、従来のKubernetesコントローラー方式に比べて信頼性、設定の柔軟性、使いやすさが向上しました。KubeIP v2はIPv4とIPv6の両方の割り当てに対応しています。

本記事では、KubeIPの具体的なユースケース、クラウドNATゲートウェイとの比較、そしてKubeIPのアーキテクチャと設定について詳しく解説します。

ユースケース

KubeIPは、Kubernetesノードに静的パブリックIPが必要となるさまざまな場面で活躍します。

代表的なユースケースは以下のとおりです。

ゲーミングアプリケーション

ゲーミングの分野では、ネットワークホップ数とレイテンシを抑えるために、コンソールがクラウドVMへ直接接続する必要があるケースがあります。ゲームサーバーをホストするノードに専用のパブリックIPを割り当てれば、コンソールから直接接続できるようになり、レイテンシやパケットロスを抑えてプレイ体験の向上が見込めます。

エージェントIPのホワイトリスト登録

Kubernetes上で稼働する複数のエージェントやサービスが外部サーバーへ直接接続する必要があり、そのサーバー側でIPアドレスをホワイトリストに登録する運用の場合、KubeIPでノードに安定したパブリックIPを割り当てれば、広範なCIDRレンジを許可するよりも管理が容易になります。外部サーバーが厳格なIPベースのアクセス制御を行うシナリオで特に有効です。

特定のPodでSNATを回避する

デフォルトでは、PodにはVPC CIDRレンジから払い出されるプライベートIPが割り当てられます。外部のIPv4アドレスと通信する際、Amazon VPC CNIプラグインはSNAT(送信元ネットワークアドレス変換)によって、PodのIPをノードのネットワークインターフェースのプライマリプライベートIPに変換します。

場合によっては、外部サービスから実際のPod IPが見えるよう、特定のPodだけSNATを回避したいことがあります。KubeIPでノードにパブリックIPを割り当て、Podのspecに hostNetwork: true を設定すれば、これを実現できます。PodはノードのパブリックIPを使って外部サービスと直接通信できるようになります。

直接インバウンド接続とカスタムネットワーク構成

KubeIPでノードにパブリックIPを割り当てると、さまざまなネットワーク構成が可能になります。たとえば、当該ノード上で動作するPodへトラフィックを直接転送できるため、従来型のロードバランサーを介さずにノード上のサービスをインターネットへ公開したい場合に便利です。

具体例としては、Pod上でWebサーバーを稼働させ、ノードのパブリックIPを使ってトラフィックを転送する構成が挙げられます。

さらに、KubeIPはノードへのパブリックIPを必要とするカスタムネットワーク構成の実装にも利用できます。たとえば、パブリックIPに基づいて特定のノードへトラフィックを振り分けるカスタムロードバランサーを構築することも可能です。この柔軟性によって、KubeIPはKubernetes上でカスタムネットワーキングソリューションを検証・運用する強力な手段となります。

IPv6サポート

KubeIPはIPv4にとどまらず、ノードへの静的パブリックIPv6アドレスの割り当てにも対応しています。IPv4アドレスの枯渇を背景にインターネット全体がIPv6への移行を進めるなか、この機能の重要性はますます高まっています。

KubeIPのIPv6サポートにより、Kubernetesノードに静的パブリックIPv6アドレスを割り当て、IPv6経由で外部サービスと直接通信できるようになります。これは、IPv6接続性が求められるアプリケーションにとって大きなメリットです。たとえばIPv6対応が必要なアプリケーションの開発・デプロイ時に、KubeIPを使ってPodへIPv6接続性を提供できます。

加えてIPv6は、IPv4と比べて広大なアドレス空間、簡素化されたヘッダーフォーマット、拡張機能とオプションの強化、マルチキャストルーティングの改善など、多くの利点を備えています。

クラウドNATゲートウェイとの比較

NATゲートウェイは、プライベートサブネット内のリソースのプライベートIPをパブリックIPへ変換することで、それらのリソースにアウトバウンドのインターネットアクセスを提供するマネージドクラウドサービスです。プライベートネットワーク内のリソースが、プライバシーとセキュリティを保ったままインターネットへのアウトバウンド接続を開始できるよう設計されています。

一方で、NATゲートウェイはインバウンド接続には対応しておらず、リソースに直接パブリックIPを割り当てることもできません。安全なアウトバウンドアクセスの提供には優れていますが、インバウンド接続が必要なケースや、リソース自体がパブリックIPを持つ必要があるシナリオには適していません。

これに対しKubeIPは、Kubernetesノードに直接静的パブリックIPを割り当てます。これにより、ノードからPodへトラフィックを転送する形で、ノード上のPodへのインバウンド接続を直接受け付けられるようになります。インターネットからアクセス可能にしたいアプリケーションや、カスタムネットワーク構成において特に有用です。

さらに hostNetwork を有効にすると、Podはホストのアドレスを直接使ってアウトバウンド接続を開始できます。ネットワーク性能の向上やトラブルシューティングの簡素化が期待できますが、セキュリティ面の考慮事項があるため慎重に利用する必要があります。

まとめると、NATゲートウェイは安全なアウトバウンドアクセスに優れたソリューションである一方、KubeIPは特定のPodやノードに対するインバウンド/アウトバウンドの接続性を、より柔軟かつ細かく制御できる手段を提供します。

コスト比較:KubeIP vs クラウドNATゲートウェイ

KubeIPとクラウドNATゲートウェイのコストを比較する際には、いくつかの観点を踏まえる必要があります。

クラウドNATゲートウェイのコスト

クラウドNATゲートウェイはマネージドサービスであるため、利用には費用が発生します。コストは通常、処理データ量と、NATゲートウェイがプロビジョニングされ稼働している時間に応じて決まります。

たとえばAWSでは、執筆時点でNATゲートウェイの料金は1時間あたり\$0.045、これにデータ処理料金が加算されます。NATゲートウェイ経由で転送されるすべてのデータには、AWSの標準データ転送料金も発生します。

Google Cloud NATの料金体系もこれと同様です。

KubeIPのコスト

一方、KubeIPはオープンソースツールであるため、利用そのものに直接的な費用は発生しません。ただし、以下のような間接コストを考慮する必要があります。

  1. 静的パブリックIPアドレス:ノードに割り当てる静的パブリックIPアドレスの料金が発生します。価格はクラウドプロバイダーによって異なります。たとえばAWSでは、Elastic IPアドレスは使用中・未使用にかかわらず1時間あたり\$0.005で課金されます。Google Cloudの静的IPアドレスも同額です。
  2. データ転送:割り当てた静的パブリックIPアドレス経由のデータ転送には、標準のデータ転送料金が適用されます。料金は各クラウドプロバイダーのデータ転送価格に準じます。
  3. クラスタへの追加負荷:KubeIPはDaemonSetとして動作し、CPUやメモリの消費は多くありませんが、それでもKubernetesクラスタ上で稼働する追加のworkloadであることに変わりはありません。リソースが限られたクラスタでは、他のworkloadのパフォーマンスに影響を及ぼす可能性があります。とはいえ、ほとんどの場合その影響はごくわずかです。
  4. メンテナンスとサポート:オープンソースツールであるKubeIPには専用のサポートはありません。メンテナンス、トラブルシューティング、アップデートは自社チームで対応する必要があります。直接的な費用は発生しませんが、時間と労力を要するため、組織にとって実質的なコストとなり得ます。

まとめると、KubeIP自体に直接的なコストはないものの、考慮すべき間接コストがいくつかあります。それでも多くのユースケースでは、KubeIPが提供する柔軟性とコントロール性がこれらのコストを上回る価値を生みます。

コストに関する考慮事項

KubeIPの費用対効果を評価する際は、利用に伴う直接コストと間接コストの両方を踏まえることが重要です。具体的には、静的パブリックIPアドレスの料金、データ転送料金、Kubernetesクラスタ上で追加のworkloadを稼働させることの影響、そしてメンテナンスとサポートに要する時間と労力です。

KubeIPに直接的なコストはないものの、特に大規模クラスタではこれらの間接コストが積み上がる可能性があります。それでも、KubeIPが提供する柔軟性とコントロール性は、特に直接インバウンド接続やカスタムネットワーク構成を必要とするユースケースにおいて、大きな価値をもたらします。

一方、クラウドNATゲートウェイは、プライベートサブネット内のリソースのアウトバウンド接続を簡潔に扱えるマネージドサービスです。費用はかかるものの、使いやすさ、スケーラビリティ、信頼性といったメリットがあります。

結論として、KubeIPとクラウドNATゲートウェイのどちらを選ぶかは、具体的なユースケース、Kubernetesクラスタの規模と要件、そして予算次第です。想定するデータ転送量、ノード数/IPアドレス数、メンテナンスニーズをもとにコストを試算し、判断することをおすすめします。

KubeIPの仕組み

KubeIPは対象ノード上でDaemonSetとして動作し、各ノードで以下の処理を行います。

  1. Kubernetes Downward APIを使ってノードとクラウドプロバイダーの情報を取得します。
  2. クラスタ全体のロックを取得し、IPを割り当てるノードを同時に1つだけに制限することで、競合状態やIPの重複を防ぎます。
  3. フィルターとセレクターを用いて、設定されたプールから利用可能な静的IPを選択します。
  4. クラウドプロバイダーのAPIを介して、ノードのプライマリネットワークインターフェースにIPを割り当てます。
  5. ネットワーク中断やAPIエラーなどで割り当てに失敗した場合、KubeIPは設定された上限まで再試行します。
  6. ノードが削除されると、KubeIPは割り当て済みのIPをプールへ返却し、他のノードで利用できるようにします。

KubeIPはIPv4とIPv6の両方をサポートし、それぞれに別々のプールを設定できます。また、ノードやノードグループごとにカスタムIPプールを利用できるため、IP管理を柔軟に行えます。

KubeIPのアーキテクチャ

KubeIP v2は標準的なKubernetes DaemonSetとして設計されており、クラスタ内の各ノードで動作します。

この設計により、従来のコントローラーベースの方式と比べて信頼性と使いやすさが向上しました。デプロイ手順もシンプルになり、各ノードが確実にパブリックIPを取得できます。さらに、ノードセレクターやノードアフィニティといった標準的なKubernetesの機能を活用することで、KubeIPをデプロイするノードを制御できます。これにより、要件に応じて特定のノードにのみパブリックIPを割り当てるなど、IP割り当てをきめ細かくコントロールできます。

KubeIP v2は拡張性の高い設計のため、GKEやEKS以外のクラウドプロバイダーとも容易に統合できます。マルチクラウド環境でパブリックIPを管理する汎用的なツールとして活躍します。

KubeIPの設定

KubeIPを利用するには、ノードの取得とリースの管理を行う権限を持つKubernetesサービスアカウントが必要です。

クラウド側では、パブリックIPの割り当て・解除・一覧取得、およびノード情報の取得を行う権限を持つIAMロールまたはサービスアカウントが必要となります。

AWS IAMポリシーの例は以下のとおりです。

{
  "Version": "2012-10-17",
  "Statement": [\
    {\
      "Effect": "Allow",\
      "Action": [\
        "ec2:AssociateAddress",\
        "ec2:DisassociateAddress",\
        "ec2:DescribeInstances",\
        "ec2:DescribeAddresses"\
      ],\
      "Resource": "*"\
    }\
  ]
}

Google Cloud IAMロールの例は以下のとおりです。

title: "KubeIP Role"
description: "KubeIP required permissions"
stage: "GA"
includedPermissions:
- compute.instances.addAccessConfig
- compute.instances.deleteAccessConfig
- compute.instances.get
- compute.addresses.get
- compute.addresses.list
- compute.addresses.use
- compute.zoneOperations.get
- compute.subnetworks.useExternalIp
- compute.projects.get

使用するIPを選ぶには、IP一覧の取得に使うクラウドCLI/APIと同じ構文でフィルターを指定します。例:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kubeip
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: kubeip
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: kubeip
    spec:
      serviceAccountName: kubeip-service-account
      terminationGracePeriodSeconds: 30
      priorityClassName: system-node-critical
      nodeSelector:
        nodegroup: public
        kubeip: "use"
      tolerations:
        - operator: "Exists"
          effect: "NoSchedule"
        - operator: "Exists"
          effect: "NoExecute"
      containers:
      - name: kubeip
        image: doitintl/kubeip-agent
        imagePullPolicy: Always
        resources:
          requests:
            cpu: "10m"
            memory: "32Mi"
        env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: LEASE_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: FILTER
          value: "Name=tag:kubeip,Values=reserved;Name=tag:environment,Values=prod"
        - name: LOG_LEVEL
          value: "debug"
        - name: LOG_JSON
          value: "true"

この設定では、AWS上のKubeIPは kubeip=reservedenvironment=prod のタグが付いたIPだけを対象にします。

KubeIPのAWSフィルターは、AWSの describe-addresses コマンドと同じフィルター構文をサポートします。詳細は describe-addresses をご覧ください。複数のフィルターを指定した場合は AND 条件で結合され、すべてのフィルターに一致する結果のみが返されます。複数のフィルターはセミコロン(;)で区切ってください。

KubeIPのGoogle Cloudフィルターは、Google Cloudの gcloud compute addresses list コマンドと同じフィルター構文をサポートします。詳細は gcloud topic filter をご覧ください。複数のフィルターを指定した場合は AND 条件で結合され、すべてのフィルターに一致する結果のみが返されます。複数のフィルターはセミコロン(;)で区切ってください。

実際に試してみる

examples ディレクトリには、KubeIPをデプロイしたGKEおよびEKSクラスタを構築するためのTerraform構成が用意されています。

EKSで実行する場合:

cd examples/aws

terraform init

terraform apply

GKEで実行する場合:

cd examples/gcp

terraform init

# IPv6サポートなし
terraform apply -var="project_id=<your-project-id>"

# IPv6サポートあり
terraform apply -var="project_id=<your-project-id>" -var="ipv6_support=true"

これにより、パブリックとプライベートのノードプールを備えたクラスタが構築され、いくつかの静的IPが予約されたうえで、それらを利用するように設定されたKubeIP DaemonSetがデプロイされます。

コミュニティに参加しよう

オープンソースのプロジェクトとして、コントリビューションを歓迎しています!プルリクエストの送信、Issueの作成、ドキュメントの改善、プロジェクトの紹介など、さまざまな形でご参加ください。

v2でのクラウドサポート拡充とDaemonSetモデルによるシンプル化を経て、KubeIPがさらに多くのユースケースで活用されることを楽しみにしています。ぜひご自身の環境で試して、ご感想をお聞かせください!

KubeIP v2は、クラウドプロバイダーを問わずKubernetesクラスタ内の静的パブリックIP管理に堅牢性と柔軟性をもたらす強力なツールです。ノードへ直接パブリックIPを割り当てられる独自の機能により、活用の幅は大きく広がります。直接インバウンド接続を実現したい場合も、独自のネットワーク構成を組みたい場合も、KubeIP v2が応えます。

KubeIP v2の大きな強みのひとつは、これからのインターネット接続に備えていることです。IPv4とIPv6の両方をサポートしており、進化し続けるインターネットのなかでも価値を保ち続けます。さらに、DaemonSetとしてデプロイされる設計により、セットアップの簡素化と信頼性の向上を同時に実現しています。

柔軟性もKubeIP v2の魅力です。ノードセレクターやノードアフィニティといった標準的なKubernetes機能を活用して、特定のノードにKubeIPをデプロイできるため、IP割り当てをきめ細かくコントロールできます。

静的パブリックIPアドレスの料金やデータ転送料金など、KubeIPの利用には一定のコストが伴いますが、多くの場合、得られるメリットがそれを上回ります。直接的な接続性や、独自のネットワーク要件に対応できる柔軟性は、コストを補って余りある価値をもたらします。

結論として、KubeIP v2は単なる静的パブリックIP割り当てツールにとどまりません。Kubernetesのネットワーキングを強化し、IP管理を簡素化し、アプリケーションに新たな可能性を切り拓く包括的なソリューションです。