Azure Redhat Openshift で Carrier Grade NAT のアドレス範囲を使う
やってみたこと
Azure Redhat Openshift(ARO) で、Pod の IP アドレス範囲に Carrier Grade NAT(CGN)のアドレス範囲を使ってみました。
ただし、100.64.0.0/16 以外の範囲を使う必要があります。
クラスターで 100.64.0.0/16 IP アドレス範囲の一部を使用している場合、OVN-Kubernetes は内部的にこの IP アドレス範囲を使用するため、クラスターを OVN-Kubernetes に移行することはできません。
やりたいこと
Azure Redhat Openshift(ARO) では、ネットワークの要件として以下のような制約があります。
- ノードとマスターの仮想ネットワーク サブネットは、/27 以上である必要があります。
- デフォルト値のポッド CIDR は 10.128.0.0/14 です。
- デフォルト値のサービス CIDR は 172.30.0.0/16 です。
- ポッドとサービス ネットワークの CIDR は、ネットワークで使われている他のアドレスの範囲と重なってはいけません。 クラスターの仮想ネットワークの IP アドレスの範囲内にあってはいけません。
- ポッド CIDR は、/18 以上のサイズである必要があります。 (ポッド ネットワークはルーティング不可能な IP であり、OpenShift SDN 内でのみ使用されます)。
多くのコンテナ系のサービスに漏れず、ノードの IP アドレスと サービス/Pod の IP アドレス分のアドレス空間を確保する必要があります。
特に Pod のアドレス範囲の /18 は範囲がかなり広いです。通常の Web アプリケーションのようにインバウンドで利用するときは特に問題になりませんが、バッチ処理の時のようにアウトバウンドで不特定多数の宛先に接続が必要な場合、このアドレス範囲を確保することはなかなか難しいことがあると思います。
Azure のドキュメントでは IPv4 枯渇の対策として、CGN のアドレス範囲を使う方法を提案しておりこれが使えるのではと考えました。
Toru Makabe さんのこちらの資料も参考になります。
検証
Terraform でデプロイしてみました。
Terraform の azurerm モジュールに ARO のリソースが無いため、AzAPI を使う必要があります。networkProfile
でアドレス範囲が指定ができます。
networkProfile = {
podCidr = var.pod_cidr
serviceCidr = var.service_cidr
outboundType = var.outbound_type
}
podCidr で 10.101.0.0/16 を指定してみました。100.101. から始まる IP アドレスが割り当てられました。
azureuser@vmlinux-1:~$ oc get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 17d 100.101.10.7 aro-abcdecfgj-55b4s-worker-australiaeast3-h82tq <none> <none>
Pod から traceroute
をしてみると、外の世界に出られました。100.64 から始まる IP アドレスがいることが分かります。
azureuser@vmlinux-1:~$ oc exec -it nginx -- traceroute 1.1.1.1
traceroute to 1.1.1.1 (1.1.1.1), 30 hops max, 60 byte packets
1 one.one.one.one (1.1.1.1) 3.048 ms 3.232 ms 3.183 ms
2 100.64.0.7 (100.64.0.7) 3.806 ms 3.798 ms 3.785 ms
3 172.16.2.5 (172.16.2.5) 91.332 ms 172.16.2.6 (172.16.2.6) 91.349 ms 91.157 ms
4 * * *
Discussion