Подтвердить что ты не робот

Как открыть сервис кубернетов для публики без жесткого кодирования для миньона IP?

У меня есть кластер кубернетов, работающий с 2 ​​миньонами. В настоящее время я предоставляю услугу в 2 этапа:

  • Запустить контроллер репликации и pod
  • Получить minion IP (используя kubectl get minions) и установить его как publicIPs для Сервиса.

Какова предлагаемая практика разоблачения услуги для общественности? Мой подход кажется неправильным, потому что я жестко кодирую IP-адреса отдельных миньонов IP-ов. Он также, кажется, обходит возможности балансировки нагрузки услуг кубернетов, поскольку клиентам приходилось напрямую обращаться к службам, работающим на отдельных миньонах.

Чтобы настроить контроллер репликации и модуль, я использую:

id: frontend-controller
kind: ReplicationController
apiVersion: v1beta1
desiredState:
  replicas: 2
  replicaSelector:
    name: frontend-pod
  podTemplate:
    desiredState:
      manifest:
        version: v1beta1
        id: frontend-pod
        containers:
          - name: sinatra-docker-demo
            image: madisn/sinatra_docker_demo
            ports:
              - name: http-server
                containerPort: 4567
    labels:
      name: frontend-pod

Чтобы настроить службу (после получения minion ip-s):

kind: Service
id: frontend-service
apiVersion: v1beta1
port: 8000
containerPort: http-server
selector:
  name: frontend-pod
labels:
  name: frontend
publicIPs: [10.245.1.3, 10.245.1.4]
4b9b3361

Ответ 1

Как я уже упоминал в комментарии выше, createExternalLoadBalancer - соответствующая абстракция, которую вы ищете, но, к сожалению, она еще не реализована для всех поставщиков облачных вычислений, и в частности для бродяг, которые вы используете локально.

Один из вариантов - использовать общедоступные IP-адреса для всех миньонов в вашем кластере для всех служб, которые вы хотите отключить. Трафик, предназначенный для службы, попадет на одного из миньонов, где он будет перехвачен процессом kube-proxy и перенаправлен на модуль, который соответствует селектору меток для службы. Это может привести к дополнительному переходу по сети (если вы приземлитесь на node, который не поддерживает локальную сеть), но для приложений, которые не очень чувствительны к задержке в сети, это, вероятно, не будет заметным.

Ответ 2

Как сказал Роберт в своем ответе, это то, что происходит, но, к сожалению, пока недоступно.

В настоящее время я запускаю кластер Kubernetes в нашей сети центров обработки данных. У меня есть 1 мастер и 3 миньона, которые работают на виртуальных сайтах CentOS 7 (vcenter). То, как я справлялся с этим, - создать выделенный сервер "kube-proxy". В основном я просто запускаю службу Kube-Proxy (вместе с Flannel для сети), а затем назначая "общедоступные" IP-адреса сетевому адаптеру, подключенному к этому серверу. Когда я говорю публично, я имею в виду адреса в нашей локальной сети центров обработки данных. Затем, когда я создаю службу, к которой я хотел бы получить доступ за пределами кластера, я просто установил значение publicIPs на один из доступных IP-адресов на сервере kube-proxy. Когда кто-то или что-то пытается подключиться к этой службе извне кластера, он попадет в прокси-сервер kube, а затем будет перенаправлен на соответствующий миньон.

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

Ответ 3

Если вы используете локальный кластер, я использовал для этого службу на своих узлах kubernetes, используя директиву nodeport в определении вашего сервиса, а затем объединить robin с каждым node в вашем кластере с помощью HAproxy.

Здесь то, что обнажает узел, выглядит следующим образом:

apiVersion: v1
kind: Service
metadata:
  name: nginx-s
  labels:
    name: nginx-s
spec:
  type: NodePort
  ports:
    # must match the port your container is on in your replication controller
    - port: 80
      nodePort: 30000
  selector:
    name: nginx-s

Примечание. Указанное значение должно находиться в пределах заданного диапазона для портов node. (по умолчанию: 30000-32767)

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

Если вы посмотрите на свою таблицу nat на одном из ваших хостов, вы можете увидеть, что она делает.

[email protected]:~# kubectl create -f nginx-s.yaml
You have exposed your service on an external port on all nodes in your
cluster.  If you want to expose this service to the external internet, you may
need to set up firewall rules for the service port(s) (tcp:30000) to serve traffic.

See http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md for more details.
services/nginx-s
[email protected]:~# iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
KUBE-PORTALS-CONTAINER  all  --  anywhere             anywhere             /* handle ClusterIPs; NOTE: this must be before the NodePort rules */
DOCKER     all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL
KUBE-NODEPORT-CONTAINER  all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL /* handle service NodePorts; NOTE: this must be the last rule in the chain */

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
KUBE-PORTALS-HOST  all  --  anywhere             anywhere             /* handle ClusterIPs; NOTE: this must be before the NodePort rules */
DOCKER     all  --  anywhere            !127.0.0.0/8          ADDRTYPE match dst-type LOCAL
KUBE-NODEPORT-HOST  all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL /* handle service NodePorts; NOTE: this must be the last rule in the chain */

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  172.17.0.0/16        anywhere

