Kubernetes (K8s) — это платформа для оркестрации контейнеризированных приложений. Одна из ключевых абстракций в ней — Service (сервис).
Сервис определяет способ доступа к набору подов и обеспечивает конечную точку для подключения к приложениям, даже когда поды пересоздаются или перемещаются.
Kubernetes предоставляет четыре типа сервисов для организации сетевого взаимодействия:
ClusterIP,
NodePort,
LoadBalancer,
ExternalName.
В статье ниже рассмотрим каждый сервис подробнее.
Предварительные действия
- 1
- 2
-
3
Убедитесь, что подключение работает, выполнив команду
kubectl cluster-info.
ClusterIP
ClusterIP — базовый тип сервиса в Kubernetes, который используется для организации связи внутри кластера. По умолчанию он назначает сервису внутренний IP-адрес из пула кластера. Этот адрес доступен только для компонентов внутри кластера и недоступен извне.
Пример использования
Создадим файл с описанием Deployment для запуска Nginx и Service типа ClusterIP.
-
1
Создайте новый namespace, например
regcloud-clusterip-example:kubectl create namespace regcloud-clusterip-example -
2
Создайте файл .yaml, например
nginx-test-deployment, и сохраните в него следующую конфигурацию:apiVersion: apps/v1 kind: Deployment metadata: name: nginx-clusterip-deployment namespace: regcloud-clusterip-example labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.28.0 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-clusterip-service namespace: regcloud-clusterip-example spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP -
3
Примените конфигурацию:
kubectl apply -f nginx-test-deployment.yaml -
4
Проверьте, что все сущности были созданы:
kubectl get all -n regcloud-serviceip-exampleЧтобы проверить, что развернутый nginx доступен изнутри кластера по созданному ClusterIp, воспользуйтесь командой:
kubectl run --rm -it --restart=Never curl-test --image=curlimages/curl -n regcloud-clusterip-example -- curl http://nginx-clusterip-service
Headless Service
Headless Service используется, когда вам не нужна балансировка нагрузки или единый Service IP. Подходит для приложений, где требуется прямое взаимодействие с каждым подом. Вы явно указываете, что для сервиса не нужен кластерный IP, установив clusterIP: None.
-
1
Создайте новый namespace, например
regcloud-headlessservice-example:kubectl create namespace regcloud-headlessservice-example -
2
Создайте файл .yaml, например
nginx-statefulset-headless, и сохраните в него следующую конфигурацию:apiVersion: apps/v1 kind: StatefulSet metadata: name: nginx-statefulset namespace: regcloud-headlessservice-example spec: serviceName: "nginx-headless" replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.28.0 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-headless namespace: regcloud-headlessservice-example spec: clusterIP: None selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 -
3
Примените конфигурацию:
kubectl apply -f nginx-statefulset-headless.yaml -
4
Проверьте, что все сущности были созданы:
kubectl get all -n regcloud-headlessservice-example kubectl get statefulset -n regcloud-headlessservice-example -
5
Убедитесь, что поды имеют стабильные имена:
kubectl get pods -n regcloud-headlessservice-example -l app=nginxВы увидите поды с именами:
nginx-statefulset-0,nginx-statefulset-1,nginx-statefulset-2. -
6
Проверьте DNS-записи Headless Service:
kubectl run dns-test --image=busybox --rm -it --restart=Never -n regcloud-headlessservice-example -- nslookup nginx-headlessDNS вернет все IP-адреса подов, а не один ClusterIP.
-
7
Проверьте доступ к конкретным подам:
kubectl run curl-test --image=curlimages/curl --rm -it --restart=Never -n regcloud-headlessservice-example -- sh -c " curl http://nginx-statefulset-0.nginx-headless:80 echo '---' curl http://nginx-statefulset-1.nginx-headless:80 echo '---' curl http://nginx-statefulset-2.nginx-headless:80 "Каждый под получил собственное DNS-имя (<pod-name>.<service-name>.<namespace>.svc.cluster.local), постоянство имен сохраняется при перезапусках.
NodePort
Сервис типа NodePort предоставляет доступ к подам через статический порт на каждом узле кластера. Kubernetes control plane автоматически выделяет порт из диапазона 30000–32767 (значение по умолчанию) и привязывает его к сервису. Каждый узел кластера перенаправляет трафик с этого порта на соответствующий сервис.
Внешние клиенты могут обращаться к приложению, используя IP-адрес любого узла кластера в сочетании с выделенным портом. Например: http://<IP_узла>:<NodePort>.
Пример использования
-
1
Создайте новый namespace, например
regcloud-nodeport-example:kubectl create namespace regcloud-nodeport-example -
2
Создайте файл .yaml, например
nginx-nodeport-deployment, и сохраните в него следующую конфигурацию:apiVersion: apps/v1 kind: Deployment metadata: name: nginx-nodeport-deployment namespace: regcloud-nodeport-example labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.28.0 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-nodeport-service namespace: regcloud-nodeport-example spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 nodePort: 30080 type: NodePort -
3
Примените конфигурацию:
kubectl apply -f nginx-nodeport-deployment.yaml -
4
Проверьте, что все сущности были созданы:
kubectl get all -n regcloud-nodeport-example
В целях безопасности ноды Kubernetes в KaaS не имеют публичных IP-адресов, поэтому для проверки используем внутреннюю сеть кластера.
-
1
Создайте тестовый под:
kubectl run test-pod --image=curlimages/curl --restart=Never -n regcloud-nodeport-example -- sleep 3600 -
2
Выполните запрос с тестового пода на NodePort другого узла:
kubectl exec -it test-pod -n regcloud-nodeport-example -- curl http://<INTERNAL_NODE_IP>:30080Замените
<INTERNAL_NODE_IP>на внутренний IP-адрес одного из узлов кластера, который можно получить с помощью командыkubectl get nodes -o wide.
LoadBalancer
Сервисы типа LoadBalancer используют внешний балансировщик нагрузки, который зачастую предоставляется облачным провайдером. В этом случае внешний балансировщик нагрузки будет отвечать на запросы, приходящие на IP-адрес сервиса и направлять трафик внутрь кластера Kubernetes.
В Рег.облаке балансировщик нагрузки — платная услуга, ознакомиться со стоимостью можно здесь.
Как подключить LoadBalancer в Рег.облаке
-
1
Создайте новый namespace, например
regcloud-loadbalancer-example:kubectl create namespace regcloud-loadbalancer-example -
2
Создайте файл .yaml, например
nginx-loadbalancer-deployment, и сохраните в него следующую конфигурацию:apiVersion: apps/v1 kind: Deployment metadata: name: nginx-loadbalancer-deployment namespace: regcloud-loadbalancer-example spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.28.0 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-loadbalancer-service namespace: regcloud-loadbalancer-example spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 type: LoadBalancer -
3
Примените конфигурацию:
kubectl apply -f nginx-loadbalancer-deployment.yaml -
4
Проверьте, что все сущности были созданы:
kubectl get all -n regcloud-loadbalancer-example
При успешном подключении информация о сервисе LoadBalancer отобразится в личном кабинете в разделе «Балансировщики нагрузки»:
Обратите внимание
Подключить балансировщики нагрузки через личный кабинет нельзя.
ExternalName
Сервис типа ExternalName работает иначе, чем другие типы сервисов. Вместо селектора для выбора подов в сервисах типа ExternalName для места назначения трафика указывается DNS-имя.
-
1
Создайте новый namespace:
kubectl create namespace regcloud-externalname-example -
2
Создайте файл .yaml, например
externalname-test.yaml, и сохраните в него следующую конфигурацию:apiVersion: v1 kind: Service metadata: name: external-website namespace: regcloud-externalname-example spec: type: ExternalName externalName: nginx.org --- apiVersion: v1 kind: Service metadata: name: external-google namespace: regcloud-externalname-example spec: type: ExternalName externalName: google.com -
3
Примените конфигурацию:
kubectl apply -f externalname-test.yaml -
4
Проверьте, что все сущности были созданы:
kubectl get all -n regcloud-externalname-example -
5
Чтобы протестировать DNS-разрешение, запустите тестовый под:
kubectl run test-pod --image=busybox --rm -it --restart=Never -n regcloud-externalname-example -- /bin/sh -
6
Внутри пода выполните:
nslookup external-website nslookup external-google