はじめに
以下記事にてKubernetesのサービスで利用するClusterIPとNodePortの違いについて説明しました。
その違いは K8sクラスタに所属していないマシンからポッド内に通信できるか否か です。
本記事ではそこからさらに踏み込んで、「どのポートをどの環境からつつけば接続できるのか?」「そのノードが落ちた場合にどういう動きになるのか?」に着目して整理しました。
環境情報
- 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番台がアサインされています。
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 ...
しかし、CLUSTER-IPは変わらず以下で各マシンからから接続できます。
# curl 10.Y.Y.Y:8080
NodePortのPortもそのまま利用できますが、IPはworker03を指定する必要があります。
# curl 10.X.X.103:3132X
終わりに
一般的に外部にサービスを公開する際はLoadBalancerを利用しますが、NodePortを利用する際はNodeのIPが変更されると接続する側で接続先を変更する必要がある点は抑えておきたいです。ただし、ポート番号は変化しません。
巷の記事を見てもWorkerノードが複数ある場合のイメージが分かりづらかったので、今回はその点を意識して可視化しました。NodePortへの理解が深まれば幸いです。