
目次
はじめに
こんにちは、クラウド事業部の照屋です。
今回はOKE及び、Kubernetesをもっと理解するために、
Podの挙動について見ていこうと思います。
どんなひとに読んで欲しい
- Kubernetesを学習し始めた人
- Podについて知見を深めたい人
関連記事
【OCI】OKEの疎通確認techblog.ap-com.co.jp
リソース確認
ノードプール2つ、各ノードプールにワーカーノード1台とワーカーノード2台が存在している状態です。
↓

やりたいこと①
前提、Podは常に同じノード上で実行され続けるものではありません。Podの寿命は短命なので、削除されては再作成されるを繰り返しています。
特に設定がなければ、デフォルトとしてPodの移動範囲はクラスタ全体になります。(※ノードプールを跨いで再作成される)
ラベルセレクターを利用することで、Podが再作成される際に、どのノード上に再作成されるかを制限することができます。
まずは何も設定せずにデフォルトの挙動を確認します。
その後、ラベルセレクターで特定のノードプールに制限してみたいと思います。
事前準備
Deploymentのマニフェストファイル(YAML)を作成し、Nginxをデプロイします。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: docker.io/library/nginx:1.14.2
ports:
- containerPort: 80
挙動確認①
Podのステータスを確認します。
[opc@bation ~]$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-75b6b65ddb-tl8nh 1/1 Running 0 16h 10.0.1.107 10.0.1.30nginx-deployment-75b6b65ddb-wh5bn 1/1 Running 0 16h 10.0.1.116 10.0.1.30
意図的にPodを削除→再作成の動きを見ていきます。
別ターミナルでPodの動きを監視します。
[opc@bation ~]$ kubectl delete pod nginx-deployment-75b6b65ddb-tl8nh pod "nginx-deployment-75b6b65ddb-tl8nh" deleted
「nginx-deployment-75b6b65ddb-tl8nh」のNginx Podを削除しました。
Podが削除後、自動で再作成されているのが分かります。
[opc@bation ~]$ kubectl get pods -w NAME READY STATUS RESTARTS AGE nginx-deployment-75b6b65ddb-tl8nh 1/1 Running 0 16h nginx-deployment-75b6b65ddb-wh5bn 1/1 Running 0 16h nginx-deployment-75b6b65ddb-tl8nh 1/1 Terminating 0 16h nginx-deployment-75b6b65ddb-tl8nh 1/1 Terminating 0 16h nginx-deployment-75b6b65ddb-4l6gm 0/1 Pending 0 1s nginx-deployment-75b6b65ddb-4l6gm 0/1 Pending 0 1s nginx-deployment-75b6b65ddb-4l6gm 0/1 ContainerCreating 0 1s nginx-deployment-75b6b65ddb-tl8nh 0/1 Completed 0 16h nginx-deployment-75b6b65ddb-tl8nh 0/1 Completed 0 16h nginx-deployment-75b6b65ddb-tl8nh 0/1 Completed 0 16h nginx-deployment-75b6b65ddb-4l6gm 1/1 Running 0 7s
Podのステータスを確認します。
10.0.1.30のワーカーノード上で実行されていたのが、
再作成後は、10.0.1.61のワーカーノード上で実行されているのが確認できます。
ノードプールを跨いで、Podがデプロイされるデフォルトの挙動を確認することができました。
[opc@bation ~]$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-75b6b65ddb-4l6gm 1/1 Running 0 25s 10.0.1.104 10.0.1.61nginx-deployment-75b6b65ddb-wh5bn 1/1 Running 0 16h 10.0.1.116 10.0.1.30
次に、ラベルセレクターでPodの移動を特定のノードプール内に制限していきます。
特定のワーカーノードに制限したい場合は、そのワーカーノードのみにラベルを付与することで実現可能です。
今回は、my-pool2というノードプールに制限してみます。
my-pool2にあるワーカーノード2台にtarget-node=web-app-01というラベルを付与します。
[opc@bation ~]$ kubectl get nodes NAME STATUS ROLES AGE VERSION 10.0.1.30 Ready node 3d14h v1.34.2 10.0.1.61 Ready node 3h47m v1.34.2 10.0.1.96 Ready node 3h47m v1.34.2 [opc@bation ~]$ kubectl label nodes 10.0.1.61 target-node=web-app-01 node/10.0.1.61 labeled [opc@bation ~]$ kubectl label nodes 10.0.1.96 target-node=web-app-01 node/10.0.1.96 labeled
↓
ラベルが付与されていることが確認できました。
[opc@bation ~]$ kubectl get nodes --show-labels | grep target-node=web-app-01 10.0.1.61 Ready node 3h50m v1.34.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=VM.Standard.E5.Flex,beta.kubernetes.io/os=linux,displayName=oke-c3jths47lcq-nttaafuvupa-sbke6szcnrq-1,failure-domain.beta.kubernetes.io/region=ap-tokyo-1,failure-domain.beta.kubernetes.io/zone=AP-TOKYO-1-AD-1,hostname=oke-c3jths47lcq-nttaafuvupa-sbke6szcnrq-1,internal_addr=10.0.1.61,kubernetes.io/arch=amd64,kubernetes.io/hostname=10.0.1.61,kubernetes.io/os=linux,last-migration-failure=get_kubesvc_failure,name=my-pool2,node-role.kubernetes.io/node=,node.info.ds_proxymux_client=true,node.info/compartment.id=aaaaaaaazsmde7hqsny6dbsvnlbbqsze6jsrfxka6e3seas6xhj46im52rsq,node.info/compartment.name=test_teruya,node.info/kubeletVersion=v1.34,node.kubernetes.io/instance-type=VM.Standard.E5.Flex,oci.oraclecloud.com/fault-domain=FAULT-DOMAIN-2,oci.oraclecloud.com/host.id=493ba568f11,oci.oraclecloud.com/host.rack_id=eccc3d93c4e,oci.oraclecloud.com/ip-family-ipv4=true,oci.oraclecloud.com/ip-family-preferred=ipv4,oci.oraclecloud.com/node.info.managed=true,oci.oraclecloud.com/vcn-native-ip-cni=true,oke.oraclecloud.com/node.info.private_subnet=true,oke.oraclecloud.com/node.info.private_worker=true,target-node=web-app-01,topology.kubernetes.io/region=ap-tokyo-1,topology.kubernetes.io/zone=AP-TOKYO-1-AD-1 10.0.1.96 Ready node 3h49m v1.34.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=VM.Standard.E5.Flex,beta.kubernetes.io/os=linux,displayName=oke-c3jths47lcq-nttaafuvupa-sbke6szcnrq-0,failure-domain.beta.kubernetes.io/region=ap-tokyo-1,failure-domain.beta.kubernetes.io/zone=AP-TOKYO-1-AD-1,hostname=oke-c3jths47lcq-nttaafuvupa-sbke6szcnrq-0,internal_addr=10.0.1.96,kubernetes.io/arch=amd64,kubernetes.io/hostname=10.0.1.96,kubernetes.io/os=linux,last-migration-failure=get_kubesvc_failure,name=my-pool2,node-role.kubernetes.io/node=,node.info.ds_proxymux_client=true,node.info/compartment.id=aaaaaaaazsmde7hqsny6dbsvnlbbqsze6jsrfxka6e3seas6xhj46im52rsq,node.info/compartment.name=test_teruya,node.info/kubeletVersion=v1.34,node.kubernetes.io/instance-type=VM.Standard.E5.Flex,oci.oraclecloud.com/fault-domain=FAULT-DOMAIN-1,oci.oraclecloud.com/host.id=c9e3e9e733c,oci.oraclecloud.com/host.rack_id=112ecddc753,oci.oraclecloud.com/ip-family-ipv4=true,oci.oraclecloud.com/ip-family-preferred=ipv4,oci.oraclecloud.com/node.info.managed=true,oci.oraclecloud.com/vcn-native-ip-cni=true,oke.oraclecloud.com/node.info.private_subnet=true,oke.oraclecloud.com/node.info.private_worker=true,target-node=web-app-01,topology.kubernetes.io/region=ap-tokyo-1,topology.kubernetes.io/zone=AP-TOKYO-1-AD-1
マニフェストファイル(YAML)に、nodeSelector:を追加します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: docker.io/library/nginx:1.14.2
ports:
- containerPort: 80
nodeSelector:
target-node: web-app-01
更新かけます。
[opc@bation ~]$ kubectl apply -f pod.yaml deployment.apps/nginx-deployment configured
Podのステータスを確認します。
my-pool2にあるワーカーノードにPodが存在していることが確認できます。
[opc@bation ~]$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-55487c76b9-cnq4l 1/1 Running 0 12s 10.0.1.159 10.0.1.96nginx-deployment-55487c76b9-jr5wn 1/1 Running 0 5s 10.0.1.136 10.0.1.61
削除→再作成後もmy-pool1のワーカーノードに移動することはないか確認してみます。
[opc@bation ~]$ kubectl delete pod nginx-deployment-55487c76b9-cnq4l pod "nginx-deployment-55487c76b9-cnq4l" deleted [opc@bation ~]$ [opc@bation ~]$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-55487c76b9-ghls9 1/1 Running 0 6s 10.0.1.201 10.0.1.96nginx-deployment-55487c76b9-jr5wn 1/1 Running 0 7m6s 10.0.1.136 10.0.1.61 [opc@bation ~]$ [opc@bation ~]$ kubectl delete pod nginx-deployment-55487c76b9-jr5wn pod "nginx-deployment-55487c76b9-jr5wn" deleted [opc@bation ~]$ [opc@bation ~]$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-55487c76b9-68bs6 1/1 Running 0 4s 10.0.1.73 10.0.1.61 nginx-deployment-55487c76b9-ghls9 1/1 Running 0 36s 10.0.1.201 10.0.1.96
my-pool2内でのみ移動するだけで、ノードプールを跨いだ移動は確認できませんでした。(Podの移動がmy-pool2ノードプール内に制限されてそうです…!)
参考
やりたいこと②
クライアント(VM)からFLBを経由してPodにアクセスする場合、
1. FLB → ワーカーノード
2. ワーカーノード → Pod
二段階で通信が転送されていきます。これがデフォルトの通信経路になります。
OKEでは、FLBのバックエンドとしてワーカーノードではなく、Podを指定することで、
ワーカーノードを完全にバイパスし、直接PodのIPアドレスに転送するように設定することができます。
通信経路としては、クライアント(VM)→FLB→Pod(直接Podに届く)になります。
FLBのバックエンドをPodにするメリット
ネットワーク効率の向上:
中間ノードでのルーティングを排除することで、ネットワークの輻輳とオーバーヘッドが削減されます。
最適化されたリソース使用率:
正常なポッドのみがバックエンドとして登録されるため、バックエンドの管理が簡素化され、スケーラビリティが向上する可能性があります。
よりシンプルなヘルスチェック:
ロード バランサは各アプリケーションポッドを直接プローブするため、ヘルスモニタリングの精度が向上します。
ノードの負荷軽減:
ノードからトラフィックをオフロードすると、処理の負担が軽減され、アプリケーションのパフォーマンスがより予測可能になります。
バックエンドとしてポッドを使用するための前提条件
- OKEクラスタの Kubernetes バージョンは1.30 以降であること
- クラスタ作成時に、ネットワーク・タイプとして「VCNネイティブ・ポッド・ネットワーク」を選択していること
事前準備②
- OKEクラスタの Kubernetes バージョンは1.30 以降であること
→クラスタ本体のバージョンを確認します。
[opc@bation ~]$ kubectl version Client Version: v1.33.7+1.el9 Kustomize Version: v5.6.0 Server Version: v1.34.2
Server Version: v1.34.2なので、条件を満たしていることが確認できました。
- クラスタ作成時に、ネットワーク・タイプとして「VCNネイティブ・ポッド・ネットワーク」を選択していること
→OKEクラスタ構築時に「VCNネイティブ・ポッド・ネットワーク」で作成している前提で進めます。
FLBを経由してPodにアクセスするため、ロードバランサを作成しておきます。
ここで、アプリをデプロイするために作成したDeploymentのマニフェストファイル(YAML)に、
type: LoadBalancerを追記してしまうとエラーになってしまいます。
なぜか?
→アプリをデプロイする用のマニフェストファイル(Deployment)と
通信を制御する用のマニフェストファイル(Service)があるからです。
type: LoadBalancerは、Serviceに書く必要があります。
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: 80
Serviceを適用していきます。
[opc@bation ~]$ kubectl apply -f nginx-service.yaml service/nginx-service created [opc@bation ~]$ kubectl get svc -w NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1443/TCP,12250/TCP 3d22h nginx-service LoadBalancer 10.96.200.18 80:32627/TCP 12s nginx-service LoadBalancer 10.96.200.18 161.33.214.206 80:32627/TCP 19s
コンソール画面からロードバランサが作成されていることが確認できました。

