• Русский
  • Настройка сервисов

    В Kubernetes Service — это способ открыть сетевое приложение, работающее в одном или нескольких Pod в вашем кластере.

    Зачем нужен Service

    1. У Pod есть собственные IP, но:

      • IP Pod нестабильны (меняются при пересоздании Pod).

      • Прямой доступ к Pod становится ненадежным.

    2. Service решает эту проблему, предоставляя:

      • Стабильный IP и DNS-имя.

      • Автоматическое балансирование нагрузки на соответствующие Pod.

    Пример Service типа ClusterIP:

    # simple-service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
    spec:
      type: ClusterIP
      selector:
        app.kubernetes.io/name: MyApp
      ports:
        - protocol: TCP
          port: 80
          targetPort: 80
    1. Доступные значения type и их поведение: ClusterIP, NodePort, LoadBalancer, ExternalName
    2. Набор Pod, на которые нацелен Service, обычно определяется селектором, который вы задаёте.
    3. Порт Service.
    4. Привязка targetPort Service к containerPort Pod. Также можно ссылаться на port.name внутри контейнера Pod.

    Headless Services

    Иногда не требуется балансировка нагрузки и единый IP Service. В таком случае можно создать так называемые headless Services:

    spec:
      clusterIP: None

    Headless Services полезны, когда:

    • Нужно обнаруживать IP отдельных Pod, а не только единый IP сервиса.

    • Требуются прямые подключения к каждому Pod (например, для баз данных типа Cassandra или StatefulSets).

    • Используются StatefulSets, где каждый Pod должен иметь стабильное DNS-имя.

    Создание сервиса через веб-консоль

    1. Перейдите в Container Platform.

    2. В левой навигационной панели выберите Network > Services.

    3. Нажмите Create Service.

    4. Следуйте инструкциям для настройки соответствующих параметров.

      ПараметрОписание
      Virtual IP AddressЕсли включено, для этого Service будет выделен ClusterIP, который можно использовать для обнаружения сервиса внутри кластера.
      Если отключено, будет создан headless Service, обычно используемый для StatefulSet.
      Type
      • ClusterIP: Открывает Service на внутреннем IP кластера. При выборе этого значения Service доступен только внутри кластера.
      • NodePort: Открывает Service на IP каждого Node по статическому порту (NodePort).
      • ExternalName: Отображает Service на содержимое поля externalName (например, на hostname api.foo.bar.example).
      • LoadBalancer: Открывает Service снаружи с помощью внешнего балансировщика нагрузки. Kubernetes напрямую не предоставляет компонент балансировки нагрузки; его нужно предоставить самостоятельно или интегрировать кластер с облачным провайдером.
      Target Component
      • Workload: Service будет перенаправлять запросы на конкретный workload, который соответствует меткам, например, project.cpaas.io/name: projectname и service.cpaas.io/name: deployment-name.

      • Virtualization: Service будет перенаправлять запросы на конкретную виртуальную машину или группу виртуальных машин.

      • Label Selector: Service будет перенаправлять запросы на определённый тип workload с указанными метками, например, environment: release.
      PortНастройка сопоставления портов для этого Service. В приведённом примере другие Pod внутри кластера могут обращаться к этому Service по виртуальному IP (если включён) и TCP-порту 80; запросы будут перенаправлены на внешний TCP-порт 6379 или redis Pod целевого компонента.
      • Protocol: Протокол, используемый Service, поддерживаются: TCP, UDP, HTTP, HTTP2, HTTPS, gRPC.
      • Service Port: Номер порта, который Service открывает внутри кластера, то есть Port, например, 80.
      • Container Port: Целевой порт (или имя), на который маппится service port, то есть targetPort, например, 6379 или redis.
      • Service Port Name: Генерируется автоматически. Формат: <protocol>-<service port>-<container port>, например: tcp-80-6379 или tcp-80-redis.
      Session AffinityСессия привязывается к исходному IP-адресу (ClientIP). Если включено, все запросы с одного IP будут направляться на один и тот же сервер при балансировке нагрузки, что гарантирует обработку запросов от одного клиента одним сервером.
    5. Нажмите Create.

    Создание сервиса через CLI

    kubectl apply -f simple-service.yaml

    Создание сервиса на основе существующего ресурса deployment my-app.

    kubectl expose deployment my-app \
      --port=80 \
      --target-port=8080 \
      --name=test-service \
      --type=NodePort \
      -n p1-1

    Пример: Доступ к приложению внутри кластера

    # access-internal-demo.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
            - name: nginx
              image: nginx:1.25
              ports:
                - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-clusterip
    spec:
      type: ClusterIP
      selector:
        app: nginx
      ports:
        - port: 80
          targetPort: 80
    1. Примените этот YAML:

      kubectl apply -f access-internal-demo.yaml
    2. Запустите другой Pod:

      kubectl run test-pod --rm -it --image=busybox -- /bin/sh
    3. Доступ к сервису nginx-clusterip из Pod test-pod:

      wget -qO- http://nginx-clusterip
      # или используя DNS-записи, созданные Kubernetes автоматически: <service-name>.<namespace>.svc.cluster.local
      wget -qO- http://nginx-clusterip.default.svc.cluster.local

    Вы должны увидеть HTML-ответ с текстом вроде "Welcome to nginx!".

    Пример: Доступ к приложению вне кластера

    # access-external-demo.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
            - name: nginx
              image: nginx:1.25
              ports:
                - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-nodeport
    spec:
      type: NodePort
      selector:
        app: nginx
      ports:
        - port: 80
          targetPort: 80
          nodePort: 30080
    1. Примените этот YAML:

      kubectl apply -f access-external-demo.yaml
    2. Проверка Pod:

      kubectl get pods -l app=nginx -o wide
    3. curl к сервису:

      curl http://{NodeIP}:{nodePort}

    Вы должны увидеть HTML-ответ с текстом вроде "Welcome to nginx!".

    Конечно, можно получить доступ к приложению снаружи кластера, создав Service типа LoadBalancer.

    Примечание: Пожалуйста, заранее настройте сервис LoadBalancer.

    # access-external-demo-with-loadbalancer.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
            - name: nginx
              image: nginx:1.25
              ports:
                - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-lb-service
    spec:
      type: LoadBalancer
      selector:
        app: nginx
      ports:
        - port: 80
          targetPort: 80
    1. Примените этот YAML:

      kubectl apply -f access-external-demo-with-loadbalancer.yaml
    2. Получите внешний IP-адрес:

      kubectl get svc nginx-lb-service
      NAME            TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)        AGE
      nginx-service   LoadBalancer   10.0.2.57        34.122.45.100   80:30005/TCP   30s

      EXTERNAL-IP — это адрес, по которому вы можете получить доступ из браузера.

      curl http://34.122.45.100

    Вы должны увидеть HTML-ответ с текстом вроде "Welcome to nginx!".

    Если EXTERNAL-IP равен pending, значит сервис LoadBalancer в данный момент не развернут в кластере.

    Пример: Service типа ExternalName

    apiVersion: v1
    kind: Service
    metadata:
      name: my-external-service
      namespace: default
    spec:
      type: ExternalName
      externalName: example.com
    1. Примените этот YAML:

      kubectl apply -f external-service.yaml
    2. Попробуйте разрешить имя внутри Pod в кластере:

      kubectl run test-pod --rm -it --image=busybox -- sh

      затем:

      nslookup my-external-service.default.svc.cluster.local

    Вы увидите, что имя разрешается в example.com.

    Аннотации для Service типа LoadBalancer

    AWS EKS Cluster

    Подробное описание аннотаций для LoadBalancer Service в EKS смотрите в Annotation Usage Documentation .

    КлючЗначениеОписание
    service.beta.kubernetes.io/aws-load-balancer-typeexternal: Использовать официальный AWS LoadBalancer Controller.Определяет контроллер для типа LoadBalancer.

    Примечание: Пожалуйста, заранее свяжитесь с администратором платформы для развертывания AWS LoadBalancer Controller.
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type
    • instance: Трафик будет отправляться на Pod через NodePort.
    • ip: Трафик направляется напрямую на Pod (кластер должен использовать Amazon VPC CNI).
    Определяет, как трафик достигает Pod.
    service.beta.kubernetes.io/aws-load-balancer-scheme
    • internal: Частная сеть.
    • internet-facing: Публичная сеть.
    Определяет использование частной или публичной сети.
    service.beta.kubernetes.io/aws-load-balancer-ip-address-type
    • IPv4
    • dualstack
    Определяет поддерживаемый стек IP-адресов.

    Huawei Cloud CCE Cluster

    Подробное описание аннотаций для LoadBalancer Service в CCE смотрите в Annotation Usage Documentation .

    КлючЗначениеОписание
    kubernetes.io/elb.idУкажите ID облачного балансировщика нагрузки, должен использоваться существующий балансировщик.
    kubernetes.io/elb.autocreateПример: {"type":"public","bandwidth_name":"cce-bandwidth-1551163379627","bandwidth_chargemode":"bandwidth","bandwidth_size":5,"bandwidth_sharetype":"PER","eip_type":"5_bgp","available_zone":["cn-north-4b"],"l4_flavor_name":"L4_flavor.elb.s1.small"}

    Примечание: Пожалуйста, ознакомьтесь с Инструкцией по заполнению и при необходимости скорректируйте параметры.
    Новый облачный балансировщик нагрузки для создания.
    kubernetes.io/elb.subnet-idID подсети, в которой расположен кластер. При версии Kubernetes 1.11.7-r0 и ниже обязательно указывать при создании нового балансировщика.
    kubernetes.io/elb.class
    • union: Общая балансировка нагрузки.
    • performance: Эксклюзивная балансировка нагрузки, поддерживается только в Kubernetes версии 1.17 и выше.
    Определяет тип создаваемого балансировщика нагрузки, см. Различия между эксклюзивной и общей балансировкой нагрузки.
    kubernetes.io/elb.enterpriseIDОпределяет проект предприятия, к которому относится создаваемый балансировщик нагрузки.

    Azure AKS Cluster

    Подробное описание аннотаций для LoadBalancer Service в AKS смотрите в Annotation Usage Documentation .

    КлючЗначениеОписание
    service.beta.kubernetes.io/azure-load-balancer-internal
    • true: Частная сеть.
    • false: Публичная сеть.
    Определяет использование частной или публичной сети.

    Google GKE Cluster

    Подробное описание аннотаций для LoadBalancer Service в GKE смотрите в Annotation Usage Documentation .

    КлючЗначениеОписание
    networking.gke.io/load-balancer-typeInternalОпределяет использование частной сети.
    cloud.google.com/l4-rbsenabledПо умолчанию публичный. Если параметр настроен, трафик направляется напрямую на Pod.

    Пример: LoadBalancer с MetalLB BGP и Local Traffic Policy

    В этом примере показано, как настроить Service типа LoadBalancer с использованием MetalLB в режиме BGP и параметром externalTrafficPolicy: Local для реализации активного активного балансирования нагрузки без дополнительных сетевых переходов.

    Преимущества

    • Активное активное балансирование нагрузки: Трафик распределяется одновременно по нескольким узлам
    • Отсутствие дополнительных сетевых переходов: Прямой маршрут к Pod без промежуточной пересылки через узлы
    • Лучшее быстродействие: externalTrafficPolicy: Local сохраняет исходный IP и снижает задержки
    • Высокая доступность: Объявления маршрутов BGP обеспечивают доставку трафика до здоровых узлов

    Предварительные требования

    Перед настройкой LoadBalancer Service убедитесь, что у вас:

    1. Развернут MetalLB: См. Создание пула внешних IP-адресов
    2. Настроен BGP Peer: См. Создание BGP Peer
    3. Пул внешних IP-адресов: Настроен IPAddressPool с BGPAdvertisement

    Шаги

    Разверните приложение с Service типа LoadBalancer и externalTrafficPolicy: Local:

    # nginx-loadbalancer-local-demo.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
            - name: nginx
              image: nginx:1.25
              ports:
                - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-loadbalancer-local
    spec:
      type: LoadBalancer
      externalTrafficPolicy: Local
      selector:
        app: nginx
      ports:
        - port: 80
          targetPort: 80

    Ключевые моменты настройки

    externalTrafficPolicy: Local

    Параметр externalTrafficPolicy: Local обеспечивает:

    • Сохранение исходного IP: Исходный IP клиента сохраняется, что важно для логирования и политики безопасности
    • Прямой маршрут к Pod: Трафик направляется напрямую к Pod без пересылки на уровне узла

    LoadBalancer с BGP

    При использовании MetalLB в режиме BGP:

    • Маршруты объявляются с узлов, указанных в nodeSelectors BGPAdvertisement
    • BGP peer получает эти объявления и маршрутизирует трафик соответствующим образом
    • Совпадение селекторов узлов между BGPPeer и BGPAdvertisement обеспечивает согласованность маршрутизации

    Шаги развертывания

    1. Разверните приложение:

      kubectl apply -f nginx-loadbalancer-local-demo.yaml
    2. Проверьте Service LoadBalancer:

      kubectl get svc nginx-loadbalancer-local

      Ожидаемый вывод:

      NAME                     TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
      nginx-loadbalancer-local LoadBalancer   10.0.2.57       4.4.4.3       80:30005/TCP   30s
    3. Проверьте работу сервиса:

      curl http://4.4.4.3

    Проверка

    • Мониторинг endpoints сервиса: kubectl get endpoints nginx-loadbalancer-local
    • Просмотр статуса сервиса: kubectl describe svc nginx-loadbalancer-local