1. はじめに
ROKS(Red Hat OpenShift on IBM Cloud)における、VPC Load Balancer(NLB)経由でアクセスする際のアクセス経路の確認を実施した。重要なのは、
- ROKSでService(type=Load Balancer)ではVPC Load BalancerのタイプとしてALBだけではなく、NLBも選択できる。
- ALBとNLBの違いはこちらを参照。
- 設定方法: https://cloud.ibm.com/docs/openshift?topic=openshift-vpc-lbaas#setup_vpc_nlb
- VPC LoadBalancer(NLB)は、確かに他のZoneのVSIにはトラフィックを割り振ることができない。ただし、externalTrafficPolicy=Clusterにしておけば、ROKS内のService(実態はiptables)経由で別のZoneにあるPodには接続できる。
2. 環境の作成
アプリのデプロイ
$ oc new-app -i php https://github.com/nin2yasu/samplephp
$ oc scale --replicas=2 deployment/samplephp
samplephp-nlb.yaml
apiVersion: v1
kind: Service
metadata:
name: samplephp-vpc-nlb-tokyo1
annotations:
service.kubernetes.io/ibm-load-balancer-cloud-provider-enable-features: "nlb"
service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type: "private"
service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-subnets: "02e7-cc434307-168d-4cb8-bbde-eb45839c8e59"
service.kubernetes.io/ibm-load-balancer-cloud-provider-zone: "jp-tok-1"
spec:
type: LoadBalancer
selector:
deployment: samplephp
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 8080
- name: https
protocol: TCP
port: 8443
targetPort: 8443
externalTrafficPolicy: Cluster
NLBのデプロイ
$ oc apply -f samplephp-nlb.yaml
3. 環境の確認
この環境はWorker Nodeが2つしかないが、それで十分動作確認できる。
WorkerNodeは2つしか存在しないが、Zoneにまたがって配置されている。
$ oc get nodes -L topology.kubernetes.io/zone
NAME STATUS ROLES AGE VERSION ZONE
10.0.0.25 Ready master,worker 27d v1.20.0+9689d22 jp-tok-1
10.1.0.17 Ready master,worker 27d v1.20.0+9689d22 jp-tok-2
今回作成されたVPC LoadBalancer(NLB)は同一Zone上のWorker nodeにしか割り振りを行っていない(VSIの数が1つ)
対象のアプリは異なるWorkerNodeにまたがって配置されている(=Zoneにまたがって配置されている)
$ oc get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
samplephp-1-build 0/1 Completed 0 68m 172.17.34.49 10.0.0.25 <none> <none>
samplephp-5d89c54548-28t56 1/1 Running 0 58m 172.17.28.90 10.1.0.17 <none> <none>
samplephp-5d89c54548-csm9n 1/1 Running 0 67m 172.17.34.4 10.0.0.25 <none> <none>
Endpointにもちゃんと異なるZone上に存在するPodが登録されている。
$ oc describe endpoints samplephp-vpc-nlb-tokyo1
Name: samplephp-vpc-nlb-tokyo1
Namespace: syasuda1
Labels: <none>
Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2021-10-12T00:29:43Z
Subsets:
Addresses: 172.17.28.90,172.17.34.4
NotReadyAddresses: <none>
Ports:
Name Port Protocol
---- ---- --------
https 8443 TCP
http 8080 TCP
Events: <none>
4. Podを一方のZoneに片寄せしてみてテスト
deploymentに以下のnodeSelectorを設定し、Podが必ずVPC LoadBalancer(NLB)とは別のZoneに配置されるように構成。
nodeSelector:
topology.kubernetes.io/zone: jp-tok-2
$ oc get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
samplephp-1-build 0/1 Completed 0 84m 172.17.34.49 10.0.0.25 <none> <none>
samplephp-77f8845999-w9cc7 1/1 Running 0 18s 172.17.28.67 10.1.0.17 <none> <none>
samplephp-77f8845999-zjr28 1/1 Running 0 15s 172.17.28.73 10.1.0.17 <none> <none>
これでも、Direct Link越しにちゃんとアクセスできることを確認(Power Systems Virtual Server(AIX)から接続確認)。
bash-4.3# oslevel -s
7200-04-01-1939
bash-4.3# curl http://eec704cd-jp-tok.lb.appdomain.cloud:8080
Host: eec704cd-jp-tok.lb.appdomain.cloud:8080 <br>
User-Agent: curl/7.52.1 <br>
Accept: */* <br>
ただし、当然ながらexternalTrafficPolicy=Local
の場合は、接続対象のPodがないため接続に失敗する
$ oc get svc samplephp-vpc-nlb-tokyo1 -o jsonpath={.spec.externalTrafficPolicy}
Local
bash-4.3# oslevel -s
7200-04-01-1939
bash-4.3# curl http://eec704cd-jp-tok.lb.appdomain.cloud:8080
(無応答)