Chain DOCKER (2 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere

Chain KUBE-NODEPORT-CONTAINER (1 references)
target     prot opt source               destination
REDIRECT   tcp  --  anywhere             anywhere             /* default/nginx-s: */ tcp dpt:30000 redir ports 42422

Chain KUBE-NODEPORT-HOST (1 references)
target     prot opt source               destination
DNAT       tcp  --  anywhere             anywhere             /* default/nginx-s: */ tcp dpt:30000 to:169.55.21.75:42422

Chain KUBE-PORTALS-CONTAINER (1 references)
target     prot opt source               destination
REDIRECT   tcp  --  anywhere             192.168.3.1          /* default/kubernetes: */ tcp dpt:https redir ports 51751
REDIRECT   tcp  --  anywhere             192.168.3.192        /* default/nginx-s: */ tcp dpt:http redir ports 42422

Chain KUBE-PORTALS-HOST (1 references)
target     prot opt source               destination
DNAT       tcp  --  anywhere             192.168.3.1          /* default/kubernetes: */ tcp dpt:https to:169.55.21.75:51751
DNAT       tcp  --  anywhere             192.168.3.192        /* default/nginx-s: */ tcp dpt:http to:169.55.21.75:42422
[email protected]:~#

В частности, эта строка

DNAT       tcp  --  anywhere             anywhere             /* default/nginx-s: */ tcp dpt:30000 to:169.55.21.75:42422

И, наконец, если вы посмотрите на netstat, вы увидите, что kube-proxy прослушивает и ждет эту службу на этом порту.

[email protected]:~# netstat -tupan | grep 42422
tcp6       0      0 :::42422                :::*                    LISTEN      20748/kube-proxy
[email protected]:~#

Kube-proxy будет прослушивать порт для каждой службы и выполнять трансляцию сетевых адресов в вашу виртуальную подсеть, в которой находятся ваши контейнеры. (Я думаю?) Я использовал фланель.


Для двух кластеров node эта конфигурация HAproxy может выглядеть примерно так:

listen sampleservice 0.0.0.0:80
    mode http
    stats enable
    balance roundrobin
    option httpclose
    option forwardfor
    server noname 10.120.216.196:30000 check
    server noname 10.155.236.122:30000 check
    option httpchk HEAD /index.html HTTP/1.0

И ваш сервис теперь доступен на порту 80 через HAproxy. Если какой-либо из ваших узлов опустится, контейнеры будут перемещены в другой node благодаря контроллерам репликации, а HAproxy будет перенаправляться только на ваши живые узлы.

Мне любопытно, какие методы использовали другие, что именно я придумал. Обычно я не отправляю сообщение о переполнении стека, поэтому извиняюсь, если я не следую соглашениям или правильному форматированию.

Ответ 4

Это для MrE. Мне не хватило места в области комментариев, чтобы опубликовать этот ответ, поэтому мне пришлось создать еще один ответ. Надеюсь, это поможет:

Мы действительно отошли от Кубернеса после публикации этого ответа. Если я правильно помню, хотя все, что мне действительно нужно было сделать, это запустить исполняемый файл kube-proxy на специализированной виртуальной машине CentOS. Вот что я сделал:

Сначала я удалил Firewalld и поместил iptables на место. Kube-proxy полагается на iptables для обработки NAT и перенаправления.

Во-вторых, вам необходимо установить фланель, чтобы вы могли иметь адаптер моста в той же сети, что и службы Docker, работающие на ваших миньонах.

Затем я назначил несколько IP-адресов локальному сетевому адаптеру, установленному на компьютере. Это будут IP-адреса, которые вы можете использовать при настройке службы. Это будут адреса, доступные вне вашего кластера.

Как только все будет позабочено, вы можете запустить службу прокси. Он подключится к Мастеру и возьмет IP-адрес для сети фланелевых мостов. Затем он будет синхронизировать все правила IPtables, и вы должны быть настроены. Каждый раз, когда добавляется новая служба, она создает правила прокси и реплицирует эти правила для всех миньонов (и вашего прокси). Пока вы указываете IP-адрес, доступный на вашем прокси-сервере, этот прокси-сервер пересылает весь трафик для этого IP-адреса на соответствующий миньон.

Надеюсь, это немного более ясно. Помните, хотя я не был частью проекта Kubernetes около 6 месяцев, поэтому я не уверен, что изменилось с тех пор, как я ушел. У них может даже быть функция, которая справляется с такими вещами. Если не надеюсь, это поможет вам позаботиться о нем.

Ответ 5

Вы можете использовать Ingress ресурс, чтобы внешние подключения извне кластера Kubernetes могли получить доступ к службам кластера.

Предполагая, что у вас уже установлен модуль Pod, теперь вам нужен ресурс службы, например:

apiVersion: v1 kind: Service metadata: name: frontend-service labels: tier: frontend spec: type: ClusterIP selector: name: frontend-pod ports: - name: http protocol: TCP # the port that will be exposed by this service port: 8000 # port in a docker container; defaults to what "port" has set targetPort: 8000

И вам нужен ресурс Ingress: apiVersion: extensions/v1beta1 kind: Ingress metadata: name: frontend-ingress spec: rules: - host: foo.bar.com http: paths: - path: / backend: serviceName: frontend-service # the targetPort from service (the port inside a container) servicePort: 8000 Чтобы иметь возможность использовать ресурсы Ingress, вам понадобится