Что такое обнаружение сервисов?
DNS是傳統的Service Discovery System,但並不適用於K8s的動態環境。
一般cache機制導致在K8s和錯誤的IP溝通,並很難及時修正。
Система доменных имен (DNS) является традиционной системой обнаружения услуг в Интернете. DNS предназначена для относительно стабильного разрешения имен с широким и эффективным кэшированием. Это отличная система для интернета, но она не подходит для динамичного мира Kubernetes.
Объект сервиса
kubectl run: 建立K8s deployment
kubectl expose: 對資源建立service
Так же как команда kubectl run является простым способом создания развертывания Kubernetes, мы можем использовать kubectl expose для создания сервиса.
Service會被指定一個ClusterIP、系統會透過selector進行load-balance。
要存取service,可以透過port-forward存取其中一個Pod。
этой службе назначается новый тип виртуального IP-адреса, называемый кластерным IP-адресом. Это специальный IP-адрес, который система будет балансировать нагрузку на все Под, определенные селектором.
DNS службы
Дополнительные сведения
Конечные точки
ПРИМЕЧАНИЕ Service拿到的IP和Pod拿到的IP屬於不同網段!而Endpoint指向的是Pod IP
Service是10.110開頭的IP
$ k get -n kubeflow svc/centraldashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
centraldashboard ClusterIP 10.110.103.203 <none> 80/TCP 23h
Pod拿到的是10.244開頭的IP
$ k describe -n kubeflow endpoints/centraldashboard
Name: centraldashboard
Namespace: kubeflow
Labels: app=centraldashboard
app.kubernetes.io/component=centraldashboard
app.kubernetes.io/instance=centraldashboard-v1.0.0
app.kubernetes.io/managed-by=kfctl
app.kubernetes.io/name=centraldashboard
app.kubernetes.io/part-of=kubeflow
app.kubernetes.io/version=v1.0.0
kustomize.component=centraldashboard
Annotations: <none>
Subsets:
Addresses: 10.244.0.29
NotReadyAddresses: <none>
Ports:
Name Port Protocol
---- ---- --------
<unset> 8082 TCP
Events: <none>
Ручное обнаружение сервиса
K8s Service是基於label selector建置。所以可以不透過Service物件手動作服務探索。
Сервисы Kubernetes построены поверх селекторов меток над Pods. Это означает, что вы можете использовать Kubernetes API для рудиментарного обнаружения сервисов без использования объекта Service вообще! Давайте продемонстрируем.
$ k get po -n kube-system -o wide --selector=k8s-app=kube-dns
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-5644d7b6d9-9bh5g 1/1 Running 0 24h 10.244.0.3 tom-g75jw <none> <none>
coredns-5644d7b6d9-v5ll9 1/1 Running 0 24h 10.244.0.2 tom-g75jw <none> <none>
kube-proxy и кластерные IP
Кластерные IP — это стабильные виртуальные IP, которые балансируют нагрузку на все конечные точки сервиса. Эту магию выполняет компонент, запущенный на каждом узле кластера, который называется kube-proxy.
kube-proxy透過API server得知新的Service。並改寫所在的node的iptables rules來導向封包至endpoint。
На рисунке 7-1 kube-proxy следит за появлением новых сервисов в кластере через APIserver. Затем он программирует набор правил iptables в ядре этого узла, чтобы переписать назначения пакетов так, чтобы они были направлены на одну из конечных точек этого сервиса.
ClusterIP通常由APIserver指定。但是使用者可以等Service啟動後自行指定,但之後刪除和重啟Service後,IP不能再被改變。
IP-адрес кластера обычно назначается API-сервером при создании службы. Однако при создании службы пользователь может указать конкретный IP-адрес кластера. После задания кластерный IP не может быть изменен без удаления и повторного создания объекта Service.
ПРИМЕЧАНИЕ:
注意ClusterIP range和submask不要和Docker bridge, K8s node重疊。
Диапазон адресов сервисов Kubernetes настраивается с помощью флага —service-cluster-ip-range в бинарном файле kube-apiserver. Диапазон адресов сервиса не должен пересекаться с IP-подсетями и диапазонами, назначенными каждому мосту Docker или узлу Kubernetes.
Кроме того, любой явно запрашиваемый кластерный IP должен быть из этого диапазона и не должен уже использоваться.
Переменные среды кластерного IP
除了DNS還有老方法可以找尋clusterIP: 設定環境變數。
Хотя большинство пользователей должны использовать службы DNS для поиска IP-адресов кластеров, есть некоторые старые механизмы, которые все еще могут использоваться. Одним из них является внедрение набора переменных окружения в Pods при их запуске.
Service必須提前Pod啟動,也不適用於大型應用,所以作者還是建議DNS才是較好的選擇。
Проблема подхода с переменными окружения заключается в том, что он требует создания ресурсов в определенном порядке. Сервисы должны быть созданы до Pods, которые на них ссылаются. Это может внести довольно много сложностей при развертывании набора сервисов, составляющих более крупное приложение. Кроме того, использование только переменных окружения кажется странным для многих пользователей. По этой причине DNS, вероятно, является лучшим вариантом.