手当たり次第に書くんだ

飽きっぽいのは本能

Kubernetes Nginx コンテナと Service NodePort – Node のポート経由でアクセスする

この記事では、Nginx の Deployment に NodePort Service を作成し、クラスタ外から Node の IP アドレスと固定ポートでアクセスする流れを確認します。

NodePort は、ClusterIP より一段外側へ Service を出す方式です。小規模な検証では便利ですが、本格的な公開方式としては扱いが粗くなりやすいため、役割と限界を理解して使う必要があります。

参考
書籍
参考書籍

Kubernetes 完全ガイド 第 2 版

Kubernetes の Service、ネットワーク、公開方式、運用設計を体系的に確認したい場合の参考書籍です。価格や在庫はリンク先で確認してください。

Amazon で見る

このリンクは Amazon アソシエイトリンクです。

NodePort の位置づけ

NodePort は、各 Node の特定ポートを開き、そのポートから Service へ転送する方式です。Node の IP アドレスと NodePort の組み合わせで、クラスタ外から Service にアクセスできます。

  • ClusterIP はクラスタ内部向け
  • NodePort は Node のポート経由で外部からアクセス可能
  • LoadBalancer は外部 IP アドレスを持つ Service
  • NodePort は検証や限定的な公開には便利だが、公開用の設計としては注意が必要

NodePort を本格公開に使いづらい理由

NodePort は分かりやすい方式ですが、実運用の公開方式としては課題があります。各 Node のポートを直接意識するため、ロードバランサー、DNS、ファイアウォール、証明書、障害時の切り替えといった設計を別途考える必要があります。

  • アクセス先が Node の IP アドレスに依存する
  • 30000-32767 などの NodePort 範囲を意識する必要がある
  • HTTP / HTTPS の入口としては Ingress や LoadBalancer の方が扱いやすい
  • 複数 Service が増えるとポート管理が煩雑になる
  • 外部公開の責任境界が曖昧になりやすい

Namespace と Deployment を作成する

まず確認用の Namespace を作成し、その中に Nginx の Deployment を作成します。Service の selector と一致するように、Pod には app: nginx の label を付けます。

kubectl create namespace nginx-nodeport-ns

kubectl -n nginx-nodeport-ns apply -f - <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80
EOF

NodePort Service を作成する

次に NodePort の Service を作成します。ここでは例として 30080 を明示しています。NodePort を省略すると、Kubernetes が範囲内のポートを自動割り当てします。

kubectl -n nginx-nodeport-ns apply -f - <<'EOF'
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - name: http
      port: 80
      targetPort: 80
      nodePort: 30080
EOF

Service と Endpoints を確認する

Service が作成されたら、Service、Endpoints、Pod の対応を確認します。NodePort でも Service の selector が Pod の label と一致していなければ通信できません。

kubectl -n nginx-nodeport-ns get deploy,pod,svc,endpoints -o wide
kubectl -n nginx-nodeport-ns describe svc nginx-svc
kubectl -n nginx-nodeport-ns get endpoints nginx-svc -o yaml

クラスタ内部から確認する

まずはクラスタ内部から Service 名で疎通できることを確認します。NodePort Service も内部的には ClusterIP を持つため、クラスタ内部からは Service 名でアクセスできます。

kubectl -n nginx-nodeport-ns run curl   --rm -it   --image=curlimages/curl   --restart=Never   -- curl -I http://nginx-svc/

クラスタ外から NodePort にアクセスする

Node の IP アドレスと NodePort を指定して、クラスタ外からアクセスします。どの Node にアクセスしても Service へ転送されるため、Pod が存在する Node を直接指定する必要はありません。

kubectl get nodes -o wide

NODE_IP=<node-ip>
curl -I http://${NODE_IP}:30080/

疎通できない場合は、Node のファイアウォール、経路、Service の NodePort、Endpoints、Pod の状態を順番に確認します。

切り分けの見る順番

NodePort で疎通できない場合は、Kubernetes 内部で成立しているか、Node のポートまで届いているかを分けて確認します。

  • Pod が Running になっているか
  • Service の selector と Pod の label が一致しているか
  • Endpoints に Pod の IP アドレスが入っているか
  • クラスタ内部から Service 名でアクセスできるか
  • Node の IP アドレスへクライアントから到達できるか
  • NodePort のポートがファイアウォールで閉じられていないか

後片付け

確認が終わったら、Namespace ごと削除します。

kubectl delete namespace nginx-nodeport-ns

関連する記事

Service の公開範囲は、ClusterIP、NodePort、LoadBalancer の順に広がります。NodePort の次は LoadBalancer と MetalLB を見るとつながりが分かりやすくなります。

まとめ

NodePort は、Node の固定ポート経由で Service へアクセスする方式です。ClusterIP より外部から確認しやすく、Kubernetes Service の動きを理解するには便利です。

一方で、Node の IP アドレスやポートを直接意識するため、本格的な外部公開には向かない場面も多いです。公開用の入口としては、Ingress、LoadBalancer、MetalLB などと組み合わせて設計する方が自然です。

Kubernetes Nginx コンテナと Service NodePort – Node のポート経由でアクセスする

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る