(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

【Kubernetes】マルチノード環境のNodePortに対する疎通確認

スポンサーリンク

はじめに

以下記事にてKubernetesのサービスで利用するClusterIPとNodePortの違いについて説明しました。

その違いは K8sクラスタに所属していないマシンからポッド内に通信できるか否か です。

本記事ではそこからさらに踏み込んで、「どのポートをどの環境からつつけば接続できるのか?」「そのノードが落ちた場合にどういう動きになるのか?」に着目して整理しました。

f:id:mtiit:20200821112653p:plain
Kubernetes環境

環境情報
  • Red Hat Enterprise Linux 7.6
  • kubectl v1.15
  • calico v3.8

想定環境の補足

Nodeの確認結果を以下とします。

# kubectl get nodes -o=wide
NAME   STATUS   ROLES   ... INTERNAL-IP
master  Ready   master  10.X.X.100
worker01  Ready  worker 10.X.X.101
worker02  Ready  worker 10.X.X.102
worker03  Ready  worker 10.X.X.103

上の図にいるNotWorkerはクラスターに参加していないにで表示されません。
ここではマシンのIPアドレスは10.X.X.104とします。

この状態でmaster上でnginxのDeploymentを作成すると以下のようにworker01に展開されました。

kubectl get pod
NAME   READY  STATUS  ... IP    Node  ...
nginx-xxx   1/1   Runnng  ... 192.168.X.70   worker01 ...

PodにはIPが付与されます。

NodePort作成前の疎通確認

この状態でnginxにアクセスするために、Podが開いている80番ポートめがけて以下のコマンドで確認します。

# curl 192.168.X.70

コマンドを打つサーバ毎に結果をまとめました。

コマンド発行サーバ 結果
master O
worker01 O
worker02 O
worker03 O
notworker X

要は、Kubernetesのクラスターに参加しているNodeからPodのIPアドレスに対して通信が可能です。
各実機で静的経路を確認すると以下のようにPodのIPアドレスがNodeにルーティングされる設定が入っています。

# ip route
...
192.168.X.X/26 via 10.X.X.101 dev tun0 proto bird onlink
...

notworkerにはこの設定が入っていないので疎通できません。

NodePort作成

以下でNodePortのServiceを作成します。

# kubectl expose deployment nginx --port=8080 --target-port=80 --name=nginx-nodep --type=NodePort

以下のServiceが作成されました。

kubectl get service
NAME   TYPE  CLUSTER-IP  EXTERNAL-IP   PORT(S) ...
nginx-nodep  NodePort   10.Y.Y.Y   <none>   8080:3132X/TCP  ...

上を見れば分かる通り、CLUSTER-IPとして新たなIPがアサインされ、PORTとして30000番台がアサインされています。

f:id:mtiit:20200821115114p:plain
IPアドレスが新たに採番される

NodePortの疎通確認

まずはNodePortによってクラスタ外のサーバからアクセスできることの確認のために以下コマンドを押下すると

# curl 10.X.X.101:3132X

以下の結果となります。

コマンド発行サーバ 結果
master O
worker01 O
worker02 O
worker03 O
notworker O

ではNodeが展開されていないNodeを宛先にするとどうでしょうか。

# curl 10.X.X.102:3132X

以下の結果となります。

コマンド発行サーバ 結果
master X
worker01 X
worker02 X
worker03 X
notworker X

NodePortはPodが展開されているNodeに対してのみ疎通が可能です。

次に各マシンからClusterIPに対してコマンドを押下すると

# curl 10.Y.Y.Y:8080

以下の結果となります。

コマンド発行サーバ 結果
master O
worker01 O
worker02 O
worker03 O
notworker X

PodのIPアドレスに対してコマンド実行した結果と同じになります。

Node01を落とす

Masterからworker01を落とすと

# kubectl drain worker01 --ignore-daemonsets

Podは空きノードに移動します。

kubectl get pod
NAME   READY  STATUS  ... IP    Node  ...
nginx-zzz   1/1   Runnng  ... 192.168.Z.72   worker03 ...

f:id:mtiit:20200821120304p:plain
Podが移動してIPが変化する

しかし、CLUSTER-IPは変わらず以下で各マシンからから接続できます。

# curl 10.Y.Y.Y:8080

NodePortのPortもそのまま利用できますが、IPはworker03を指定する必要があります。

# curl 10.X.X.103:3132X

終わりに

一般的に外部にサービスを公開する際はLoadBalancerを利用しますが、NodePortを利用する際はNodeのIPが変更されると接続する側で接続先を変更する必要がある点は抑えておきたいです。ただし、ポート番号は変化しません。

巷の記事を見てもWorkerノードが複数ある場合のイメージが分かりづらかったので、今回はその点を意識して可視化しました。NodePortへの理解が深まれば幸いです。