トポロジを意識したservice転送
- Topology-aware service routing
- クラスタがリージョンやAZにまたがっていてもserviceは意識せずに転送する
- またがるとレイテンシーやパフォーマンスの低下
- ノード数が多いと起きやすい
- externalTrafficPolicy: Localでリスクは下げれるが・・・
- ClusterIPでは不可
- 同一ノード内でしか転送できない、同一ノード内にpodがいなければタイムアウト
- Topology-aware service routingにより回避できる
- ただし、
- 送信元IPは取れない
- Topology-aware service routingとexternalTrafficPolicy: Localは併用できない
Topology-aware service routingの設定
- どのトポロジに転送するかを複数の優先度で判断する
- 例
-
- 同一ノード
-
- 同一ゾーン
-
- どれか
-
kindで3node用意してやってみる. alplaなfeatureなのでfeatureGatesで有効にしてあげる
apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
name: sample
nodes:
- role: control-plane
- role: worker
kubeadmConfigPatches:
- |
kind: JoinConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 30080
hostPort: 30001
protocol: TCP
- containerPort: 30443
hostPort: 30011
protocol: TCP
- role: worker
kubeadmConfigPatches:
- |
kind: JoinConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 30080
hostPort: 30002
protocol: TCP
- containerPort: 30443
hostPort: 30012
protocol: TCP
- role: worker
kubeadmConfigPatches:
- |
kind: JoinConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 30080
hostPort: 30003
protocol: TCP
- containerPort: 30443
hostPort: 30013
protocol: TCP
featureGates:
ServiceTopology: true
topologyKeysを使う
- 同じ kubernetes.io/hostname のラベルがあるnode内が最優先
- そうでなければいずれか("*")
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: bootcamp
name: bootcamp-deployment
spec:
replicas: 4
selector:
matchLabels:
app: bootcamp
template:
metadata:
labels:
app: bootcamp
spec:
containers:
- image: gcr.io/google-samples/kubernetes-bootcamp:v1
name: bootcamp
ports:
- name: "http"
containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: bootcamp-service
spec:
type: ClusterIP
ports:
- name: "http-port"
protocol: "TCP"
port: 8888
targetPort: 8080
selector:
app: bootcamp
topologyKeys:
- kubernetes.io/hostname
- "*"
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
bootcamp-deployment-8d6697479-cjckn 1/1 Running 0 56s 10.244.1.2 sample-worker2 <none> <none>
bootcamp-deployment-8d6697479-rnp6l 1/1 Running 0 56s 10.244.1.3 sample-worker2 <none> <none>
bootcamp-deployment-8d6697479-v7qdj 1/1 Running 0 56s 10.244.2.2 sample-worker3 <none> <none>
bootcamp-deployment-8d6697479-xs8xb 1/1 Running 0 56s 10.244.3.2 sample-worker <none> <none>
nodeportにアクセスしてみる. node-1のpodしか応答しない。
$ curl localhost:30001
Hello Kubernetes bootcamp! | Running on: bootcamp-deployment-8d6697479-xs8xb | v=1
$ curl localhost:30001
Hello Kubernetes bootcamp! | Running on: bootcamp-deployment-8d6697479-xs8xb | v=1
$ curl localhost:30001
Hello Kubernetes bootcamp! | Running on: bootcamp-deployment-8d6697479-xs8xb | v=1
複数podが立っているnode-2にアクセスしてみる。node-2のpodのどちらかが応答する
$ curl localhost:30002
Hello Kubernetes bootcamp! | Running on: bootcamp-deployment-8d6697479-rnp6l | v=1
$ curl localhost:30002
Hello Kubernetes bootcamp! | Running on: bootcamp-deployment-8d6697479-cjckn | v=1
$ curl localhost:30002
Hello Kubernetes bootcamp! | Running on: bootcamp-deployment-8d6697479-cjckn | v=1
$ curl localhost:30002
Hello Kubernetes bootcamp! | Running on: bootcamp-deployment-8d6697479-rnp6l | v=1
topologyKeysに指定可能なラベルは以下の3種類
- kubernetes.io/hostname
- topology.kubernetes.io/zone
- topology.kubernetes.io/region
"*"を指定する場合は最後に指定すること
Headless Service
statefulset以外(deployment)の場合
headlessではclusterIPがない
名前解決してみる
nodeportとかの場合だとこうなるので違いがわかる
statefulsetだとpod名で名前解決可能. statefulsetのspec.serviceNameとserviceのmetadata.nameが同じである必要がある。
pod名.service名やpod名.service名.namespace名でもひける