0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【KCNA】KubernetesでNamespaceとServiceを使う|ClusterIP・NodePort・名前解決の確認(Part4)

0
Posted at

はじめに

KubernetesでNamespaceを作成し、その中に配置したNginxをService経由で利用します。

本記事では、以下を確認します。

  • Namespaceによるリソースの整理
  • ClusterIP Serviceによるクラスタ内部への公開
  • Serviceの接続先の確認
  • クラスタ内での名前解決とHTTP通信
  • NodePort Serviceの作成
  • port-forwardによるローカルからの接続確認

1. 前提条件

前の記事で作成したkindのtrainingクラスタを使用します。

操作前に、接続先を確認してください。

kubectl config current-context

想定するコンテキストは以下です。

kind-training

必要に応じて切り替えます。

kubectl config use-context kind-training

本記事では、対象の名前空間を-n kcnaで明示します。出力例のPod名、IPアドレス、NodePort番号などは、環境によって異なります。

2. Namespaceを作成する

学習用のNamespaceとして、kcnaを作成します。

kubectl create namespace kcna
kubectl get namespaces

kcnaのSTATUSがActiveになっていることを確認します。

Namespaceの役割

Namespaceは、Deployment・Pod・Serviceなどのリソースをクラスタ内で論理的に分ける仕組みです。

たとえば、異なるNamespaceには、同じ名前のDeploymentやServiceを作成できます。

ただし、Namespaceを分けただけでは、Namespace間の通信は遮断されません。通信制限には、NetworkPolicyと、それを実装するネットワーク機能などが必要です。

参考:Kubernetes公式ドキュメント:Namespaces

3. Namespaceにアプリケーションを配置する

kcnaに、NginxのPodを2つ管理するDeploymentを作成します。

kubectl -n kcna create deployment app \
  --image=nginx:1.27 --replicas=2

起動完了を待ち、Podとラベルを確認します。

kubectl -n kcna rollout status deployment/app
kubectl -n kcna get pods --show-labels

出力例:

NAME                     READY   STATUS    RESTARTS   AGE   LABELS
app-7c4db8785b-d6h2j      1/1     Running   0          23s   app=app,pod-template-hash=7c4db8785b
app-7c4db8785b-j9hwx      1/1     Running   0          23s   app=app,pod-template-hash=7c4db8785b

コマンドの解説

項目 意味
-n kcna 操作対象のNamespaceを指定
create deployment app appというDeploymentを作成
--image=nginx:1.27 コンテナイメージとタグを指定
--replicas=2 希望するPod数を2つに指定
--show-labels リソースのラベルを表示

今回のコマンドで作成されるPodには、app=appラベルが付与されます。このラベルは、次に作成するServiceが対象のPodを選ぶ際にも使用されます。

4. ClusterIP Serviceを作成する

Deployment appを対象とするServiceを作成します。

kubectl -n kcna expose deployment app \
  --port=80 --target-port=80 --name=app-svc

コマンドの解説

項目 意味
expose deployment app Deploymentの情報をもとにServiceを作成
--port=80 Serviceが受け付けるポート
--target-port=80 転送先となるPodのポート
--name=app-svc Service名

--typeを省略しているため、Serviceの種類は既定のClusterIPになります。

ClusterIPは、クラスタ内部から利用するためのServiceです。Podが置き換わってIPアドレスが変わっても、利用側はServiceの名前やClusterIPを使って接続できます。

Serviceと接続先を確認する

kubectl -n kcna get svc,endpoints app-svc

出力例:

NAME              TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
service/app-svc   ClusterIP   10.96.86.216   <none>        80/TCP    4m10s

NAME                ENDPOINTS                       AGE
endpoints/app-svc   10.244.1.14:80,10.244.2.10:80   4m10s
表示 意味
svc Serviceの省略名
CLUSTER-IP Serviceに割り当てられた仮想IPアドレス
EXTERNAL-IP: <none> 外部向けのIPアドレスが割り当てられていない
ENDPOINTS 接続先となるPodのIPアドレスとポート

この例では、Serviceの10.96.86.216:80への通信が、接続先となる2つのPodへ転送されます。

EndpointSliceで確認する

Endpoints APIは、Kubernetes v1.33以降では非推奨です。EndpointSliceでもServiceの接続先を確認できます。

kubectl -n kcna get endpointslices \
  -l kubernetes.io/service-name=app-svc

詳細を確認する場合は、以下を実行します。

kubectl -n kcna describe endpointslices \
  -l kubernetes.io/service-name=app-svc

参考:Kubernetes公式ドキュメント:Service

5. クラスタ内からService名で接続する

確認用の一時Podを起動し、Serviceの名前解決とHTTP通信を確認します。

kubectl -n kcna run tester --rm -it --restart=Never \
  --image=busybox:1.36 -- sh -c \
  'nslookup app-svc; wget -qO- http://app-svc | head -n 5'

名前解決の結果に続いて、NginxのHTMLの先頭部分が表示されることを確認します。

HTMLの出力例:

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>

Pod起動コマンドの解説

