Serviceでトラフィックを繋ぐ
目標
サービスの5つのタイプとIngressを自分で作成し、セレクターがずれてエンドポイントが空になる状況を作って直します。
なぜ重要なのか
試験で「サービスを作成したのに接続できない」という問題は、ほとんどが、セレクター、ポート、Readyの3つのうちどれかです。Serviceオブジェクトがトラフィックを運ぶのではなく、セレクターでバックエンドの一覧を作る宣言であるという点を理解すれば、診断の順序が自動的に決まります。まずエンドポイントにIPがあるかを見ます。あればデータプレーンかポートの問題で、なければセレクターかPodのReadyの問題です。
targetPortとportを区別することも重要です。portはサービスが開くポート、targetPortはPod側のポートです。両者が同じなら省略できるため、混乱しやすいですが、違う値にした瞬間に、ミスが表面化します。
ステップ
- ネームスペース
cka-netを作成し、Deploymentweb(レプリカ2、イメージnginx:1.27、Podラベルapp=web)を作成してください。そのあと、ClusterIPサービスweb-svcを作成してください。port 80、targetPort 80、セレクターapp=webです。 - Deployment
api(レプリカ2、イメージnginx:1.27、Podラベルapp=api)を作成してください。サービスapi-svcを、セレクターapp=api-serverで間違えて作成したあとに、エンドポイントの照会結果を/root/cka-net/endpoints-before.txtに保存してください。そのあと、セレクターをapp=apiに直してください。 - NodePortサービス
web-npを作成してください。port 80、セレクターapp=web、nodePortは30080を直接指定してください。 - Deployment
db(レプリカ1、イメージnginx:1.27、Podラベルapp=db)を作成し、ヘッドレスサービスdb-headlessを作成してください。clusterIPNone、port 5432、セレクターapp=dbです。 - サービス
multi-svcを作成してください。セレクターapp=web、ポートは2つで、名前http(port 80、targetPort 8080)、名前metrics(port 9090)です。 - サービス
ext-dbを作成してください。typeExternalName、externalNamenas.homelab.internalです。 - Ingress
web-ingを作成してください。ingressClassNamenginx、hostcka.homelab.internalで、パス/(pathType Prefix)はweb-svcの80ポートに、パス/api(pathType Prefix)はapi-svcの80ポートに送ってください。
参考
- エンドポイントは、
kubectl get endpointslice -n cka-net -l kubernetes.io/service-name=web-svcでも見られます。 - ステップ2は、順序が採点の対象です。直す前に、必ずファイルに残してください。
- よくあるミス1:
clusterIP: Noneを、あとから直そうとすることです。このフィールドは不変です。 - よくあるミス2: Ingressで
pathTypeを忘れることです。v1では必須フィールドなので、拒否されます。
ClusterIPサービスとエンドポイント
ネームスペースcka-netを作成し、Deploymentweb(レプリカ2、イメージnginx:1.27、Podラベルapp=web)を作成してください。そのあと、ClusterIPサービスweb-svcを作成してください。port 80、targetPort 80、セレクターapp=webです。
kubectl exposeが最も速いですが、セレクターが何で設定されるかを確認してください。エンドポイントは、PodがReadyであってはじめて埋まります。
セレクターのタイプミスでエンドポイントが空になる状況
Deploymentapi(レプリカ2、イメージnginx:1.27、Podラベルapp=api)を作成してください。サービスapi-svcを、セレクターapp=api-serverで間違えて作成したあとに、エンドポイントの照会結果を/root/cka-net/endpoints-before.txtに保存してください。そのあと、セレクターをapp=apiに直してください。
まず、間違ったセレクターで作成し、エンドポイントが空なのを目で見てファイルに残してから、直してください。順序を守らないと、証拠が残りません。
NodePortの番号を直接指定する
NodePortサービスweb-npを作成してください。port 80、セレクターapp=web、nodePortは30080を直接指定してください。
nodePortは、ports配列の中に入ります。デフォルトの範囲は30000–32767で、それ以外の値は拒否されます。
ヘッドレスサービス
Deploymentdb(レプリカ1、イメージnginx:1.27、Podラベルapp=db)を作成し、ヘッドレスサービスdb-headlessを作成してください。clusterIPNone、port 5432、セレクターapp=dbです。
clusterIPをNoneにすると、VIPが割り当てられません。このフィールドは作成後に変更できないので、間違えて作成したなら、作り直してください。
ポートを2つ公開する
サービスmulti-svcを作成してください。セレクターapp=web、ポートは2つで、名前http(port 80、targetPort 8080)、名前metrics(port 9090)です。
ポートが2つ以上なら、各ポートにnameが必須です。portとtargetPortは、違う値でもかまいません。
ExternalNameで外部システムを指す
サービスext-dbを作成してください。typeExternalName、externalNamenas.homelab.internalです。
ExternalNameサービスは、セレクターもポートも持たず、ClusterIPも受け取りません。別のタイプで先に作成したなら、作り直すほうがすっきりします。
総合: Ingressで2つのサービスを束ねる
Ingressweb-ingを作成してください。ingressClassNamenginx、hostcka.homelab.internalで、パス/(pathType Prefix)はweb-svcの80ポートに、パス/api(pathType Prefix)はapi-svcの80ポートに送ってください。
ingressClassNameは、アノテーションではなく、specのフィールドです。各pathにはpathTypeが必須で、バックエンドはservice.nameとservice.port.numberで指名します。