• Русский
  • Создание сервисов

    В 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 к Service:

      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Определяет использование частной сети.
    loud.google.com/l4-rbsenabledПо умолчанию публичный. Если этот параметр настроен, трафик будет направляться напрямую на Pod.