обнаружение службы kubernetes с определенной конечной точкой (DNS)

Я использую кластер AKS в Azure. Я пытаюсь обнаружить службу с помощью DNS (http://my-api.default.svc.cluster.local:3000/), но он не работает (этот сайт недоступен). С конечной точкой IP службы все работает нормально.

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-api
  labels:
    app: my-api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-api
  template:
    metadata:
      labels:
    app: my-api
    spec:
      containers:
      - name: my-api
    image: test.azurecr.io/my-api:latest
    ports:
    - containerPort: 3000
      imagePullSecrets:
      - name: testsecret
---
apiVersion: v1
kind: Service
metadata:
  name: my-api
spec:
  selector:
    app: my-api
  ports:
  - protocol: TCP
    port: 3000
    targetPort: 3000

kubectl описать службы kube-dns --namespace kube-system

Name:              kube-dns
Namespace:         kube-system
Labels:            addonmanager.kubernetes.io/mode=Reconcile
               k8s-app=kube-dns
               kubernetes.io/cluster-service=true
               kubernetes.io/name=KubeDNS
Annotations:       kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"addonmanager.kubernetes.io/mode":"Reconcile","k8s-app":"kube-dns","kubernet...
Selector:          k8s-app=kube-dns
Type:              ClusterIP
IP:                10.10.110.110
Port:              dns  53/UDP
TargetPort:        53/UDP
Endpoints:         10.10.100.54:53,10.10.100.64:53
Port:              dns-tcp  53/TCP
TargetPort:        53/TCP
Endpoints:         10.10.100.54:53,10.10.100.64:53
Session Affinity:  None
Events:            <none>

kubectl описывает svc my-api

Name:              my-api
Namespace:         default
Labels:            <none>
Annotations:       kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"my-api","namespace":"default"},"spec":{"ports":[{"port":3000,"protocol":...
Selector:          app=my-api
Type:              ClusterIP
IP:                10.10.110.104
Port:              <unset>  3000/TCP
TargetPort:        3000/TCP
Endpoints:         10.10.100.42:3000
Session Affinity:  None
Events:            <none>

Со второго POD

kubectl exec -it second-pod /bin/bash
curl my-api.default.svc.cluster.local:3000
Response: {"value":"Hello world2"}

Веб-сайт From Second POD использует ту же конечную точку, но не подключается к службе.

введите здесь описание изображения


person Ronak Patel    schedule 07.09.2018    source источник
comment
Почему? Обычно вы используете DNS-имя, которое предоставляет kube-dns (my-api.default.svc.cluster.local), и служба находит соответствующий Pod по совпадениям меток, не беспокоясь о конкретных IP-адресах.   -  person David Maze    schedule 07.09.2018
comment
@DavidMaze: нужно ли мне определять конфигурацию DNS при развертывании?   -  person Ronak Patel    schedule 07.09.2018
comment
Ничего особенного делать не надо, нет.   -  person David Maze    schedule 07.09.2018
comment
Итак, я пытаюсь получить доступ к службе с помощью my-api.default.svc.cluster.local:3000 и использую селектор в службе вместо определения конечных точек, но получаю This site can’t be reached ошибку. Если я обращаюсь к нему с помощью IP-адреса, все работает нормально.   -  person Ronak Patel    schedule 07.09.2018
comment
Глядя на ваш yaml, я вижу проблему с отступом при указании меток в шаблоне Pod. Надеюсь, это не вызовет проблем.   -  person leodotcloud    schedule 11.09.2018


Ответы (3)


Исправив отступ в вашем yaml-файле, я смог успешно запустить развертывание и обслуживание. Также разрешение DNS работало нормально.

Отличия:

  • Фиксированный отступ
  • Использованы test1 пространства имен вместо default
  • Использовал containerPort 80 вместо 3000
  • Использовал мое изображение

Развертывание:

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  labels:
    app: my-api
  name: my-api
  namespace: test1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-api
  template:
    metadata:
      labels:
        app: my-api
    spec:
      containers:
      - image: leodotcloud/swiss-army-knife
        name: my-api
        ports:
        - containerPort: 80
          protocol: TCP

Услуга:

apiVersion: v1
kind: Service
metadata:
  name: my-api
  namespace: test1
spec:
  ports:
  - port: 3000
    protocol: TCP
    targetPort: 80
  selector:
    app: my-api
  type: ClusterIP

second-pod-test

Шаги отладки:

  • Установите tcpdump внутри обоих контейнеров kube-dns и начните перехват DNS-трафика (с фильтрами со второго IP-адреса модуля).
  • Изнутри второго модуля выполните команду curl или dig, используя полное доменное имя.
  • Проверьте, достигают ли пакеты запроса DNS контейнеров kube-dns.
  • Если нет, проверьте наличие проблем с сетью.
  • Если разрешение DNS работает, запустите tcpdump внутри контейнера приложения и проверьте, доходит ли пакет curl до контейнера.
  • Проверьте исходный и целевой IP-адрес пакетов.
  • Проверьте правила iptables на хостах.
  • Проверьте настройки sysctl.
person leodotcloud    schedule 11.09.2018
comment
В моем случае dns также работает из второго модуля, когда я использую curl, но приложение, работающее внутри этого модуля, не может получить к нему доступ. Даже когда я использую частный IP-адрес в своем браузере, он работает, но DNS не работает. (ноутбук подключен к VNET, поэтому частные IP-адреса и DNS должны работать). Пожалуйста, проверьте прикрепленное изображение в вопросе. - person Ronak Patel; 11.09.2018
comment
kube-dns работает только внутри кластера, поэтому CNAME нельзя будет разрешить извне (ноутбук). Какое приложение мы рассматриваем? Обычно приложения используют свои собственные библиотеки DNS, которые могут иметь свои особенности. - person leodotcloud; 11.09.2018
comment
Итак, в основном, на уровне кубернетов все выглядит нормально, поскольку я могу получить доступ к сервису через второй модуль с DNS, но сервис не подвергается воздействию лазурного узла. Я проверил его по ssh в узел и свернул службу. Он работает с IP-адресом конечной точки службы, но не с DNS. - person Ronak Patel; 11.09.2018
comment
@RonakPatel вы можете подключиться к Kubernetes Services с узла по IP, потому что сетевая маршрутизация к службам работает на уровне узла. Но вы не сможете разрешить полное доменное имя своего узла, потому что DNS в кластере, который содержит записи о ваших службах, доступен только внутри модулей, а не на узле. Я думаю, вы можете разрешить эти имена из узлов, но вам следует вручную настроить DNS на своих узлах и установить IP-адрес службы DNS в кластере в качестве преобразователя для зоны *.local. - person Anton Kostenko; 14.09.2018
comment
@AntonKostenko: Вы правы. Я недавно узнал об этом. Я опубликую конкретное решение, как только я его протестирую, или вы можете ответить, как настроить частный DNS вручную в Azure и подключить его к AKS. Спасибо за ваш вклад. - person Ronak Patel; 14.09.2018

Если вы используете Deployment для развертывания своего приложения в кластере, где оно будет использоваться через Service, вам вообще не нужно будет вручную устанавливать Endpoints. Просто положитесь на кубернеты и определите обычный селектор в своем объекте Service.

Кроме того, когда это имеет смысл (внешняя служба, потребляемая из кластера), вам необходимо убедиться, что определение ваших Endpoints портов полностью соответствует определению для службы (включая протокол и, возможно, имя). Это неполное сопоставление является наиболее частой причиной того, что конечные точки не видны как часть службы.

person Radek 'Goblin' Pieczonka    schedule 07.09.2018
comment
Как я могу получить доступ к службе, используя DNS по умолчанию? kube-dns уже установлен, но когда я пытаюсь получить доступ к службе с помощью DNS, он не работает. В любом случае мне нужна исправленная конечная точка для доступа к этой службе. - person Ronak Patel; 07.09.2018
comment
что вы получаете, когда kubectl describe svc my-api? - person Radek 'Goblin' Pieczonka; 07.09.2018
comment
вы уверены, что ваше приложение прослушивает и отвечает на 3000? - person Radek 'Goblin' Pieczonka; 07.09.2018
comment
да. Когда я использую предоставленные конечные точки, они работают, но не эта: my-api.default.svc.cluster.local:3000 - person Ronak Patel; 07.09.2018
comment
Я могу получить доступ к услуге с IP-адресом изнутри и вне модуля. Но с DNS доступ к нему возможен только из 2-го модуля (когда я использую curl). Но, опять же, приложение в этом модуле не может использовать эту службу с DNS. - person Ronak Patel; 08.09.2018

Из приведенного выше обсуждения я понял, что вы хотите предоставить услугу, но не используете IP-адрес. Служба может быть раскрыта по-разному. вам следует искать тип службы LoadBalancer.

Попробуйте изменить свой сервис следующим образом:

apiVersion: v1
kind: Service
metadata:
  name: my-api
spec:
  type: LoadBalancer
  selector:
    app: my-api
  ports:
  - protocol: TCP
    port: 3000
    targetPort: 3000

Это создаст балансировщик нагрузки и сопоставит ваш сервис с ним.

Позже вы можете добавить этот балансировщик нагрузки в свою службу сопоставления DNS, предоставляемую Azure, чтобы присвоить желаемое доменное имя. пример: http:\\my-api.example.com:3000

Также я хотел бы добавить, если вы определите свои порты следующим образом:

ports:
  - name: http
    port: 80
    targetPort: 3000

Это перенаправит трафик, поступающий на порт 80, на порт 3000, и ваш сервисный вызов, например, будет выглядеть намного чище. http:\\my-api.example.com

person prranay    schedule 16.09.2018