課題
お客様がROKS v4.14上に構築されたアプリに対して、アクセス元のIPアドレスを制限することを実施していました。
(背景として、お客様にはVPNを利用できない事情があり、ROKSのService EndpointはPublicとPrivateの両方も公開されるのが必要でした。IPアドレスの制限をかかないと、アプリはInternet向けに公開されてしまうことになります。)
その際には、下記の二つの記事を順番に参考して設定し、問題なく実現できました:
- @hisato_imanishi(Hisato Imanishi)さんのご記事: 「Red Hat OpenShift on IBM Cloudでアクセス元IPアドレスを制限する」
- 私の記事:「Red Hat OpenShift on IBM Cloudでアクセス元IPアドレスを制限する方法のご補足:Ingress Degradedエラーの解消方法」
ただし、最近IBM Cloud上の最新版のROKS v4.17を利用する時、上記の手順を実施してもエラーが出て、アプリへの通信が全く出来なくなりました。
この記事は、上記の問題の解決方法、つまり、ROKS v4.17でアクセス元IPアドレスを制限する方法をご説明いたします。
この記事を参照する前に、上記の2つの記事に目を通し、ROKSのセキュリティグループ(Security Group、SG)についての基本設定をご理解しておくことをお勧めします。
ROKS v4.17のSecurity Groupの説明
4.17のROKS clusterにおいては、デフォルトの自動設定として、下記の図のように四つのSecurity Groupが出ています。
上から順番に:
-
kube-[ROKS cluster ID]
このSGは、ClusterのWorker Nodeに関連付けられます。
ただし、SG の詳細ページでもWorker Nodeが表示されないのは、かなりわかりにくいです。(そもそも、ROKS Worker NodeがVSIとして表示されないためです。) -
kube-lbaas-[ROKS cluster ID]
このSGは、ALB(Application Load Balancer)に関連付けられます。 -
kube-vpegw-[ROKS cluster ID]
このClusterのAPI Server VPE(Virutal Private Endpoint)に関連付けられます。 -
kube-vpegw-[VPC ID]
ICOSやRegistryなどのVPE(Virutal Private Endpoint)に関連付けられます。
#3と#4は主にIBM Cloud内部の通信を制御しており、私たちの課題にはあまり関係していません。
#1と#2に対してRule変更が必要です。
課題解決のため、必要な設定変更
まずは、#2のALB用のSGを変更します
Best Practiceとして、デフォルトで作成されているSecurity Groupを変更せず、新しいものを作成し、Load Balancerに置き換えることがお勧めです。手順は:
- Security Groupの詳細画面で、ActionのところにDuplicateという選択肢があり、それをクリックして、新規作成の画面で新しいSGの名前を適当に入力します。私は新SG に「kube-lbaas-whitelist」という名前を付けました。
- 複製で作成された「kube-lbaas-whitelist」SGには、既に下記のような二つのOutbound Ruleが存在します。Destination typeがSecurity Groupであり、DestinationがWorker Node用のSG #1です。これは、「全てのWorker Nodeへの通信は、Portが32654か31277であれば、許可する」という意味です。
これらのOutbound Rulesを変更しないことが重要です。
なぜか、Port 32654と31277を許可するかと言いますと、
ClusterのWorker NodeはLoad BalancerのBack-end poolsのService Instancesであります。
つまり、外部からLoad BalancerのPort 443へのhttps requestは、Round robinの方法で一つのWorker NodeのPort 31277に転送します。同じく、Load BalancerのPort 80へのhttps requestは、 Worker NodeのPort 32564に転送します。
各Clusterで使用されるPort番号は必ずしも32654と31277に固定されているわけではありません。30000-32767の範囲からランダムに選択され、Load Balancerの詳細画面で確認できます。
- 「kube-lbaas-whitelist」SGのInbound Rulesを確認と変更しておきます。
上からの二つは:すべでのIncoming https requestは,Port 80と443で許可しています。
私たちの課題としては、Source IP Addressは社内のIP rangeであれば許可するため、この二つのInbound Rulesを削除するのが必要です。
上からの三番目のRuleは、Public Gateway(Floating IPが165.x.x.x)からの通信はPort 443で許可するとの意味です。私の記事「Red Hat OpenShift on IBM Cloudでアクセス元IPアドレスを制限する方法のご補足:Ingress Degradedエラーの解消方法」での説明とは一致しています。つまり、このInbound Ruleを変更せずに維持する必要があります。
(注:
私の検証環境では、Subnetは1つのみで、Public Gatewayも1つだけです。そのため、Public Gateway向けのInbound Ruleも1つになります。
一方、本番環境であれば、3つのDataCenterにWorker Nodeを配置することが多いため、SubnetとPublic Gatewayがそれぞれ3つとなり、こちらのInbound Ruleも3つとなります。)
これから、追加必要のInbound Ruleとして:
-
ROKS ClusterのControl Planeからの通信を許可するため、
TCP 80 CIDR 東京リージョンのControl IP Subnet(control-plane-ips-tok.txt)
--> v4.14頃の設定方法と同じで、Subnet自体にも変更なしです。 -
お客様の端末からの通信を許可するため、
TCPかALL 任意のポート CIDRかIPAddress 客様の端末のSubnetかIP Addr
Inbound Ruleの設定結果は、こうなります。
- Load BalancerのSecurity Groupを置き換えます。
次に、#1のWorker Node用のSGを変更します
設定変更がここまで進んだら、Load Balancerの状態を確認すると、Back-endが警告ステータスになっているはずです。
また、上記のようにLoad BalancerのSecurity Groupを置き換えてから約10分後に、Ingressもエラーの状態になるはずです。
もちろん、このような状況で、アプリへの通信も止まります。
そのエラーの原因は、下記の図の上から4番目と5番目のように、ROKS v4.17では、Worker Node用のSecurity Groupにも、Load Balancerからの通信を許可するInbound Ruleがありますから。
Load BalancerのSecurity Groupを置き換えましたので、ここでの 4 番目と 5 番目のRuleは実際には機能しなくとなります。 (ただし、削除しないことをお勧めします)。これらを参照して、新しい SG 「kube-lbaas-whitelist」のため 2 つのルールを追加する必要があります。設定結果はこうなります。
必要な設定変更は完了です。
最後に、効果の確認
まずは、Load Balancerとも、Ingressとも、Greenの状態となるはずです。
後は、許可された端末からアプリのWeb URLを訪問でき、他の端末から訪問できないはずです。
以上です。