Anthos clusters on bare metal は、IPv4/IPv6 デュアルスタック ネットワーキングをサポートしています。つまり、クラスタは、インターネット プロトコル バージョン 4(IPv4)か、インターネット プロトコル バージョン 6(IPv6 など)を使用するデバイスからのトラフィックを受け入れることができます。
デュアルスタック ネットワーキングは、IPv4 と IPv6 の両方のアドレスを Pod とノードに割り当てます。 Kubernetes Service は、IPv4 アドレス、IPv6 アドレス、またはその両方を保有できます。
すべてのデュアル スタック クラスタは、IPv6 にフラットモードを使用します。デフォルトでは、デュアルスタック クラスタは IPv4 にアイランド モードを使用しますが、IPv4 にフラットモードを使用するように構成できます。
デュアルスタック クラスタを作成するには、基盤となるネットワークでデュアルスタックが有効である必要があります。基盤となるネットワークがシングルスタック IPv4 または IPv6 ネットワークの場合、デュアルスタック クラスタを起動できません。
準備
クラスタノードが CentOS または RedHat Enterprise Linux を実行し、SELinux が有効化されている場合は、各ノードで:
/etc/firewalld/firewalld.conf
でIPv6_rpfilter=no
を設定します。systemctl restart firewalld
を実行します。
デュアルスタック クラスタの作成の概要
デュアルスタック ネットワーキングは新しいクラスタを作成するときに有効にできますが、既存のクラスタに対してデュアルスタック ネットワーキングを有効にすることはできません。
クラスタ作成に関するドキュメントの手順に沿って操作します。
構成ファイルに、次の項目に関するマニフェストを追加します。
- 1 つの Namespace リソース
- 1 つのクラスタ リソース。
- 1 つ以上の NodePool リソース
- 1 つ以上の ClusterCIDRConfig リソース
シングルスタック クラスタの場合のように、Namespace マニフェストと NodePool マニフェストを入力します。
クラスタ マニフェストの clusterNetwork.services.cidrBlocks
で、IPv4 CIDR 範囲と IPv6 CIDR 範囲の両方を指定します。これはデュアルスタック クラスタの有効化の基準です。つまり、IPv4 と IPv6 の両方に Service CIDR 範囲を指定すると、クラスタはデュアルスタック ネットワークを持ちます。
クラスタ マニフェストの clusterNetwork.pods.cidrBlocks
で IPv4 CIDR 範囲を指定しますが、IPv6 CIDR 範囲は指定しません。Pod の IPv6 CIDR 範囲は、ClusterCIDRConfig マニフェストで指定します。
バンドル型ロード バランシングを使用している場合は、クラスタ マニフェストの loadBalancer.addressPools
セクションに IPv4 アドレスと IPv6 アドレスの両方を指定します。
ClusterCIDRConfig リソースは、Pod の IPv4 と IPv6 の CIDR 範囲を指定するためのものです。単一の ClusterCIDRConfig リソースを使用して、クラスタ全体の CIDR 範囲を指定できます。つまり、すべてのノードの IPv4 Pod アドレスは単一の CIDR 範囲から取得され、すべてのノードの IPv6 Pod アドレスは単一の CIDR 範囲から取得されます。または、複数の ClusterCIDRConfig リソースを使用して、特定のノードプールまたは特定のノードに適用される CIDR 範囲を指定できます。
Pod IP アドレスのネットワーク到達性
デュアルスタック クラスタは、IPv6 ネットワーキングにフラットモードを使用します。このドキュメントの例では、IPv6 に静的フラットモード ネットワーキングを使用するクラスタを対象としています。つまり、クラスタは Border Gateway Protocol(BGP)を使用するように構成されていません。
静的フラットモード ネットワーキングを使用するクラスタの場合、すべて同じサブネットの一部であるノードと Pod の IP アドレスを指定する必要があります。これにより、クラスタ外のクライアントでクラスタノードと同じレイヤ 2(L2)ドメインに Pod の IP アドレスに直接パケットを送信できるようになります。
たとえば、クラスタノードと他のマシンがすべて同じ L2 ドメインにあるとします。次の方法でアドレス範囲を指定できます。
目的 | 範囲 | アドレスの数 |
---|---|---|
L2 ドメイン全体 | fd12::/108 | 2^20 |
Pod | fd12::1:0/112 | 2^16 |
ノード | fd12::2:0/112 | 2^16 |
その他のマシン | fd12::3:0/112 | 2^16 |
VIP | fd12::4:0/112 | 2^16 |
上の例で、次の点に注意してください。
すべてのノード、Pod、マシンのアドレスは、fd12::/108 の広い範囲にあります。
Pod IP アドレスが広い範囲のサブセット内にある。
ノードの IP アドレスが、広い範囲の異なるサブセットにある。
他のマシンの IP アドレスは、広い範囲の異なるサブセットにあります。
すべてのサブセット範囲は互いに区別されています。
上記の例では、クラスタノードを含む L2 ドメイン内の各マシンに、広い範囲の転送ルールが必要です。次に例を示します。
inet fd12::/108 scope global eth0
例: デュアル スタック クラスタを作成する
デュアルスタック クラスタを作成する場合は、さまざまなオプションがあります。たとえば、クラスタ全体の CIDR 範囲を持つことも、特定のノードプールに適用される CIDR 範囲を持つこともできます。IPv6 フラット ネットワークと IPv4 アイランドモード ネットワークを組み合わせることができます。または、IPv4 ネットワークと IPv6 ネットワークの両方をフラットにできます。バンドル型負荷分散または手動負荷分散を使用できます。
このセクションでは、デュアルスタック クラスタを作成する方法の一例を示します。この例のクラスタには次の特性があります。
- アイランド モードの IPv4 ネットワーク
- フラットモードの IPv6 ネットワーク
- クラスタ全体にわたる Pod 用の IPv4 CIDR 範囲
- クラスタ全体にわたる Pod 用の IPv6 CIDR 範囲
- クラスタ全体にわたる Service 用の IPv4 CIDR 範囲
- クラスタ全体にわたる Service 用の IPv6 CIDR 範囲
LoadBalancer
型の Service に使用される IPv4 アドレスプールLoadBalancer
型の Service に使用される IPv6 アドレスプール- バンドル型負荷分散
他の構成例については、ClusterCIDRConfig の使用に関するバリエーションをご覧ください。
構成ファイルに入力する
クラスタ作成に関するドキュメントの手順に沿って操作します。
構成ファイルの Cluster
マニフェストで:
clusterNetwork.pods.cidrBlocks
に、1 つの IPv4 CIDR 範囲を指定します。clusterNetwork.services.cidrBlocks
に、2 つの CIDR 範囲(IPv4 用と IPv6 用)を指定します。loadBalancer.addressPools
に、2 つのアドレス範囲(IPv4 用と IPv6 用)を指定します。LoadBalancer
型の Service を作成すると、Service の外部 IP アドレスはこうした範囲から選択されます。
次に、クラスタ マニフェストの関連部分の例を示します。
apiVersion: baremetal.cluster.gke.io/v1 kind: Cluster metadata: name: "dual-stack" namespace: "cluster-dual-stack" spec: clusterNetwork: pods: cidrBlocks: - "192.168.0.0/16" services cidrBlocks: - "172.16.0.0/20" - "fd12::5:0/116" ... loadBalancer: mode: "bundled" ... addressPools: - name: "pool-1" addresses: - "10.2.0.212-10.2.0.221" - "fd12::4:101-fd12::4:110"
同じ構成ファイルに ClusterCIDRConfig
のマニフェストを含みます。
ipv4.cidr
を、Cluster
マニフェストで指定したものと同じ CIDR 範囲に設定します。これは、IPv4 がアイランド モードの場合の要件です。namespace
を、Cluster
マニフェストで指定したものと同じ値に設定します。ipv6.cidr
を Pod の IPv6 CIDR 範囲に設定します。CIDR 範囲ごとに、
perNodeMaskSize
に値を指定して、各ノードに割り振る Pod のアドレスの数を指定します。各ノードに割り振る IPv4 アドレスの数は、各ノードに割り振る IPv6 アドレスの数と同じにする必要があります。perNodeMaskSize
の値は、それに対応して設定する必要があります。たとえば、ノードごとに 2^8 個のアドレスが必要な場合、perNodeMaskSize
の値は次のように設定します。ipv4.perNodeMaskSize: 24
# (32 - 8 = 24)ipv6.perNodeMaskSize: 120
# (128 - 8 = 120)
ClusterCIDRConfig マニフェストの例を次に示します。
apiVersion: baremetal.cluster.gke.io/v1alpha1 kind: ClusterCIDRConfig metadata: name: "cluster-wide-ranges" namespace: "cluster-dual-stack" # Must be the same as the Cluster namespace. spec: ipv4: cidr: "192.168.0.0/16" # For island mode, must be the same as the Cluster CIDR. perNodeMaskSize: 24 ipv6: cidr: "fd12::1:0/112" perNodeMaskSize: 120
上の例の各要素の内容は次のとおりです。
IPv4 Pod CIDR 範囲には、2^(32-16) = 2^16 個のアドレスが存在します。ノードあたりのマスクサイズは 24 であるため、各ノードに割り当てられるアドレスの数は 2^(32-24) = 2^8 です。
IPv6 Pod CIDR 範囲には、2^(128-112) = 2^16 個のアドレスが存在します。ノードあたりのマスクサイズは 120 であるため、各ノードに割り当てられるアドレスの数は 2^(128-120) = 2^8 です。
例: 構成ファイル
クラスタの作成を完了する
クラスタ作成のドキュメントの説明に沿って、クラスタの作成を完了します。
クラスタのノードと Pod を表示する
クラスタのノードを一覧表示します。
kubectl --kubeconfig CLUSTER_KUBECONFIG get nodes --output yaml
CLUSTER_KUBECONFIG
は、ユーザー クラスタ kubeconfig ファイルのパスに置き換えます。
出力に、各ノードの IPv4 アドレスと IPv6 アドレスが表示されます。また、ノード上の Pod の IPv4 と IPv6 のアドレス範囲も確認できます。次に例を示します。
- apiVersion: v1 kind: Node ... spec: podCIDR: 192.168.1.0/24 podCIDRs: - 192.168.1.0/24 - fd12::1:100/120 providerID: baremetal://10.2.0.5 status: addresses: - address: 10.2.0.5 type: InternalIP - address: fd12::2:5 type: InternalIP
クラスタ内の Pod を一覧表示します。
kubectl --kubeconfig CLUSTER_KUBECONFIG get pods --all-namespaces
1 つの Pod を選択し、詳細を一覧表示します。次に例を示します。
kubectl --kubeconfig CLUSTER_KUBECONFIG get pod gke-metrics-agent-b9qrv \ --namespace kube-system \ -- output yaml
出力に、Pod の IPv4 アドレスと IPv6 アドレスが表示されます。次に例を示します。
apiVersion: v1 kind: Pod metadata: ... name: gke-metrics-agent-b9qrv namespace: kube-system ... status: ... podIPs: - ip: 192.168.1.146 - ip: fd12::1:11a
ClusterCIDRConfig の使用のバリエーション
上記の例では、ClusterCIDRConfig オブジェクトを使用して、クラスタ全体の Pod CIDR 範囲を指定しました。つまり、クラスタ内のすべての Pod に単一の IPv4 CIDR 範囲が使用されます。クラスタ内のすべての Pod に単一の IPv6 CIDR 範囲が使用されます。
特定の状況では、クラスタ内のすべての Pod に対して 1 つの CIDR 範囲を使用する必要はありません。たとえば、ノードプールごとに個別の CIDR 範囲を指定すること、ノードごとに個別の CIDR 範囲を指定することが可能です。
たとえば、次の ClusterCIDRConfig は、"workers"
という名前のノードプールの CIDR 範囲を指定します。
apiVersion: baremetal.cluster.gke.io/v1alpha1 kind: ClusterCIDRConfig metadata: name: "worker-pool-ccc" namespace: "cluster-dual-stack" spec: ipv4: cidr: "192.168.0.0/16" perNodeMaskSize: 24 ipv6: cidr: "fd12::1:0/112" perNodeMaskSize: 120 nodeSelector: matchLabels: baremetal.cluster.gke.io/node-pool: "workers"
次の ClusterCIDRConfig は、IP アドレス 10.2.0.5 を含む単一ノードの CIDR 範囲を指定します。
apiVersion: baremetal.cluster.gke.io/v1alpha1 kind: ClusterCIDRConfig metadata: name: "range-node1" namespace: "cluster-dual-stack" spec: ipv4: cidr: "192.168.1.0/24" perNodeMaskSize: 24 ipv6: cidr: "fd12::1:0/120" perNodeMaskSize: 120 nodeSelector: matchLabels: baremetal.cluster.gke.io/k8s-ip: "10.2.0.5"
タイプ ClusterIP
のデュアル スタック Service を作成する
Deployment のマニフェストは次のとおりです。
apiVersion: apps/v1 kind: Deployment metadata: name: "my-deployment" spec: selector: matchLabels: app: "try-dual-stack" replicas: 3 template: metadata: labels: app: "try-dual-stack" spec: containers: - name: "hello" image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
このマニフェストを my-deployment.yaml
という名前のファイルに保存して、Deployment を作成します。
kubectl --kubeconfig CLUSTER_KUBECONFIG apply -f my-deployment.yaml
CLUSTER_KUBECONFIG
は、ユーザー クラスタ kubeconfig ファイルのパスに置き換えます。
ClusterIP
タイプの Service のマニフェストは次のとおりです。
apiVersion: v1 kind: Service metadata: name: "my-service" spec: selector: app: "try-dual-stack" type: "ClusterIP" ipFamilyPolicy: "RequireDualStack" ipFamilies: - "IPv6" - "IPv4" ports: - port: 80 targetPort: 8080
この演習のコンテキストにおいて、次のことが上記の Service マニフェストについて理解すべき重要なポイントです。
ipFamilyPolicy
フィールドはRequireDualStack
に設定されています。つまり、IPv6 と IPv4 の両方のClusterIP
アドレスがサービスに割り振られます。ipFamilies
フィールドは、最初に IPv6 ファミリーを指定し、次に IPv4 ファミリーを指定します。つまり、Service のspec.ClusterIP
がクラスタ マニフェストのclusterNetwork.services.cidrBlocks
から選択された IPv6 アドレスになります。
このマニフェストを my-cip-service.yaml
という名前のファイルに保存して、Service を作成します。
kubectl --kubeconfig CLUSTER_KUBECONFIG apply -f my-cip-service.yaml
Service の詳細を一覧表示します。
kubectl --kubeconfig CLUSTER_KUBECONFIG get service my-service --output yaml
出力に、Service のクラスタ IP アドレスが表示されます。次に例を示します。
apiVersion: v1 kind: Service metadata: name: my-service … spec: clusterIP: fd12::5:9af clusterIPs: - fd12::5:9af - 172.16.12.197
クラスタノードで、Service を呼び出します。
curl IPV4_CLUSTER_IP curl [IPV6_CLUSTER_IP]
出力に「Hello world」というメッセージが表示されます。
Hello, world! Version: 2.0.0 Hostname: my-deployment-xxx
タイプ LoadBalancer
のデュアル スタック Service を作成する
LoadBalancer
タイプの Service のマニフェストは次のとおりです。
apiVersion: v1 kind: Service metadata: name: "my-lb-service" spec: selector: app: "try-dual-stack" type: "LoadBalancer" ipFamilyPolicy: "RequireDualStack" ipFamilies: - "IPv6" - "IPv4" ports: - port: 80 targetPort: 8080
このマニフェストを my-lb-service.yaml
という名前のファイルに保存して、Service を作成します。
kubectl --kubeconfig CLUSTER_KUBECONFIG apply -f my-lb-service.yaml
クラスタ マニフェストでは、LoadBalancer
タイプの Service に使用する IPv6 アドレスの範囲と IPv4 アドレスの範囲を指定しました。
loadBalancer: mode: "bundled" ... addressPools: - name: "pool-1" addresses: - "10.2.0.112-10.2.0.221" - "fd12::4:101-fd12::4:110"
Service には、IPv4 範囲から選択した外部 IPv4 アドレスと、IPv6 範囲から選択した外部 IPv6 アドレスが割り振られます。
Service の詳細を一覧表示します。
kubectl --kubeconfig CLUSTER_KUBECONFIG get service my-lb-service --output yaml
出力に、Service の外部アドレスが表示されます。次に例を示します。
apiVersion: v1 kind: Service metadata: name: my-lb-service ... status: loadBalancer: ingress: - ip: 10.2.0.213 - ip: fd12::4:101
ipFamilyPolicy
に取り得る値
デュアルスタック Service を作成する場合、ipFamilyPolicy
は次のいずれかの値に設定できます。
SingleStack
: コントローラが 1 つのクラスタ IP アドレスを Service に割り振ります。これは、clusterNetwork.services.cidrBlocks
に指定されたクラスタ マニフェストの最初の範囲から選択されます。PreferDualStack
: コントローラは、Service の IPv4 および IPv6 クラスタ IP アドレスを、クラスタ マニフェスト(clusterNetwork.services.cidrBlocks
の下)に指定された範囲から選択して割り振ります。クラスタがデュアル スタック クラスタでない場合、動作はSingleStack
の場合と同じです。RequireDualStack
: コントローラは、Service の IPv4 および IPv6 クラスタ IP アドレスを、クラスタ マニフェスト(clusterNetwork.services.cidrBlocks
の下)に指定された範囲から選択して割り振ります。Service マニフェスト(ipFamilies
の下)で指定された最初のアドレス ファミリーに基づいてspec.clusterIP
の値を設定します。
詳細
デュアルスタック サービスの作成方法については、新しい Service のデュアルスタック オプションをご覧ください。