Kubernetes ports - arosh/arosh.github.com GitHub Wiki
Kubernetes には ports を指定する箇所がいろいろある。たくさんあって何が何だったか毎回調べている気がするのでまとめる。
Pod の .spec.containers.ports
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#containerport-v1-core
hostIP と hostPort はまともなロードバランサーが整備されている環境では使うことはない。よって設定するのは以下のみ
- name
- containerPort
- protocol (TCP, UDP, SCTP. defaults to TCP)
name は Service から名前で参照できる用途で利用される。ここでポートを指定しなくても外には公開されている(ファイアウォールの許可ポートを指定しているわけではない)。よって極端な話、何も指定しなくても動かすことはできる ("Not specifying a port here DOES NOT prevent that port from being exposed.")。
Service の .spec.ports
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#serviceport-v1-core
- appProtocol
- name
- nodePort
- port
- protocol
- targetPort
appProtocol は "This is used as a hint for implementations to offer richer behavior for protocols that they understand." ということなのでいったん気にしないことにする。Istio はこのフィールドを参照しているので不適切な設定をすると問題が起きた例があるらしい。
name は実質必須。その Service に含まれる ports が一つだけのときは optional だが、複数あると必須。
targetPort は 1~65535 の整数を指定するか、Pod の ports の name を文字列で指定する。指定しなければ port の値が利用される(ただし port には整数しか指定できない)。clusterIP=None すなわち headless service の場合は port!=targetPort に指定することに意味がないことから、指定しない or port と同じ値であることが要求される。
EndpointSlice, EndpointPort
コードを読むのがよさそう
https://qiita.com/nakamasato/items/13698c24af0a60f71bcd
未確認だが、こういうことになるのだと仮定すると腑に落ちる。
selector を指定しない & headless でない Service を作って自前で Endpoints を管理する場合
ServicePort の name と EndpointPort の name が一致するものを探して ServicePort → EndpointPort の DNAT を設定する ("This must match the 'name' field in the corresponding ServicePort." のような記述があるのでこれは正しそう)
ServicePort の targetPort は無視される?(無視されるようになっていないとおかしい)
selector を指定しない & headless のとき
DNS で addresses フィールドの IP アドレスが提供されるだけで ports は関係ない。
selector を指定する場合
Service が selector と ports.targetPort から Endpoints が作成される
Q. headless Service では ports は指定しなくてもいい? A. 無くてもいいが、環境変数で注入されるサービスディスカバリが提供されなくなるので不便かも
Q. headless Service なら Endpoints の ports は指定しなくてもいい? A. 無くてもいいが、headless でない Service を新たに作らないといけなくなったときには追加してね