Как явно определить конечную точку службы Kubernetes

Я подготовил кластер kubernetes на своей паре виртуальных машин с помощью kubespray. Kubespray использует project-calico в качестве сетевого плагина по умолчанию, который довольно хорошо соответствует моим требованиям к прокси-сервисам в сети кластера во внешний мир.

Kubespray развертывает сам apiserver как службу ClusterIP. Чтобы сделать его доступным извне, он определяет конечную точку этой службы с IP-адресом хоста главных узлов, который маршрутизируется на внутренний ClusterIP с помощью Calico, насколько я мог понять это самостоятельно.

Мой вопрос: как можно определить мою собственную конечную точку (для другой службы), поскольку они уже неявно определены путем предоставления service.yaml и не могут быть перезаписаны. Я хотел бы следовать аналогичному подходу, чтобы моя Rook/Ceph Dashboard была видна из-за пределов кластера.

РЕДАКТИРОВАТЬ: обратите внимание, что kubectl get ingresses.networking.k8s.io --all-namespaces возвращает No resources found., а kubectl describe service kubernete возвращает

Name:              kubernetes
Namespace:         default
Labels:            component=apiserver
                   provider=kubernetes
Annotations:       <none>
Selector:          <none>
Type:              ClusterIP
IP:                10.233.0.1
Port:              https  443/TCP
TargetPort:        6443/TCP
Endpoints:         192.168.103.254:6443
Session Affinity:  None
Events:            <none>

person Jürgen Zornig    schedule 19.12.2019    source источник
comment
Это больше связано с контроллером входа и входом. Чтобы ваша служба работала с настраиваемыми конечными точками, чтобы внешние службы могли обращаться к службе, работающей внутри кластера kubernetes, вам нужен вход, подключенный к вашей службе. Дополнительные сведения см. в этой документации Ingress.   -  person BinaryMonster    schedule 19.12.2019
comment
@BinaryBullet да, я уже много читал о входе и о том, что это правильный способ балансировки нагрузки и т. Д. Мне просто интересно, что в свежем кластере с kubespray на самом деле не определен вход ... он просто работает с конечной точкой на IP-адресе главного хоста, маршрутизируемом в службу ClusterIP с помощью calico, и мне было интересно, как я могу определить аналогичную настройку   -  person Jürgen Zornig    schedule 19.12.2019
comment
Если вы не хотите использовать вход и хотите получать через IP-адрес главного хоста, вы можете напрямую использовать прокси-сервер или службу (либо haproxy, nginx и т. д.), чтобы направлять трафик с внешнего URL-адреса на конкретный IP-адрес хоста напрямую. Я точно не уверен, что это то, что вы ищете. Если я ошибаюсь в этом, пожалуйста, поправьте меня. Как вы уже читали о входе, он имеет преимущество в маршрутизации и управлении трафиком. Надеюсь, это полезно.   -  person BinaryMonster    schedule 19.12.2019
comment
@BinaryBullet это также не совсем то, о чем я спрашиваю, потому что даже если есть HAProxy, это не решает часть маршрутизации внешнего IP-адреса узлов на IP-адрес внутренней сети кластера. Ingress решает эту проблему, и кажется, что есть еще один подход, который используется kubespray, который направляет apiserver наружу, явно определяя конечную точку на IP-адресе хоста. Я хотел бы знать, как это определение может быть сделано.   -  person Jürgen Zornig    schedule 19.12.2019


Ответы (2)


Я не совсем уверен, что вы имеете в виду, но я думаю, что вы ищете возможность предоставлять услуги извне.

Вы можете предоставлять свои услуги, такие как Rook/Ceph Dashboard, с помощью «Publishing Services» (типы услуг, которые предоставляют внутренние услуги извне).

Цитата из документации kubernetes:

Для некоторых частей вашего приложения (например, интерфейсов) вы можете захотеть предоставить сервису внешний IP-адрес, который находится за пределами вашего кластера.

Kubernetes ServiceTypes позволяет вам указать, какой сервис вам нужен. По умолчанию ClusterIP.

Type значения и их поведение:

  • ClusterIP: Предоставляет услугу на внутреннем IP-адресе кластера. Выбор этого значения делает службу доступной только внутри кластера. Это значение по умолчанию ServiceType.
  • NodePort: Предоставляет услугу на IP-адресе каждого узла на статическом порту. (NodePort). Служба ClusterIP, к которой направляется служба NodePort, создается автоматически. Вы сможете связаться со службой NodePort из-за пределов кластера, запросив <NodeIP>:<NodePort>.
  • LoadBalancer: предоставляет доступ к Службе извне с помощью балансировщика нагрузки облачного провайдера. NodePort и ClusterIP Сервисы, к которым маршрутизирует внешний балансировщик нагрузки, создаются автоматически.
  • ExternalName: сопоставляет сервис с содержимым поля externalName ( например foo.bar.example.com), возвращая запись CNAME со своим значением. Никакого проксирования не настроено.

Вот пример из документации.


Вы также можете определить Services с манифестами yaml следующим образом:

apiVersion: v1
kind: Service
metadata:
  name: examplelb
spec:
  type: LoadBalancer
  selector:
    app: asd
  ports:
    -
      name: koala
      port: 22223
      targetPort: 22225
      nodePort: 31913
    -
      name: grisly
      port: 22224
      targetPort: 22226
      nodePort: 31914
    -
      name: polar
      port: 22225
      targetPort: 22227
      nodePort: 31915

Это делает модули с меткой: app: asd открытыми следующими портами с шаблоном внутреннего порта 22223, открытым на 31913.

$ kubectl get svc examplelb
NAME        TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                                           AGE
examplelb   LoadBalancer   10.111.8.204   <pending>     22223:31913/TCP,22224:31914/TCP,22225:31915/TCP   7d2h

Если служба с типом LoadBalancer имеет ожидающий внешний IP-адрес, вы все равно можете получить доступ ко всем этим портам на каждом узле как NodePort.

Надеюсь это поможет.

person Piotr Malec    schedule 19.12.2019
comment
Да, я знаю.... См. мой РЕДАКТИРОВАТЬ в вопросе... я специально запрашиваю, потому что API kubernetes развертывается КАК служба ClusterIP... согласно документации, они должны быть видны только внутри кластера. Тем не менее, я могу получить доступ к своему apiserver из Outsider, потому что есть какой-то ситцевый хак, который самцы это возможно. Мне интересно, как работает этот хак. - person Jürgen Zornig; 19.12.2019

Я сошлюсь на ваш вопрос:

Как можно определить мою собственную конечную точку?

Вы должны будете:

1) Создайте сервис без селектора Pod:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 9376

(На этом этапе K8S не будет создавать автоматически сгенерированные конечные точки, потому что он не может решить, к каким модулям должны относиться эти конечные точки).

2 ) Создайте объект Endpoints и сопоставьте его с нужным сетевым адресом и портом, на котором работает внешний ресурс:

apiVersion: v1
kind: Endpoints
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 192.0.2.45
    ports:
      - port: 9376

(*) Обратите внимание, что имя службы должно совпадать с именем объекта Endpoints.

person RtmY    schedule 21.10.2020
comment
Я искал этот ответ. Также здесь есть подробное объяснение этого: kubernetes.io/ docs/concepts/services-networking/service/ - person hadican; 20.05.2021