事前知識
デフォルトの動きを確認していく前に、
externalTrafficPolicyとは何か?について触れておこうと思います。
externalTrafficPolicyには、
Cluster(デフォルト)と、Localという値が設定できます。
※明示的に指定しない(省略する)場合、デフォルト値であるClusterが適用されます。
externalTrafficPolicy: Clusterの場合、
FLBからの通信がどのワーカーノードに届いても、全ワーカーノードのPodへ転送できます。
但し、送信元IPアドレスは保持されないため、Podに届く通信の送信元IPは、クライアントのIPではなく、ワーカーノードのプライベートIPになります。
externalTrafficPolicy: Localの場合、
FLBからの通信がワーカーノードAに届いた場合、ワーカーノードA上で動いているPodにのみ通信は渡されます。
この時、送信元IPアドレスは保持されるため、Podに届く通信の送信元IPは、クライアントのIPになります。
※今回はFLBを経由するため、FLBがバックエンドのアクセスに使用するバックエンドIPになるはずです。
参考
KubernetesのServiceのexternalTrafficPolicyとinternalTrafficPolicyって何?
挙動確認②
デフォルトの動きについて確認していきます。
まず、VM(Bastionサーバ)からFLBに向けてcurlコマンドを投げます。
[opc@bation ~]$ curl -I http://161.33.214.206 HTTP/1.1 200 OK Server: nginx/1.14.2 Date: Thu, 12 Feb 2026 05:43:47 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 04 Dec 2018 14:44:49 GMT Connection: keep-alive ETag: *********** Accept-Ranges: *****
200が返ってきたので、通信はPodまで到達できていることが確認できます。
では、通信が本当に「デフォルト経路」で到達したかを確認したいと思います。
※externalTrafficPolicy: Cluster
Pod名を確認します。
[opc@bation ~]$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-55487c76b9-68bs6 1/1 Running 2 46h 10.0.1.104 10.0.1.61nginx-deployment-55487c76b9-ghls9 1/1 Running 2 46h 10.0.1.159 10.0.1.96
ワーカーノードA(10.0.1.61)にいるPod が nginx-deployment-55487c76b9-68bs6
ワーカーノードB(10.0.1.96)にいるPod が nginx-deployment-55487c76b9-ghls9
↓
[opc@bation ~]$ kubectl logs nginx-deployment-55487c76b9-68bs6
10.0.1.96 - - [12/Feb/2026:05:29:53 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 zgrab/0.x" "-"
10.0.1.61 - - [12/Feb/2026:05:33:13 +0000] "\x16\x03\x02\x01o\x01\x00\x01k\x03\x02RH\xC5\x1A#\xF7:N\xDF\xE2\xB4\x82/\xFF\x09T\x9F\xA7\xC4y\xB0h\xC6\x13\x8C\xA4\x1C=\x22\xE1\x1A\x98 \x84\xB4,\x85\xAFn\xE3Y\xBBbhl\xFF(=':\xA9\x82\xD9o\xC8\xA2\xD7\x93\x98\xB4\xEF\x80\xE5\xB9\x90\x00(\xC0" 400 173 "-" "-" "-"
2026/02/12 05:42:45 [error] 6#6: *3 open() "/usr/share/nginx/html/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php" failed (2: No such file or directory), client: 10.0.1.30, server: localhost, request: "POST /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php HTTP/1.1", host: "161.33.214.206:80"
10.0.1.30 - - [12/Feb/2026:05:42:45 +0000] "POST /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php HTTP/1.1" 404 571 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" "-"
10.0.1.96 - - [12/Feb/2026:05:43:47 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.76.1" "-"
10.0.1.96 - - [12/Feb/2026:05:51:32 +0000] "POST / HTTP/1.1" 405 173 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" "-"
10.0.1.61上にあるPodのログを見ると、送信元IPが10.0.1.96になっており、ワーカーノードBから通信が届いています。
つまり、先ほどのクライアントからの通信は、FLBを経由して、ワーカーノードBに到達し、ワーカーノードBからワーカーノードA上にあるPodに転送されたことが分かります。(externalTrafficPolicy: Clusterの挙動が確認できましたね!)
本稿の趣旨から少し脱線してしまいますが、
ついでにexternalTrafficPolicy: Localに設定した場合の挙動も見ておきたいと思います。
Service(nginx-service.yaml)を下記の通りに書き替えます。
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: LoadBalancer
externalTrafficPolicy: Local
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: 80
変更を適用します。
[opc@bation ~]$ kubectl apply -f nginx-service.yaml service/nginx-service configured
もう一度curlを投げて、200が返ってくることを確認します。
[opc@bation ~]$ curl -I http://161.33.214.206 HTTP/1.1 200 OK Server: nginx/1.14.2 Date: Thu, 12 Feb 2026 06:40:38 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 04 Dec 2018 14:44:49 GMT Connection: keep-alive ETag: "5c0692e1-264" Accept-Ranges: bytes
ワーカーノードAのPodのログを確認していきます。
[opc@bation ~]$ kubectl logs nginx-deployment-55487c76b9-68bs6 10.0.1.61 - - [12/Feb/2026:06:10:50 +0000] "GET /security.txt HTTP/1.1" 404 169 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" "-" 10.0.1.96 - - [12/Feb/2026:06:23:30 +0000] "GET / HTTP/1.1" 200 612 "-" "Wget" "-" 10.0.2.64 - - [12/Feb/2026:06:40:38 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.76.1" "-"
ロードバランサがあるサブネットのCIDR(10.0.2.0/24)から割り当てられたバックエンドIPが、送信元IPになっていることが確認できます。
一通りの挙動が確認できたところで、
最後に、バックエンドとしてPodを指定し、クライアント(VM)から直接Podに通信が届くのかを確認していきます。
事前準備③
Kubernetesエンジンは、oci-cloud-controller-manager (CCM)を使用して、Kubernetes サービス用のロードバランサをプロビジョニングします。
oci-cloud-controller-manager (CCM)がNSGを自動管理できるように、必要なIAM ポリシーを付与しておきます。
ALLOW any-user to manage network-security-groups in compartment <compartment-name> where request.principal.type = 'cluster'
※制御方法としては、NSGとセキュリティ・リストがありますが、
今回はOracleの推奨であるNSGで設定していきます。
参考
ロードバランサーとネットワークロードバランサーのセキュリティルール管理オプションの指定
次に、Serviceにoci.oraclecloud.com/security-rule-management-mode: "NSG"の追加と、管理対象のNSGのOCIDを記述します。
ここで設定するNSGはPod用のNSGになります。
ワーカーノードには、プライマリVNICとセカンダリVNICがあります。
プライマリVNICにアタッチされているNSGでワーカーノード側を制御し、セカンダリVNICにアタッチされているNSGでPod側を制御できるようになっています。
ServiceにNSGを記述しておくことで、CCMが対象のNSGに対して自動でルールの追加や削除を行えるようになりますので、
NSGを新規作成するだけで、中身のルールは手動で追加する必要がありません。
※FLB用のNSGについては、自動でNSGを新規作成のうえ必要なルールを追加して、FLBにアタッチまでしてくれます。

挙動確認③
OCI公式ドキュメントを参考にしながら、Serviceのマニフェストファイルを下記の通りに書き換えていきます。
現在はまだバックエンドがワーカーノードになっていますが、
ServiceのマニフェストファイルにallocateLoadBalancerNodePorts: falseを含めることで、NodePortの割り当てを無効にします。
=「1. FLB → ワーカーノード」の経路自体を作らないように設定します。
+oci.oraclecloud.com/load-balancer-backend-set-type: "IP"を記述することで、バックエンドをPodに設定することができるようになります。
apiVersion: v1 kind: Service metadata: name: nginx-service annotations: oci.oraclecloud.com/load-balancer-backend-set-type: "IP" oci.oraclecloud.com/load-balancer-type: "lb" oci-load-balancer.oraclecloud.com/health-check: '{"protocol": "HTTP", "port": 80, "urlPath": "/", "returnCode": 200, "retries": 3, "timeoutInMillis": 3000}' oci.oraclecloud.com/security-rule-management-mode: "NSG" oci.oraclecloud.com/oci-backend-network-security-group: "<nsg-ocid>" spec: type: LoadBalancer selector: app: nginx ports: - name: http port: 80 targetPort: 80 allocateLoadBalancerNodePorts: false
変更を適用させるために一度Serviceを削除して再作成します。
[opc@bation ~]$ kubectl delete svc nginx-service service "nginx-service" deleted
↓
ロードバランサが削除されていることを確認します。
↓
[opc@bation ~]$ kubectl apply -f nginx-service.yaml service/nginx-service created

curlを投げて、結果を確認していきます。
[opc@bation ~]$ curl -I http://132.226.7.70 HTTP/1.1 200 OK Server: nginx/1.14.2 Date: Sun, 15 Feb 2026 15:34:36 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 04 Dec 2018 14:44:49 GMT Connection: keep-alive ETag: "5c0692e1-264" Accept-Ranges: bytes
送信元IPを確認するために、Podのログも確認していきます。
[opc@bation ~]$ kubectl logs nginx-deployment-75b6b65ddb-fh4lm
10.0.2.140 - - [15/Feb/2026:15:34:27 +0000] "GET / HTTP/1.1" 200 612 "-" "-" "-"
10.0.2.140 - - [15/Feb/2026:15:34:28 +0000] "GET / HTTP/1.1" 200 612 "-" "-" "-"
10.0.2.140 - - [15/Feb/2026:15:34:36 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.76.1" "-"
10.0.2.140 - - [15/Feb/2026:15:34:37 +0000] "GET / HTTP/1.1" 200 612 "-" "-" "-"
送信元IPとして、ロードバランサーサブネットのCIDR(10.0.2.0/24)から割り当てられたバックエンドIPを確認できました!
が、ちょっと気になるのは、この通信は本当にNodePort(ワーカーノード)を通っていないのか?という点です。
ワーカーノードサブネットとPodサブネットを分けている場合は、バックエンド・セットの詳細画面にて、バックエンドのIPアドレスがワーカーノードからPodに変わっているので問題ないと思いますが、
同じサブネットにしていた場合は、ログの結果だけでは、externalTrafficPolicy: Localに設定したときとの違いが分からないですね。
ということで、FLB→Podに直接通信が届いているのかを確認するために、ワーカーノード用のNSGと、ワーカーノードサブネットにアタッチされているセキュリティリストのすべてのルールを削除してみたいと思います。
■NSG

■セキュリティリスト

Serviceを再適用してロードバランサを作成していきます。

問題なく通信できていることが確認できました!
これにより、FLB→Podに直接通信が届いていることが証明できたかと思います。
[opc@bation ~]$ curl -I http://138.2.23.218 HTTP/1.1 200 OK Server: nginx/1.14.2 Date: Sun, 15 Feb 2026 15:51:46 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 04 Dec 2018 14:44:49 GMT Connection: keep-alive ETag: "5c0692e1-264" Accept-Ranges: bytes
参考
おわりに
今回はPodの挙動に焦点を当てましたが、
Kubernetesは奥が深いので、また気になることがあった際は検証しようと思います。
お知らせ
私達クラウド事業部はクラウド技術を活用したSI/SESのご支援をしております。
また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。