項目 意味
run tester testerというPodを作成
--rm 接続して実行した処理の終了後、Podを削除
-i 標準入力を開いておく
-t 仮想端末を割り当てる
--restart=Never 終了したコンテナを再起動しない
--image=busybox:1.36 基本的なコマンドを含む軽量イメージを使用
-- 以降をコンテナで実行するコマンド・引数として扱う
sh -c '...' コンテナ内のシェルで文字列をコマンドとして実行

コンテナ内で実行するコマンド

コマンド・オプション 意味
nslookup app-svc Service名の名前解決を確認
wget HTTPでデータを取得
-q 進行状況などの表示を抑制
-O - 取得内容をファイルではなく標準出力へ出力
http://app-svc Service名でHTTP接続。ポート省略時は80
head -n 5 出力の先頭5行を表示

NamespaceとService名の関係

確認用PodとServiceが同じkcnaにあるため、短い名前のapp-svcで接続できます。

別のNamespaceから接続する場合は、Namespaceを含めた名前を使用します。

app-svc.kcna

既定のクラスタドメインを使用する環境では、完全な名前は以下です。

app-svc.kcna.svc.cluster.local

参考:Kubernetes公式ドキュメント:DNS for Services and Pods

6. NodePort Serviceを作成する

同じDeploymentを対象として、NodePort Serviceを作成します。

kubectl -n kcna expose deployment app \
  --type=NodePort --port=80 --target-port=80 --name=app-np

作成したServiceを確認します。

kubectl -n kcna get svc app-np

出力例:

NAME     TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
app-np   NodePort   10.96.100.118   <none>        80:31451/TCP   40s

コマンドと表示内容の解説

項目 意味
--type=NodePort ノードのポートでも接続を受け付けるServiceを作成
--port=80 Serviceのポート
--target-port=80 転送先Podのポート
80:31451/TCP Serviceポートが80、NodePortが31451、プロトコルがTCP

NodePort番号は未指定のため、クラスタが自動で割り当てます。標準の割り当て範囲は30000~32767です。

この操作は、既存のapp-svcを変更するものではありません。同じPod群を対象とする、2つ目のService app-npを作成しています。

kindでのNodePortへの接続

NodePortは、基本的にノードIP:NodePort番号で利用します。

ただし、kindのノードはコンテナとして動作するため、ノードIPへ直接接続できるかは、ホストOSやネットワーク構成によって異なります。

Linux上のDockerではホストからノードIPへ接続できる場合があります。一方、Docker Desktopなどでは、ホストから利用するためにextraPortMappingsが必要になる場合があります。

したがって、「kindではNodePortに直接接続できない」と一律に判断することはできません。

参考:kind公式ドキュメント:NodePort with Port Mappings

7. port-forwardでローカルから接続する

ここでは、NodePortへの直接接続とは別に、kubectl port-forwardを使ってアプリケーションへ接続します。

この手順はNodePort番号への疎通確認ではありません。 Serviceを指定して対象Podを選び、ローカルのポートからPodへ転送します。ClusterIP Serviceでも同じ方法を利用できます。

7.1 ローカルポートの使用状況を確認する

接続確認にはローカルの8080番ポートを使用します。

ss -ltnp 'sport = :8080'

8080番ポートで待ち受けているソケットがないことを確認してください。使用中の場合は、別のローカルポートを選びます。

オプション 意味
-l 待ち受け中のソケットを表示
-t TCPを対象とする
-n IPアドレス・ポートを数値で表示
-p 使用しているプロセス情報を表示

プロセス情報は、実行ユーザーの権限によって表示されない場合があります。

7.2 ターミナル1で転送を開始する

kubectl -n kcna port-forward svc/app-np 8080:80

出力例:

Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80

8080:80は、ローカルの8080番ポートへの通信を、Serviceの80番ポートに対応する対象Podへ転送する指定です。

このターミナルは、転送を実行したままにします。

7.3 ターミナル2でHTTP接続を確認する

同じホスト上の別ターミナルで、以下を実行します。

curl -sS http://localhost:8080 | head -n 5

出力例:

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
項目 意味
curl -s 進行状況などの表示を抑制
curl -S -sと併用した場合もエラーを表示
head -n 5 HTMLの先頭5行を表示

接続時には、ターミナル1に以下のようなメッセージが表示されます。

Handling connection for 8080

7.4 転送を終了する

確認が終わったら、ターミナル1でCtrl+Cを押します。

終了するのはport-forwardの処理です。Deployment・Pod・Serviceは残ります。

なお、port-forwardは、kubectlを実行しているホスト上で待ち受けます。SSHでRocky Linuxに接続して作業している場合、この手順のlocalhostはRocky Linux側を指します。

参考:Kubernetes公式ドキュメント:Use Port Forwarding to Access Applications in a Cluster

8. 今回使用した仕組みの違い

仕組み 役割
Namespace リソースを論理的に整理する
ClusterIP Service クラスタ内部向けの接続先を提供する
NodePort Service ClusterIPに加え、ノードのポートでも接続を受け付ける
ServiceのDNS名 IPアドレスを直接指定せずにServiceへ接続する
port-forward ローカルポートから対象Podへ一時的に接続する

本記事では、ClusterIP経由のクラスタ内通信と、port-forward経由のローカルからの通信を確認しました。NodePort番号への直接接続は、別途ネットワーク構成に合わせて確認する必要があります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?