Kubernetes: использовать iptables для проксирования вместо пользовательского пространства

Созданный на 23 янв. 2015  ·  187Комментарии  ·  Источник: kubernetes/kubernetes

Вчера я играл с iptables и прототипировал (ну, скопировал из результатов Google и изменил) набор правил iptables, которые, по сути, делают все прокси за нас без помощи пользовательского пространства. Это не срочно, но я хочу сохранить свои заметки до того, как потеряю их.

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

Вероятно, это можно оптимизировать в дальнейшем, но при базовом тестировании я вижу, что липкие сеансы работают, и если я закомментирую эту часть, я вижу ~ равную вероятность попадания в каждый бэкэнд. Мне не удалось заставить детерминированный циклический алгоритм работать должным образом (с --nth вместо --probability), но мы могли бы вернуться к этому, если захотим.

Это устанавливает сервисный портал с перечисленными ниже серверными модулями.

iptables -t nat -N TESTSVC
iptables -t nat -F TESTSVC
iptables -t nat -N TESTSVC_A
iptables -t nat -F TESTSVC_A
iptables -t nat -N TESTSVC_B
iptables -t nat -F TESTSVC_B
iptables -t nat -N TESTSVC_C
iptables -t nat -F TESTSVC_C
iptables -t nat -A TESTSVC -m recent --name hostA --rcheck --seconds 1 --reap -j TESTSVC_A
iptables -t nat -A TESTSVC -m recent --name hostB --rcheck --seconds 1 --reap -j TESTSVC_B
iptables -t nat -A TESTSVC -m recent --name hostC --rcheck --seconds 1 --reap -j TESTSVC_C
iptables -t nat -A TESTSVC -m statistic --mode random --probability 0.333 -j TESTSVC_A
iptables -t nat -A TESTSVC -m statistic --mode random --probability 0.500 -j TESTSVC_B
iptables -t nat -A TESTSVC -m statistic --mode random --probability 1.000 -j TESTSVC_C

iptables -t nat -A TESTSVC_A -m recent --name hostA --set -j DNAT -p tcp --to-destination 10.244.4.6:9376
iptables -t nat -A TESTSVC_B -m recent --name hostB --set -j DNAT -p tcp --to-destination 10.244.1.15:9376
iptables -t nat -A TESTSVC_C -m recent --name hostC --set -j DNAT -p tcp --to-destination 10.244.4.7:9376

iptables -t nat -F KUBE-PORTALS-HOST
iptables -t nat -A KUBE-PORTALS-HOST -d 10.0.0.93/32 -m state --state NEW -p tcp -m tcp --dport 80 -j TESTSVC
iptables -t nat -F KUBE-PORTALS-CONTAINER
iptables -t nat -A KUBE-PORTALS-CONTAINER -d 10.0.0.93/32 -m state --state NEW -p tcp -m tcp --dport 80 -j TESTSVC
prioritawaiting-more-evidence release-note sinetwork siscalability

Все 187 Комментарий

Прохладный! Я думаю, что мы обязательно должны объединить это. С другой стороны, я видел, как прокси съедает ~ 30% ядра при большой нагрузке, я должен верить, что iptables даст нам лучшую производительность, чем это.

Мы должны расставить приоритеты - это почти полная переработка kube-proxy и
все тесты оного. У него также есть проблемы с обратной совместимостью (не будет работать на
старые ядра или старые двоичные файлы iptables).

В пн, 26 января 2015 г., в 11:06, Брендан Бернс [email protected]
написал:

Прохладный! Я думаю, нам обязательно нужно объединить это. Отдельно отметим,
Я видел, как прокси съедает ~ 30% ядра при большой нагрузке, мне нужно
считают, что iptables даст нам лучшую производительность, чем это.

Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -71517501
.

Может быть, имеет смысл реализовать его как параллельный вариант и медленно мигрировать?

В пн, 26 января 2015 г., в 12:01, Тим Хокин [email protected]
написал:

Мы должны расставить приоритеты - это почти полная переработка kube-proxy и
все тесты оного. У него также есть проблемы с обратной совместимостью (не будет работать на
старые ядра или старые двоичные файлы iptables).

В пн, 26 января 2015 г., в 11:06, Брендан Бернс [email protected]
написал:

Прохладный! Я думаю, нам обязательно нужно объединить это. На отдельном
Примечание,
Я видел, как прокси съедает ~ 30% ядра при большой нагрузке, мне нужно
считают, что iptables даст нам лучшую производительность, чем это.

Ответьте на это письмо напрямую или просмотрите его на GitHub
<
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -71517501

.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -71527216
.

Я пытаюсь уговорить кого-то, кто плохо знает этот код, выучить его
и возьми это на себя. Я действительно _want_ взяться за это, но было бы лучше, если бы
кто-то другой изучил это пространство (не вы! :)

Тем не менее, вы также отправили (хорошее) электронное письмо о большом списке P1 - и я
не думаю, что это еще в этом списке.

В пн, 26 января 2015 г., в 13:06, Брендан Бернс [email protected]
написал:

Возможно, реализация его как параллельного варианта и медленная миграция сделает
смысл?

В пн, 26 января 2015 г., в 12:01, Тим Хокин [email protected]
написал:

Мы должны расставить приоритеты - это почти полная переработка kube-proxy.
а также
все тесты оного. У него также есть проблемы с обратной совместимостью (не будет работать
на
старые ядра или старые двоичные файлы iptables).

В пн, 26 января 2015 г., в 11:06, Брендан Бернс <
[email protected]>
написал:

Прохладный! Я думаю, нам обязательно нужно объединить это. На отдельном
Примечание,
Я видел, как прокси съедает ~ 30% ядра при большой нагрузке, мне нужно
считают, что iptables даст нам лучшую производительность, чем это.

Ответьте на это письмо напрямую или просмотрите его на GitHub
<

https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -71517501

.

Ответьте на это письмо напрямую или просмотрите его на GitHub
<
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment-71527216>

.

Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -71538256
.

Это P2? Может, стоит пока сделать из него P3?

Я надеюсь, что это сработает, но мы еще можем понизить его.

В среду, 11 февраля 2015 г., в 14:49, Сатнам Сингх [email protected]
написал:

Это P2? Может, стоит пока сделать из него P3?

Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -73982161
.

Разве «надежда» не приравнивается к P3, до которой мы доберемся, если сможем?

Из обсуждения с @thockin : Это требование для поддержки диапазонов служебных портов, которые не требуются для версии 1.0, но мы хотели бы поддерживать их в конечном итоге.

@thockin "

Не СЛИШКОМ новый, но у нас есть некоторые пользователи, которые ДЕЙСТВИТЕЛЬНО хотят использовать iptables с 2012 по
Работа.

В понедельник, 23 февраля 2015 г., в 14:44, Сидхарта Ситхана < [email protected]

написал:

@thockin https://github.com/thockin "У этого есть обратная сторона: не
совместим со старыми iptables и ядрами. "Насколько новым будет ядро
должен быть?

Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -75654187
.

@thockin спасибо. Например, мы используем / тестируем с RHEL / CentOS 6 - поэтому было бы неплохо, если бы у нас не было жесткой зависимости от последних ядер 3.x.

@ pweil- мы обсуждали это на днях
В понедельник, 23 февраля 2015 г., в 23:40 Сидхарта Ситхана [email protected]
написал:

@thockin https://github.com/thockin спасибо. Мы используем / тестируем с
Например, RHEL / CentOS 6 - так что было бы неплохо, если бы у нас не было жесткого
зависимость от последних ядер 3.x.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -75698480
.

Что ж, вам действительно нужен Docker для запуска, и в какой-то момент мы должны его отключить.
Поддержка back-rev iptables не остановит меня от (в конечном итоге) создания
это изменение, и это будет больно для некоторых людей.

В понедельник, 23 февраля 2015 г., в 20:40, Сидхарта Ситхана < [email protected]

написал:

@thockin https://github.com/thockin спасибо. Мы используем / тестируем с
Например, RHEL / CentOS 6 - так что было бы неплохо, если бы у нас не было жесткого
зависимость от последних ядер 3.x.

Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -75698480
.

С помощью @thockin мы попробовали то же самое с udp.

Мы создали кластер GCE Kubernetes с 3 контроллерами репликации sky-dns.
На kubernetes-master мы устанавливаем в iptables следующее:
IP-адрес службы DNS был 10.0.0.10, а конечные точки pod, на которых запущены DNS, были 10.244.0.5:53, 10.244.3.6:53, 10.244.0.6:53.

iptables -t нат -N ТЕСТСВЦ
iptables -t нат -F ТЕСТСВЦ
iptables -t нат -N ТЕСТСВС_А
iptables -t нат -F ТЕСТСВС_А
iptables -t нат -N ТЕСТСВС_Б
iptables -t нат -F ТЕСТСВС_Б
iptables -t нат -N ТЕСТСВК_С
iptables -t нат -F ТЕСТСVC_C
iptables -t nat -N KUBE-PORTALS-HOST
iptables -t nat -F KUBE-PORTALS-HOST

iptables -t nat -A TESTSVC -m недавний --name hostA --rcheck --seconds 1 --reap -j TESTSVC_A
iptables -t nat -A TESTSVC -m недавний --name hostB --rcheck --seconds 1 --reap -j TESTSVC_B
iptables -t nat -A TESTSVC -m недавнее --name hostC --rcheck --seconds 1 --reap -j TESTSVC_C

iptables -t nat -A TESTSVC -m statistic --mode random --probability 0.333 -j TESTSVC_A
iptables -t nat -A TESTSVC -m statistic --mode random --probability 0.5 -j TESTSVC_B
iptables -t nat -A TESTSVC -m statistic --mode random --probability 1.000 -j TESTSVC_C

iptables -t nat -A TESTSVC_A -m недавний --name hostA --set -j DNAT -p udp --to-destination 10.244.0.5:53
iptables -t nat -A TESTSVC_B -m latest --name hostB --set -j DNAT -p udp --to-destination 10.244.3.6:53
iptables -t nat -A TESTSVC_C -m недавний --name hostC --set -j DNAT -p udp --to-destination 10.244.0.6:53
iptables -t nat -A KUBE-PORTALS-HOST -d 10.0.0.10/32 -p udp -m udp --dport 53 -j TESTSVC
iptables -t nat -A ВЫХОД -j KUBE-PORTALS-HOST


kubernetes-master> nslookup kubernetes.default.kuberenetes.local 10.0.0.10

Получаем ответ!

Отличный материал! Просто к вашему сведению (подтверждается нашим личным разговором), запускать несколько одновременных команд iptables в целом небезопасно (разные цепочки звучат так, как будто это может быть нормально). iptables - это оболочка для libiptc, и см. комментарий к iptc_commit: http://www.tldp.org/HOWTO/Querying-libiptc-HOWTO/mfunction.html

Это было , по- видимому зафиксирован в 2013 году, но , возможно , только если вы передаете --wait (?): Http://git.netfilter.org/iptables/commit/?id=93587a04d0f2511e108bbc4d87a8b9d28a5c5dd8

Основная причина этого в том, что iptables эффективно вызывает iptables-save / iptables-restore (по крайней мере для каждой цепочки); Я видел много кода, который просто вызывает iptables-save и iptables-restore вместо того, чтобы делать что-то посредством добавления и удаления. У меня даже может быть какой-то код, который я мог бы выкопать, если это будет полезно.

Мне непонятно, что нет возможности выполнять операции типа CAS или LL / SC.

Мы должны добавить поддержку --wait, хотя она появилась достаточно недавно, чтобы GCE
В debian-backports этого нет.

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

26 февраля 2015 г., в 13:56, Джастин Санта-Барбара <
[email protected]> написал:

Отличный материал! Просто к вашему сведению (подтверждается нашим личным разговором),
вообще небезопасно запускать несколько одновременных команд iptables
(разные цепи звучат так, как будто все в порядке). iptables - это оболочка вокруг
libiptc и посмотрите комментарий к iptc_commit:
http://www.tldp.org/HOWTO/Querying-libiptc-HOWTO/mfunction.html

По-видимому, это было исправлено в 2013 году, но, возможно, только если вы передадите --wait (?):
http://git.netfilter.org/iptables/commit/?id=93587a04d0f2511e108bbc4d87a8b9d28a5c5dd8

Основная причина этого в том, что iptables эффективно вызывает iptables-save /
iptables-restore (по крайней мере, для каждой цепочки); Я видел много кода, который просто
поэтому вызывает iptables-save & iptables-restore вместо того, чтобы делать что-то
через добавляет и удаляет. У меня даже может быть какой-то код, чтобы я мог копать
вверх, если это полезно.

Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -76282629
.

Что происходит в случае неудач при создании кучи правил?

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

26 февраля 2015 г., в 20:47, Брайан Грант [email protected]
написал:

Что происходит в случае неудач при создании кучи
правила?

Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -76331174
.

@thockin Сегодня из irc:

net.ipv4.conf.all.route_localnet позволяет 127.0.0.1 быть целью правил DNAT . Из документов :

route_localnet - БУЛЕВЫЙ

Не считайте адреса обратной связи как марсианский источник или пункт назначения.
при маршрутизации. Это позволяет использовать 127/8 для целей локальной маршрутизации.
по умолчанию ЛОЖЬ

Будем ли мы интегрировать это в kubelet или хранить в отдельном демоне? Kubelet уже наблюдает за сервисами, чтобы заполнить env vars.

Я хотел бы сохранить его как отдельный двоичный файл. Есть причины, по которым ты
может захотеть запустить это на других машинах (например, домашних виртуальных машинах) за пределами k8s
кластер, чтобы получить доступ к сервисам k8s.

--brendan

Пт, 13 марта 2015 г., в 11:37, Брайан Грант [email protected]
написал:

Будем ли мы интегрировать это в kubelet или хранить в отдельном демоне?
Kubelet уже наблюдает за сервисами, чтобы заполнить env vars.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79230747
.

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

while (true) {
actualState = iptablesSave ()
если фактическое состояние! = желаемое состояние {iptablesRestore (желаемое состояние))
sleep_a_ while ()
}

Согласитесь на 100%, это правильный способ справиться с ошибкой при написании iptables
правила.

В пятницу, 13 марта 2015 г., в 13:16, Куинтон Хул [email protected]
написал:

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

  • где-то хранить желаемое состояние и периодически согласовывать желаемое и
    фактическое состояние (путем изменения фактического состояния). В этом случае, возможно, так просто:

while (true) {
actualState = iptablesSave ()
если фактическое состояние! = желаемое состояние {iptablesRestore (желаемое состояние))
sleep_a_ while ()
}

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79336296
.

Это более или менее то, что происходит сейчас, не так ли? Для каждого ожидаемого правила
проверьте, существует ли он, а если нет, сделайте это.

Пт, 13 марта 2015 г., 14:02, Брендан Бернс [email protected]
написал:

Согласитесь на 100%, это правильный способ справиться с ошибкой при написании iptables
правила.

В пятницу, 13 марта 2015 г., в 13:16, Куинтон Хул [email protected]
написал:

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

  • где-то хранить желаемое состояние и периодически согласовывать желаемое и
    фактическое состояние (путем изменения фактического состояния). В этом случае, возможно, так же просто
    в качестве:

while (true) {
actualState = iptablesSave ()
если фактическое состояние! = желаемое состояние {iptablesRestore (желаемое состояние))
sleep_a_ while ()
}

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
<
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79336296

.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79392626
.

Я согласен, что утилита есть в отдельном двоичном файле, но, возможно, мы свяжем ее с
kubelet (как и cAdvisor) и сделать его автономным на
в то же время.

Пт, 13 марта 2015 г., 12:03, Брендан Бернс [email protected]
написал:

Я хотел бы сохранить его как отдельный двоичный файл. Есть причины, по которым ты
может захотеть запустить это на других машинах (например, домашних виртуальных машинах) за пределами k8s
кластер, чтобы получить доступ к сервисам k8s.

--brendan

Пт, 13 марта 2015 г., в 11:37, Брайан Грант [email protected]
написал:

Будем ли мы интегрировать это в kubelet или хранить в отдельном демоне?
Kubelet уже наблюдает за сервисами, чтобы заполнить env vars.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
<
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79230747

.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79257059
.

Мне было бы любопытно услышать, что говорят ребята из Kubernetes-Mesos о том, должны ли компоненты узла быть более интегрированными или модульными. @jdef?

[[EDITED]] Мне очень нравится модульность компонентов k8s, например, запуск прокси-процесса отдельно от процесса kubelet. Если прокси выходит из строя по какой-либо причине, он не прекращает работу kubelet. Это довольно здорово, поскольку у исполнителей Mesos сейчас нет очень изящной модели аварийного переключения, а исполнитель фреймворка kubernetes-mesos представляет собой гибрид кублета / исполнителя. Эта модель также позволяет мне запускать прокси-сервис на мезо-мастере и использовать его в качестве балансировщика циклического перебора для внешних клиентов (как в руководстве по началу работы, которое мы отправили).

Что касается упаковки / доставки двоичных файлов, я думаю, что было бы очень полезно объединить функциональность, как в Hyperkube. Я также подумал о том, как упаковать компоненты фреймворка kubernetes-mesos в минимальные контейнеры Docker. Iptables имеет зависимости от внешних библиотек, что усложняет ситуацию. Таким образом, хорошим компромиссом может быть доставка фреймворка k8sm как Docker, содержащего единственный образ гиперкуба, но когда эта структура запускается и начинает распределять исполнители кубелета по кластеру, он в основном отправляет образ гиперкуба, который может трансформироваться либо в кубелет. исполнитель или прокси - и каждый процесс может запускаться непосредственно на хосте. По сути, это решает проблему зависимости iptables- {двоичные файлы, библиотеки} -in-Docker.

+1 для модульной функциональности, +1 для одиночного двоичного изображения

@thockin re: @ bgrant0607 от 26 февраля о том, что ошибки можно игнорировать и они будут исправлены на следующей итерации SyncLoop () (в настоящее время 1 минута)? Или, может быть, я что-то упускаю?

@thockin

  1. Беспокоит ли нас сетевой трафик, создающий черную дыру, или это то, о чем нужно позаботиться автору службы / модуля?

С прокси-сервером пользовательского пространства
Предположим, что виртуальный IP-адрес 10.0.0.11 имеет 3 конечные точки, скажем, 10.240.1.1, 10.240.1.2, 10.240.1.3.
С прокси-сервером пользовательского пространства, если одна конечная точка, скажем, 10.240.1.1, не работает, прокси-сервер поймет, что TCP-соединение не было установлено с 10.240.1.1, и может вернуться к одной из двух других конечных точек.

С iptables
Когда мы используем iptables, нет никакого запасного механизма, поскольку kubernetes не понимает, работает конечная точка или нет.
Мы могли бы смягчить это, если бы у нас была какая-то проверка работоспособности конечных точек, которая удаляла бы неотзывчивые конечные точки.

Или, может быть, забота о невосприимчивых конечных точках - это не ответственность системы Kubernetes, а ответственность автора пода?

Пользователь может настроить проверки готовности, которые выполняет Kubelet. Сбой зонда приведет к удалению конечной точки из списка конечных точек контроллером конечных точек. Затем прокси-сервер службы должен удалить конечную точку из целевого набора.

Я искал это для GSoC, и мне интересно:

Итак, в идеале мы бы обнаружили, достаточно ли новый iptables, чтобы его можно было использовать, и в противном случае продолжили бы использовать kube-proxy?

Из https://github.com/GoogleCloudPlatform/kubernetes/issues/5419 похоже, что это был бы идеальный подход; где kubelet определяет, следует ли использовать ip-таблицы или запустить kube-proxy.

Я также немного опоздал на GSoC (был на весенних каникулах ....), поэтому мне также интересно, могу ли я подать предложение GSoC для этого завтра / позже сегодня (кроме, конечно, 27-го крайнего срока, это все еще открыто)?

@BenTheElder Да, у вас есть до пятницы, чтобы подать предложение. Есть еще один человек, который потенциально может заинтересоваться этой темой, но пока нет конкретного предложения по ней.

Я не беспокоюсь о ядрах старше 2012 года так сильно, как об ОС без iptables, хотя они в какой-то степени уже сломаны.

@ bgrant0607 спасибо!
Думаю, тогда я могу выбрать этот выпуск. Смотрится интересно.

Проверка готовности будет хорошо работать для запуска приложения, но я не уверен, что готовность подходит для смягчения последствий сбоя приложения. При сбое модуля сигнал должен пройти из приложения -> kubelet -> apiserver -> endpoints_controller -> apiserver -> kube-proxy. Мне было бы интересно понять задержку между отказом приложения и удалением конечной точки из ротации kube-proxy. В течение этого периода запросы будут передаваться на неотвечающую конечную точку.

Повторная попытка при сбое подключения - распространенная стратегия и достаточно полезная функция многих популярных балансировщиков нагрузки (например, haproxy, AWS ELB) и обрабатывается текущей реализацией kube-proxy. Следует ли перенести эту ответственность на внешний LB? А как насчет внутрикластерного трафика?

Еще одна мысль: с iptables мы, вероятно, столкнемся с проблемами изящного истощения соединения при реконфигурации по сравнению с фактическим LB.

Майк поднимает хорошие вопросы.

В понедельник, 23 марта 2015 г., в 23:00, Майк Данезе [email protected]
написал:

Еще одна мысль, мы, скорее всего, столкнемся с проблемами изящного подключения
истощение при реконфигурации по сравнению с фактическим LB.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -85354865
.

Я читал исходники для kube-proxy и proxy pkg; iptables еще не используется в текущей версии?

Что именно нужно с этим делать? Исходя из текущего основного источника, похоже, что iptables уже довольно широко используется в прокси.

@mikedanese @thockin Готовность наиболее полезна при плановых отключениях. Незапланированные отключения всегда вызывают некоторые наблюдаемые ошибки. Интервал опроса, как правило, должен быть большим по сравнению с задержкой обновления, но мы также могли бы ввести правила повторной переадресации на узле назначения через прямую связь между Kubelet и kube-proxy, если задержка через apiserver и etcd слишком велика и / или что путь недостаточно надежен.

@BenTheElder Существующие правила направляют трафик через прокси. Идея здесь в том, чтобы использовать правила для обхода прокси.

@ bgrant0607 Спасибо, теперь это имеет смысл. Еще раз прочитал исходный код и документацию по дизайну, и я почти закончил писать черновик предложения.

Проект предложения GSoC: https://gist.github.com/BenTheElder/ac61900595a7ea9ea9b5

Я особенно признателен за отзывы о разделе расписания. Я не совсем уверен в этом.
Должен ли я закончить раньше, я бы хотел поработать над некоторыми другими (меньшими?) Невыполненными проблемами GSoC, такими как:
https://github.com/GoogleCloudPlatform/kubernetes/issues/1651.

Еще раз спасибо, Kubernetes берет торт за самую дружелюбную группу.

Я просто хочу сказать, что я очень рад сообщить, что мое предложение было принято, и что я буду работать над этим летом. : смайлик:

Я очень рад. К сожалению, сейчас я нахожусь в середине финала, но, начиная где-то в эти выходные, мне нужно намного больше и работать над этим, скорее всего, начиная с получения https://github.com/GoogleCloudPlatform/kubernetes/pull/7032 законченный.

@thockin @brendanburns Может ли кто-нибудь взвесить, хотим ли мы делать это параллельно с прокси-сервером пользовательского пространства или как будет работать переход на повторную реализацию?

Похоже, мы уже предпочитаем iptables> = 1.4.11 (выпущен 26 мая 2011 г.).

// Executes the rule check without using the "-C" flag, instead parsing iptables-save.
// Present for compatibility with <1.4.11 versions of iptables.  This is full
// of hack and half-measures.  We should nix this ASAP.
func (runner *runner) checkRuleWithoutCheck(table Table, chain Chain, args ...string) (bool, error) {

Источник: https://github.com/GoogleCloudPlatform/kubernetes/blob/aec41967416cf3463b188d72c97e71465e00719d/pkg/util/iptables/iptables.go#L206

Действительно ли мы видим хостов старше этого?

Один из подходов, очевидно, заключался бы в том, чтобы определить во время выполнения, какую версию iptables мы запускаем, и сделать «лучшее», что мы можем дать этой версии, например, что-то вроде:

if (oldversion) {
загрузить модуль проксирования пользовательского пространства
}
еще {
загрузить модуль прокси iptables
}

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

Я не просматривал код подробно, чтобы понять, насколько осуществим вышеупомянутый подход.

Кроме того, все ли узлы должны реализовывать одну и ту же стратегию (пространство пользователя или проксирование iptables), или каждый может принимать решение независимо?

Если каждый узел принимает независимое решение, мы потенциально увеличиваем площадь тестовой поверхности пропорционально квадрату количества ветвей в приведенном выше выражении if (т.е. source_mode x dest_mode), но если мы можем сохранить количество режимов равным 2, я думаю, что это нормально. .

Q

Да, и ответ на ваш вопрос о том, видим ли мы старые узлы, к сожалению, положительный.

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

@ quinton-hoole Спасибо!

Также я почти уверен, что мы можем запустить пользовательское пространство на одном узле, а iptables - на другом.

Количество режимов должно быть просто 2, за исключением того взлома, когда у нас нет -C, но узлы с -C должны иметь возможность запускать чистую версию iptables (я думаю).

Ах да, в # 7528 обсуждаются версии ядра и тому подобное.

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

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

Я начал взламывать это здесь: https://github.com/BenTheElder/kubernetes/tree/iptables_proxy

В частности, я переместил реализацию пользовательского пространства за интерфейс сюда:
https://github.com/BenTheElder/kubernetes/commit/4e5d24bb74aca43b0dd37cf5cfee8a34f8eff2bf

Сейчас я не уверен, должна ли реализация быть выбрана в cmd / kube-proxy или в pkg / proxy, поэтому я могу удалить это и вместо этого выбрать реализацию с помощью kube-proxy.

Изменить: оглядываясь назад, я думаю, что, вероятно, имеет смысл выбрать реализацию из kube-proxy.

@BenTheElder Я проверил правила Тима с Calico, и они работают нормально. Мы выполняем всю нашу работу в таблице фильтров, поэтому правила DNAT к этому моменту установили соответствующий IP-адрес src.

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

@ Симметричный Да. Я еще не уверен насчет плагинов, но это кажется очень важным.

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

Вы хоть представляете, как бы вы хотели, чтобы это выглядело / как это должно работать?

FWIW, я сделал кое-что, что сработало для нас, потому что kube-proxy почти не отвечал. Это здесь: https://github.com/MikaelCluseau/kubernetes-iptables-proxy/blob/master/iptables-routing.rb.

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

Я также хотел бы поделиться тем, что мы быстро достигли nf_conntrack_max. Вероятно, его следует увеличить.

# cat /etc/sysctl.d/nf_conntrack.conf 
net.netfilter.nf_conntrack_max = 1000000
net.nf_conntrack_max           = 1000000

Возможно, я не понимал всей необходимости iptables , но почему бы не использовать вместо этого IPVS ?
Вроде для проксирования актуальнее, чем iptables ...
Вот простая реализация: https://github.com/noxiouz/go-ipvs
И просто для завершения # 561 есть еще проект ktcpvs .

IPVS, похоже, также является абстракцией от netfilter (например, iptables). Мы можем поделиться некоторыми функциями с существующим кодом с помощью iptables; и iptables кажется более гибким / общим решением для управления netfilter.

Что касается # 561 и ktcpvs: похоже, что ktcpvs не разрабатывалась с 2004 года и, похоже, не имеет функций, которые пользователи хотели бы, например, перезаписи URL-адресов. Независимо от того, # 561 ищет универсальное решение, которое можно было бы использовать с подключаемыми балансирами.

Боковое примечание: похоже, что у этого проекта go нет лицензии.

iptables не рекомендуется "на один день" в пользу nftables ( nft cli).
Кроме того, использование интерфейса командной строки iptables для создания правил не кажется достаточно надежным ...

Быстрый поиск, найдите мне этот другой проект MIT: https://github.com/vieux/go-libipvs
Но, похоже, действительно довольно легко создать простой рабочий, поскольку вся сложность уже защищена от пули внутри кода ядра.

Я сомневаюсь, что iptables будет удален из любого из основных дистрибутивов в ближайшее время, а интерфейс командной строки iptables предназначен специально для создания и управления правилами для netfilter ...?

Неполная оболочка cgo, такая как связанная, кажется намного менее безопасной, чем обработка iptables и iptables-restore и нам уже нужны iptables для других правил (например, nodeports) и с iptables-restore мы можем делать массовые обновления с некоторой атомарностью.

Кроме того, кажется, что IPVS предназначен для использования на хост-машине с балансировкой нагрузки отдельно от «реальных» серверов.
Это говорит о том, что это единственное поддерживаемое использование:

2.2. Подсказки: вам нужен внешний клиент (директор и реальные серверы не могут получить доступ к виртуальному сервису)

Для настройки и тестирования / запуска LVS вам потребуется как минимум 3 машины: клиент, директор, реальный сервер (ы).

Снаружи LVS работает как одна машина. Клиент не может быть одной из машин в LVS (директором или реальным сервером). Вам нужен сторонний клиент. Если вы попытаетесь получить доступ к службе, управляемой LVS (например, http, smtp, telnet) с любой из машин в LVS; доступ от директора зависнет, доступ с реального сервера будет подключаться к сервису локально, минуя LVS.

Также похоже, что IPVS / LVS добавляет некоторые дополнительные требования, такие как демон пульса и дополнительные процессы мониторинга. Мы уже обрабатываем информацию о конечных точках, мониторинг работоспособности подов и т. Д. Из Kubernetes.

+1 за подход iptables. Мы широко используем iptables в Calico, и они доказали свою надежность, работают и хорошо масштабируются (при условии, что вы хорошо разрабатываете свои правила). @BenTheElder , если вам понадобится помощь в работе с iptables, дайте нам знать, потому что мы будем рады помочь.

+1 для iptables и iptables-restore, это гораздо менее деспотичный подход
чем IPVS / LVS, и требует меньше системных требований (демон пульса,
так далее.)

В сб, 13 июня 2015 г., в 11:27, Alex Pollitt [email protected]
написал:

+1 за подход iptables. Мы широко используем iptables в Calico и
они доказали свою надежность, работают и хорошо масштабируются (при условии, что вы
хорошо разработайте свои правила). @BenTheElder https://github.com/BenTheElder ,
если вам понадобится помощь с работой iptables, пожалуйста, позвольте
мы знаем, потому что мы были бы счастливы внести свой вклад.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -111719474
.

Спасибо, Алекс, я дам тебе знать, если узнаю.

Я мог бы использовать отзывы / комментарии по текущей реализации (https://github.com/GoogleCloudPlatform/kubernetes/pull/9210), если у кого-то есть время.

Он в основном завершен и в настоящее время полностью обновлен с помощью восходящего мастера, мне нужно закончить писать код, который сравнивает сгенерированные правила с iptables-save и восстанавливает счетчики и т. Д., Но правила сгенерированы и (в основном) работают, в значительной степени следуя правилам, изложенным в OP здесь, с самым большим изменением только в именах цепочек, которые были необходимы для автоматической генерации имен, которые будут принимать iptables.

Здесь сообщается о крайнем случае: https://github.com/BenTheElder/kubernetes/issues/3, который может потребовать изменения для обработки подключаемых к себе модулей.

У меня были отличные отзывы и обсуждения с @MikaelCluseau и @Symmetric, в частности, о

PR сам по себе довольно большой, но соответствующая генерация правил находится в pkg/proxy/proxieriptables.go syncProxyRules() адресу: https://github.com/BenTheElder/kubernetes/blob/iptables_proxy/pkg/proxy/proxieriptables. go # L286

Существующее обсуждение можно увидеть (здесь, конечно), а также в комментариях по связям с общественностью и на https://github.com/BenTheElder/kubernetes/issues/3, а также немного больше на https://github.com/ BenTheElder / kubernetes / issues / 4.

Еще одна проблема, требующая ввода:

В текущий код по-прежнему включен kube-proxy, чтобы обрабатывать ТОЛЬКО случай nodePort. Я думаю, что мы можем отказаться от kube-proxy и в этом случае, и для PR Бена предложили несколько простых правил iptables.

Но эти правила по-прежнему скрывают исходный IP-адрес любого внешнего LB, поэтому они не идеальны. Проблема в том, что если мы просто трафик DNAT от LB, когда он попадает в узел, то ответный пакет может поступать от другого узла, и поэтому я не думаю, что LB сможет соотнести ответ с исходным сеансом TCP. . Это опасение справедливо? Реализация была бы проще, если бы нам не приходилось об этом беспокоиться.

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

Я пробую черную магию из вашего PR, но для меня это ничего не генерирует, похоже, правила начали генерироваться с обращениями к iptables, после чего создается файл iptables-restore.

В созданном файле отсутствует часть заголовка, как правило, те, которые были заполнены с помощью вызова iptables. Соответствующая часть журнала:

I0807 11: 41: 24.560063 8369 iptables.go: 327] выполнение iptables -N [KUBE-PORTALS-CONTAINER -t nat]
I0807 11: 41: 24.562361 8369 iptables.go: 327] выполнение iptables -C [PREROUTING -t nat -m comment --comment handle ClusterIPs; ПРИМЕЧАНИЕ: это должно быть перед правилами NodePort -j KUBE-PORTALS-CONTAINER]
I0807 11: 41: 24.563469 8369 iptables.go: 327] запуск iptables -N [KUBE-PORTALS-HOST -t nat]
I0807 11: 41: 24.565452 8369 iptables.go: 327] выполнение iptables -C [OUTPUT -t nat -m comment --comment handle ClusterIPs; ПРИМЕЧАНИЕ: это должно быть перед правилами NodePort -j KUBE-PORTALS-HOST]
I0807 11: 41: 24.566552 8369 iptables.go: 327] выполнение iptables -N [KUBE-NODEPORT-CONTAINER -t nat]
I0807 11: 41: 24.568363 8369 iptables.go: 327] выполнение iptables -C [PREROUTING -t nat -m addrtype --dst-type LOCAL -m comment --comment handle service NodePorts; ПРИМЕЧАНИЕ: это должно быть последнее правило в цепочке -j KUBE-NODEPORT-CONTAINER]
I0807 11: 41: 24.569564 8369 iptables.go: 327] запуск iptables -N [KUBE-NODEPORT-HOST -t nat]
I0807 11: 41: 24.571458 8369 iptables.go: 327] выполнение iptables -C [OUTPUT -t nat -m addrtype --dst-type LOCAL -m comment --comment handle service NodePorts; ПРИМЕЧАНИЕ: это должно быть последнее правило в цепочке -j KUBE-NODEPORT-HOST]
I0807 11: 41: 24.573392 8369 iptables.go: 327] запуск iptables -C [POSTROUTING -t nat -m comment --comment handle pod подключение к self -s 10.240.240.78/32 -d 10.240.240.78/32 -j MASQUERADE ]
I0807 11: 41: 24.574447 8369 proxier.go: 349] Синхронизация правил iptables.
I0807 11: 41: 24.575592 8369 proxier.go: 399] Цепочка: PREROUTING, правило:: PREROUTING ACCEPT [0: 0]
I0807 11: 41: 24.575615 8369 proxier.go: 401] Правило: -A PREROUTING -m comment --comment "обрабатывать IP-адреса кластера; ПРИМЕЧАНИЕ: это должно быть перед правилами NodePort" -j KUBE-PORTALS-CONTAINER
I0807 11: 41: 24.575625 8369 proxier.go: 401] Правило: -A PREROUTING -m addrtype --dst-type LOCAL -m comment --comment «обрабатывать сервисные NodePorts; ПРИМЕЧАНИЕ: это должно быть последнее правило в цепочке» -j КУБЕ-НОДЕПОРТ-КОНТЕЙНЕР
I0807 11: 41: 24.575633 8369 proxier.go: 399] Цепочка: INPUT, правило:: INPUT ACCEPT [0: 0]
I0807 11: 41: 24.575646 8369 proxier.go: 399] Цепочка: OUTPUT, правило:: OUTPUT ACCEPT [0: 0]
I0807 11: 41: 24.575658 8369 proxier.go: 401] Правило: -A ВЫХОД -m комментарий --comment "обрабатывать IP-адреса кластера; ПРИМЕЧАНИЕ: это должно быть перед правилами NodePort" -j KUBE-PORTALS-HOST
I0807 11: 41: 24.575670 8369 proxier.go: 401] Правило: -A ВЫХОД -m addrtype --dst-type LOCAL -m comment --comment "обрабатывать сервисные NodePorts; ПРИМЕЧАНИЕ: это должно быть последнее правило в цепочке" -j КУБЕ-НОДЕПОРТ-ХОЗЯИН
I0807 11: 41: 24.575683 8369 proxier.go: 399] Цепочка: POSTROUTING, правило:: POSTROUTING ACCEPT [0: 0]
I0807 11: 41: 24.575691 8369 proxier.go: 401] Правило: - РАЗВЕДЕНИЕ! -d 10.0.0.0/8 -o eth0 -j МАСКАРАД
I0807 11: 41: 24.575699 8369 proxier.go: 401] Правило: -A POSTROUTING -s 10.240.240.78/32 -d 10.240.240.78/32 -m comment --comment "ручка управления подключением к себе" -j MASQUERADE
I0807 11: 41: 24.575709 8369 proxier.go: 399] Цепочка: KUBE-NODEPORT-CONTAINER, правило:: KUBE-NODEPORT-CONTAINER - [0: 0]
I0807 11: 41: 24.575720 8369 proxier.go: 399] Цепочка: KUBE-NODEPORT-HOST, правило:: KUBE-NODEPORT-HOST - [0: 0]
I0807 11: 41: 24.575729 8369 proxier.go: 399] Цепочка: KUBE-PORTALS-CONTAINER, правило:: KUBE-PORTALS-CONTAINER - [0: 0]
I0807 11: 41: 24.575740 8369 proxier.go: 399] Цепочка: KUBE-PORTALS-HOST, правило:: KUBE-PORTALS-HOST - [0: 0]
I0807 11: 41: 24.581897 8369 proxier.go: 603] Правило синхронизации:: KUBE-PORTALS-HOST - [0: 0]
: КУБЕ-ПОРТАЛЫ-КОНТЕЙНЕР - [0: 0]
: KUBE-NODEPORT-HOST - [0: 0]
: КУБЕ-НОДЕПОРТ-КОНТЕЙНЕР - [0: 0]
: KUBE-SVC-VO8JL93ZeRSf8cnsLpl - [0: 0]
: KUBE-SVC-L26cB3JYuxdW5TF84ct - [0: 0]
: KUBE-SVC-j2SF8q3nUajS8vOx2qL - [0: 0]
: KUBE-SVC-shln2urO8W1aBiB2bWJ - [0: 0]
: KUBE-SVC-8jQ3IvijvhJ4ppFj3Ui - [0: 0]
[... СНиП ...]

Слияние iptable-save с результатом, полученным в подробном режиме, может быть импортировано и делать хорошие вещи.

@bnprss, спасибо за отчет, недавно был iptables-restore во время некоторых переделок для процесса проверки. Я внесу исправление, как только узнаю, что вызвало регресс.

@bnprss Как вы сказали, заголовок таблицы отсутствует («* nat» должен быть первой строкой), он был ошибочно удален, и после того, как он был возвращен, все, похоже, снова работает нормально, по-видимому, без других ошибок (за исключением: https: / /github.com/BenTheElder/kubernetes/issues/3). Еще раз спасибо, извиняюсь за это. Я настоял на исправлении.

Хорошая работа, правила загружаются и, кажется, работают изнутри, но не повезло с externalloadbalancer, никакая связь извне не дает ответа.

Хм. Не могли бы вы перейти к PR и подробнее рассказать? Так далеко
он работает хорошо, но я не планирую выходить за рамки локального тестирования, и я
не думаю, что кто-то из других тестировщиков использовал внешний балансировщик нагрузки.
7 августа 2015 г. в 13:29 "bnprss" [email protected] написал:

Хорошая работа, правила загружаются и вроде работает изнутри, но не повезло
с externalloadbalancer никакая связь извне не дает ответа.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -128772763
.

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

Можете ли вы вычислить токен правил без разделителей "-_"?

@bnprss , отлично.
Сгенерированные цепочки правил для служб представляют собой хэш порта / конечной точки службы, а затем закодированный и усеченный URL-адрес base64. KUBE-SVC-. Код находится здесь: https://github.com/GoogleCloudPlatform/kubernetes/pull/9210/files#diff -d51765b83fe795b469e8a86276b12dc9R321
Мы выбрали это как способ генерации допустимых имен цепочек, которые будут соответствовать лимиту символов в iptables, но при этом будут детерминированными.
Так что должна быть возможность репликации извне.
Если вы имеете в виду, можем ли мы прекратить использование разделителей, мы, вероятно, могли бы, но "_" происходит от некоторого закодированного хэша, а "-" все просто следуют шаблонам в именах правил из существующего прокси-сервера пользовательского пространства.
Возможно, мы могли бы без особых проблем использовать что-нибудь еще, если бы это было необходимо.

Я согласен с этим, и это действительно косметическое средство! :)
Но это отличается от того, что я видел раньше:
Правила gce lb: a07f76b3b2ec311e59e2642010af0479
Правила gce fw: k8s-fw-a7ecad94f3ba511e59e2642010af0479
правила маршрутизации gce: default-route-6973e029b504a0e8
Маршрутизация gce к узлу: obfuscated_cluster_node-43506797-2eb2-11e5-9e26-42010af04793

это хорошо:
Кубе-SVC-6ADi2TVfn7mFPvBjC56
эти смешные:
KUBE-SVC-zU6ParcQ-UfW_LdRDUc
KUBE-SVC-y - z1xTUpHPT6sgAUCC

Да, я тоже не совсем их фанат, возможно, мы могли бы изменить хеш
кодирование.

В пятницу, 7 августа 2015 г., в 14:16 bnprss [email protected] написал:

Я согласен с этим, и это действительно косметическое средство! :)
Но это отличается от того, что я видел раньше:
Правила gce lb: a07f76b3b2ec311e59e2642010af0479
Правила gce fw: k8s-fw-a7ecad94f3ba511e59e2642010af0479
правила маршрутизации gce: default-route-6973e029b504a0e8
Маршрутизация gce к узлу:
obfuscated_cluster_node-43506797-2eb2-11e5-9e26-42010af04793

это хорошо:
Кубе-SVC-6ADi2TVfn7mFPvBjC56
эти смешные:
KUBE-SVC-zU6ParcQ-UfW_LdRDUc
KUBE-SVC-y - z1xTUpHPT6sgAUCC

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -128785914
.

Да, можно использовать только усеченную часть SHA, git с этим согласен, docker тоже, и, похоже, это способ другой ссылки на сущности kube. В случае коллизии в сгенерированном хэше base64 не поможет. ;)
Думаю, @thockin мог бы посоветовать по этому поводу.

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

Пт, 7 августа 2015 г., в 14:29, bnprss [email protected] написал:

Да, возможно использовать только усеченную часть SHA, git в порядке с
это тоже докер, и, похоже, это другая ссылка на kube
сущности сделаны. В случае коллизии в сгенерированном хэше base64 не будет
помощь. ;)
Думаю, @thockin https://github.com/thockin мог бы посоветовать по этому поводу.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -128788454
.

@bnprss fyi PR довольно нестабилен, и его переделывают, за thockin, на данный момент мы сокращаем NodePort и т. д. и сосредотачиваемся на получении более простой и чистой версии с поддержкой порталов, а затем возвращаемся к полной паритетности.

Я бы _не_ не пытался запустить это прямо сейчас, но, надеюсь, он скоро вернется. Разбить PR на несколько более мелких связанных, а затем прямо сейчас продвинуть чистый с помощью iptables-proxy.

Для тех из вас, кто играет дома, я уверен, что мы сможем довести его до полной
четность, но поэтапно будет намного проще :)

В пятницу, 7 августа 2015 г., в 21:35, Бенджамин Элдер [email protected]
написал:

Мой ответ на вышеупомянутый комментарий, который также скоро будет уничтожен:

Обсуждается в IRC:

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

В противном случае кажется очень чистым упрощением, будет реализовано после
еще какое-то обсуждение.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -128912169
.

Статус: «основная» логика проверена и заблокирована.

Сейчас я работаю над портами узлов. Есть много странных случаев, требующих особого внимания. Мои заметки на данный момент:

# Basic node ports:
iptables -t nat -N KUBE-NODEPORTS
iptables -t nat -A PREROUTING -j KUBE-NODEPORTS
iptables -t nat -A OUTPUT -j KUBE-NODEPORTS
iptables -t nat -A KUBE-NODEPORTS -p tcp -m comment --comment "TEST: default/nodeport:p" -m tcp --dport 30241 -j KUBE-SVC-EQKU6GMUKRXBR6NWW53

# To get traffic from node to localhost:nodeport to the service:
echo 1 > /proc/sys/net/ipv4/conf/all/route_localnet
# Mark packets that are destined for services from localhost, then masquerade those
iptables -t nat -I KUBE-SVC-EQKU6GMUKRXBR6NWW53 -s 127.0.0.0/16 -j MARK --set-mark 0x4b000001;
iptables -t nat -A POSTROUTING -m mark --mark 0x4b000001 -j MASQUERADE

# To get traffic from a pod to itself via a service:
for intf in $(ip link list | grep veth | cut -f2 -d:); do brctl hairpin cbr0 $intf on; done
# Mark packets that are destined for each endpoint from the same endpoint, then masquerade those.
# This is hacky, but I don't really know which pods are "local" and I don't really want to right now. (but I will eventually)
iptables -t nat -I KUBE-SEP-HHNEQBOLY57T5MQCFIY -s 10.244.1.6 -j MARK --set-mark 0x4b000001

Работал над инструментом contrib для тестирования.
Пока что я подумываю запустить сервер на узле, задержка по времени
запросы к нему, посмотрите, как получить загрузку ресурса kube-proxy и сбросить
данные в CSV для построения графиков и т. д.
Надеюсь, сделано до пятницы, познакомимся с kubectl прямо сейчас.

В среду, 12 августа 2015 г., в 20:48, Тим Хокин [email protected]
написал:

Статус: «основная» логика проверена и заблокирована.

Сейчас я работаю над портами узлов. Есть много странных случаев, требующих
особое обращение. Мои заметки на данный момент:

Порты базового узла:

iptables -t нат -N КУБЕ-НОДЕПОРТЫ
iptables -t nat -A PREROUTING -j KUBE-NODEPORTS
iptables -t nat -A ВЫХОД -j KUBE-NODEPORTS
iptables -t nat -A KUBE-NODEPORTS -p tcp -m comment --comment «ТЕСТ: по умолчанию / nodeport: p » -m tcp --dport 30241 -j KUBE-SVC-EQKU6GMUKRXBR6NWW53

Чтобы получить трафик с узла на localhost: nodeport на службу:

эхо 1> / proc / sys / net / ipv4 / conf / all / route_localnet

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

iptables -t nat -I KUBE-SVC-EQKU6GMUKRXBR6NWW53 -s 127.0.0.0/16 -j MARK --set-mark 0x4b000001;
iptables -t nat -A POSTROUTING -m mark --mark 0x4b000001 -j MASQUERADE

Чтобы получить трафик от модуля к самому себе через службу:

для intf в $ (список IP-ссылок | grep veth | cut -f2 -d :); сделать brctl hairpin cbr0 $ intf on; сделано

Отметьте пакеты, предназначенные для каждой конечной точки от одной конечной точки, а затем замаскируйте их.

Это хакерство, но я действительно не знаю, какие модули являются «местными», и не очень хочу прямо сейчас. (но в конце концов я сделаю это)

iptables -t nat -I KUBE-SEP-HHNEQBOLY57T5MQCFIY -s 10.244.1.6 -j MARK --set-mark 0x4b000001

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130492394
.

@BenTheElder Я только что провел достаточно подробные измерения производительности сети на GCE - рекомендую взглянуть на netperf (qperf также дает измерения задержки).

netperf - это клиент-серверный инструмент perf, я упаковал и клиент, и сервер в контейнер docker paultiplady / netserver: ubuntu.2. В netperf есть множество опций, но что-то вроде раскрутки двух модулей netserver и запуска

kubectl exec  -t $netserver-pod-1 -- netperf –l 30 -i 10 -I 99,1 -c -j -H $netserver-pod-2-ip -t OMNI --  -T tcp -D -O THROUGHPUT,THROUGHPUT_UNITS,MEAN_LATENCY,MIN_LATENCY,MAX_LATENCY,P50_LATENCY,P90_LATENCY,P99_LATENCY,STDDEV_LATENCY,LOCAL_CPU_UTIL

должен дать вам приличный разброс статистики, включая задержку и пропускную способность. Вы можете запустить контейнер netserver, используя docker run --net=host чтобы выполнить тесты node-> pod.

Dockerfile для этого контейнера довольно прост, я могу запустить его, если вы хотите расширить его до чего-то более компактного (например, контейнера на основе alpinelinux для более быстрого извлечения).

Спасибо, я займусь этим.

Из этого комментария я думаю, что мы хотим сделать некоторую задержку запроса службы. Прямо сейчас я пытаюсь использовать стандартный контейнер nginx в качестве узла X и работаю над тем, чтобы тестовый модуль периодически нажимал на него, чтобы мы могли построить график на узле Y.

Я посмотрю на netperf / qperf, и у нас всегда может быть несколько тестов.
Я хотел бы сначала создать этот график, хотя в предыдущем обсуждении с @thockin

13 августа 2015 г., в 00:02, Пол Типлади [email protected]
написал:

@BenTheElder https://github.com/BenTheElder Я просто сделал несколько разумных
подробные измерения производительности сети на GCE - рекомендую взглянуть на
netperf (qperf также дает измерения задержки).

netperf - это инструмент производительности клиент / сервер, я упаковал и клиент, и
сервер в контейнере докеров paultiplady / netserver: ubuntu.2. Там
есть много вариантов на netperf, но что-то вроде раскрутки двух
стручки netserver и запуск

kubectl exec -t $ netserver-pod-1 - netperf –l 30 -i 10 -I 99,1 -c -j -H $ netserver-pod-2-ip -t OMNI - -T tcp -D -O THROUGHPUT, THROUGHPUT_UNITS, MEAN_LATENCY, MIN_LATENCY, MAX_LATENCY, P50_LATENCY, P90_LATENCY, P99_LATENCY, STDDEV_LATENCY, LOCAL_CPU_UTIL

должен дать вам приличный разброс статистики, включая задержку и пропускную способность.
Вы можете запустить контейнер netserver, используя docker run --net = host to do
node-> pod tests тоже.

Dockerfile для этого контейнера довольно прост, я могу запустить его, если
вы хотите расширить его до чего-то более компактного (например, на основе alpinelinux
контейнер для более быстрого извлечения).

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130524576
.

относительно портов узла: В # 9210 @Symmetric привел такой случай:

Если движение идет:
LB -> node1:nodePort
И сервисный модуль находится на node2, тогда полный поток будет:
LB -> node1:nodePort -> node2 -> pod:svcPort
SrcIP по-прежнему будет LB, поэтому ответ будет
pod -> node2 -> LB
Поскольку node2 может маршрутизировать напрямую к LB.

Теперь мы теряем возможность un-DNAT для восстановления правильного IP-адреса источника для возвращаемого пакета (это может произойти только на node1).

Я воспроизвел проблему. Подтвердите, что это реальная проблема. tcpdump показывает пакеты, которые DNAT отправляются на порт IP: pod (за пределами машины), с неповрежденным src, но tcpdump на конечном компьютере ничего не показывает. Я не уверен, чего я ожидал, даже если бы пакеты все-таки попали туда.

Думаю, единственное решение - SNAT. Наименее эффективным решением было бы _только_ пакеты SNAT от LB, которые предназначены вне узла, но а) у меня нет этой информации в kube-proxy (можно получить ее ценой кода) и б) поскольку любой Политика в любом случае должна будет учитывать случай SNAT, я могу упростить, всегда используя SNAT для внешних LB-пакетов. Насколько это плохо для механизмов политики?

В конечном итоге LB станут достаточно умными, чтобы нацеливаться только на хосты с модулями, и трафик останется локальным, и тогда это будет спорным.

Однако все становится сложнее. У нас есть поле deprecatedPublicIPs, от которого мы, вероятно, откажемся, внося некоторые изменения в его поведение. Думаю, нам нужно сделать то же самое с ними. Но это становится еще более сложным - я фактически не ЗНАЮ все общедоступные IP-адреса (например, виртуальная машина имеет внешний IP-адрес NAT 1: 1). Простой ответ - всегда пакеты SNAT узел-порт. Что думаете?

Завтра еще попробую.

@BenTheElder Вы можете сделать модуль netserver сервисом, чтобы трафик от perf <->
сервер идет через сервис VIP. Таким образом, вам не нужно делать
Самостоятельные расчеты выборки / задержки ...

В среду, 12 августа 2015 г., в 21:20, Бенджамин Элдер [email protected]
написал:

Спасибо, я займусь этим.

Из этого комментария
хотя я думаю, что мы хотим сделать некоторую задержку запроса на обслуживание. Верно
теперь я пытаюсь использовать стандартный контейнер nginx в качестве узла X и работаю над
иметь тестовый модуль, который время от времени ударяет по нему, чтобы мы могли построить график на
узел Y.

Я посмотрю на netperf / qperf, и у нас всегда может быть несколько тестов.
Я хотел бы сначала построить этот график, хотя в предыдущем обсуждении с
@thockin

13 августа 2015 г., в 00:02, Пол Типлади [email protected]
написал:

@BenTheElder https://github.com/BenTheElder Я просто сделал несколько разумных
подробные измерения производительности сети на GCE - рекомендую взглянуть на
netperf (qperf также дает измерения задержки).

netperf - это инструмент производительности клиент / сервер, я упаковал и клиент, и
сервер в контейнере докеров paultiplady / netserver: ubuntu.2. Там
есть много вариантов на netperf, но что-то вроде раскрутки двух
стручки netserver и запуск

kubectl exec -t $ netserver-pod-1 - netperf –l 30 -i 10 -I 99,1 -c -j -H
$ netserver-pod-2-ip -t OMNI - -T tcp -D -O
THROUGHPUT, THROUGHPUT_UNITS, MEAN_LATENCY, MIN_LATENCY, MAX_LATENCY, P50_LATENCY, P90_LATENCY, P99_LATENCY, STDDEV_LATENCY, LOCAL_CPU_UTIL

должен дать вам приличный разброс статистики, включая задержку и
пропускная способность.
Вы можете запустить контейнер netserver, используя docker run --net = host to do
node-> pod tests тоже.

Dockerfile для этого контейнера довольно прост, я могу запустить его, если
вы хотите расширить его до чего-то более компактного (например, на основе alpinelinux
контейнер для более быстрого извлечения).

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
<
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130524576

.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130527558
.

Правда. Я думаю, что @thockin в конечном итоге упомянул о желании провести тест задержки e2e как
хорошо. Если позволит время, будет несколько различных тестов, и мы
вероятно, придется учитывать gce vs AWS и т. д.
13 августа 2015 г. в 13:47 «Пол Типлади» [email protected] написал:

Вы можете сделать модуль netserver сервисом, чтобы трафик от perf <->
сервер идет через сервис VIP. Таким образом, вам не нужно делать
Самостоятельные расчеты выборки / задержки ...

В среду, 12 августа 2015 г., в 21:20, Бенджамин Элдер [email protected]
написал:

Спасибо, я займусь этим.

От [этот комментарий] (

https://github.com/kubernetes/kubernetes/pull/9210#issuecomment-130154261)
хотя я думаю, что мы хотим сделать некоторую задержку запроса на обслуживание. Верно
теперь я пытаюсь использовать стандартный контейнер nginx в качестве узла X и работаю
на
иметь тестовый модуль, который время от времени ударяет по нему, чтобы мы могли построить график на
узел Y.

Я посмотрю на netperf / qperf, и у нас всегда может быть несколько тестов.
Я хотел бы сначала построить этот график, хотя в предыдущем обсуждении с
@thockin

13 августа 2015 г., 12:02, Пол Типлади < [email protected]

написал:

@BenTheElder https://github.com/BenTheElder Я только что сделал несколько
разумно
подробные измерения производительности сети на GCE - рекомендую посмотреть
в
netperf (qperf также дает измерения задержки).

netperf - это инструмент для перфорации клиент / сервер, я упаковал клиентские
а также
сервер в контейнере докеров paultiplady / netserver: ubuntu.2.
Там
есть много вариантов на netperf, но что-то вроде раскрутки двух
стручки netserver и запуск

kubectl exec -t $ netserver-pod-1 - netperf –l 30 -i 10 -I 99,1 -c -j
-ЧАС
$ netserver-pod-2-ip -t OMNI - -T tcp -D -O

THROUGHPUT, THROUGHPUT_UNITS, MEAN_LATENCY, MIN_LATENCY, MAX_LATENCY, P50_LATENCY, P90_LATENCY, P99_LATENCY, STDDEV_LATENCY, LOCAL_CPU_UTIL

должен дать вам приличный разброс статистики, включая задержку и
пропускная способность.
Вы можете запустить контейнер netserver, используя docker run --net = host to do
node-> pod tests тоже.

Dockerfile для этого контейнера довольно прост, я могу запустить его поверх
если
вы хотите расширить его до чего-то более компактного (например, на основе alpinelinux
контейнер для более быстрого извлечения).

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
<

https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130524576

.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
<
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130527558

.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130776866
.

@Symmetric тесты netperf работают

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

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

13 августа 2015 г., в 14:32, Бенджамин Элдер [email protected]
написал:

@Symmetric https://github.com/Symmetric - тесты netperf работают
мило. Спасибо за предложение :-)

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

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130850398
.

@thockin Я думаю, что мы можем жить с SNAT для трафика LB. В настоящее время я считаю, что вам нужно указать одну из следующих политик доступа модуля:

  • по умолчанию - "разрешить из [мое пространство имен]", и в этом случае пакеты LB отбрасываются.
  • 'разрешить из [список пространств имен]' или 'разрешить из [всех пространств имен в кластере]', снова LB-пакеты всегда отбрасываются
  • 'разрешить от всех', и в этом случае нам все равно, из LB, другого узла или откуда-то еще.

Таким образом, потеря исходного IP-адреса только для LB на самом деле нам не дорого.

Если мы сможем гарантировать, что LB попадает в правильный узел для модуля службы, это было бы здорово - в этом случае нам не нужен SNAT, и мы можем работать более жестко, занося IP-адреса LB в белый список, когда они предоставляются на сервис, а в противном случае - сбросить трафик.

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

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

-------- Исходное сообщение --------
De: Пол Типлади [email protected]
Дата: 14.08.2015 12:50 (GMT + 11: 00)
А: kubernetes / kubernetes [email protected]
Копия: Mikaël Cluseau [email protected]
Objet: Re: [kubernetes] использовать iptables для проксирования вместо пользовательского пространства
(# 3760)

@thockin Я думаю, что мы можем жить с SNAT для трафика LB. В настоящее время я считаю, что вам нужно указать одну из следующих политик доступа модуля:

по умолчанию - "разрешить из [мое пространство имен]", и в этом случае пакеты LB отбрасываются.
'разрешить из [список пространств имен]' или 'разрешить из [всех пространств имен в кластере]', снова LB-пакеты всегда отбрасываются
'разрешить от всех', и в этом случае нам все равно, из LB, другого узла или откуда-то еще.

Таким образом, потеря исходного IP-адреса только для LB на самом деле нам не дорого.

Если мы сможем гарантировать, что LB попадает в правильный узел для модуля службы, это было бы здорово - в этом случае нам не нужен SNAT, и мы можем работать более жестко, занося IP-адреса LB в белый список, когда они предоставляются на сервис, а в противном случае - сбросить трафик.

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

-
Ответьте на это письмо напрямую или просмотрите его на GitHub.

@MikaelCluseau , это неплохая идея - не могли бы вы открыть новый выпуск специально по этому поводу, чтобы я не потерял его из виду?

Тем не менее TODO: исправить шпильку, e2e, включить по умолчанию

Привет, Тим, извини, что не вернулся к тебе, но мы тут кое-что уладили ... Думаю, в следующую субботу я исправлю шпильку.

Это было примечание для меня - вы планировали заняться чем-то из этого? :)

Да, конечно, как я уже сказал, когда мы говорили о тестировании e2e. Я собираюсь помочь, Kubernetes мне очень помогает, поэтому мне лучше освоить его как можно лучше, а что лучше, чем исправлять ошибки? :-) Не стесняйтесь предлагать что-нибудь более приоритетное, но я думаю, что шпилька для начала неплохая. Он должен находиться в кубеле и иметь флаг для включения (сначала отключен по умолчанию). Постараюсь работать от 0,5 до 1 дня в неделю.

AFAIK, единственная часть этого, что осталось сделать, - это сделать это по умолчанию, что может произойти (при условии отсутствия взрывов) через некоторое время после v1.1, и это имеет несколько миль.

Ого!

В четверг, 24 сентября 2015 г., в 11:21, Тим Хокин [email protected]
написал:

AFAIK, единственное, что осталось сделать, это сделать его значением по умолчанию, которое может
произойдет (при условии отсутствия взрыва) через некоторое время после версии 1.1, и это имеет несколько миль
в теме.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -142960614
.

через некоторое время после v1.1, и у этого есть несколько миль.

Ой. Мы действительно рассчитывали на него в 1.1 ....
https://github.com/kubernetes/kubernetes/blob/master/docs/roadmap.md

@bgrieder вы все равно можете включить его с помощью параметра.

Он ВХОДИТ, но не включен по умолчанию. Вы можете подписаться с одной аннотацией для каждого
узел (и перезапуск kube-proxy)

24 сентября 2015 г. в 8:27 Бруно Г. [email protected] написал:

через некоторое время после v1.1, и у этого есть несколько миль.

Ой. Мы действительно рассчитывали на него в 1.1 ....
https://github.com/kubernetes/kubernetes/blob/master/docs/roadmap.md

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -142962932
.

@thockin @bnprss хорошо, но мы ожидаем, что версия 1.1 будет работать на Google Container Engine после выпуска. Интересно, какая гибкость у нас будет, чтобы «подписаться с единственной аннотацией для каждого узла». Не могли бы вы дать нам некоторые подробности о том, каков будет процесс, или указать нам какую-либо документацию?

После обновления до 1.1:

$ for node in $(kubectl get nodes -o name); do kubectl annotate $node net.beta.kubernetes.io/proxy-mode=iptables; done

Затем подключитесь по SSH к каждому узлу и перезапустите kube-proxy (или перезагрузите каждый узел).

Если вы хотите быть более осторожным, сделайте один или два узла, а затем попробуйте :)

Я пометил эту проблему как «примечание к выпуску», чтобы мы не забыли включить этот волшебный цикл в нашу документацию по 1.1.

@RichieEscarez

(Просто хотел заглянуть и сказать, что мы уже неделю используем проксирование iptables, и, похоже, все в порядке!)

@thockin Следует закрыть это или убрать с этапа 1.1?

Я переведу его на 1.2 только для включения по умолчанию.

Приносим извинения за потенциально глупый вопрос, но относительно сохранения клиентских IP-адресов:

@thockin Я видел в другом выпуске 2 сентября, что «только внутрикластерный трафик сохраняет клиентский IP» - это все еще верно для версии 1.2 alpha?

Мы запустили новый кластер 1.2, применили аннотацию узла, перезапустили и по-прежнему видим 10.244.0.1 в качестве исходного адреса для всех запросов, сделанных к модулю, на котором запущен HAProxy.

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

По умолчанию по-прежнему используется режим пользовательского пространства. Вы должны установить аннотацию на
узел (net.beta.kubernetes. io / proxy-mode = iptables) и перезапустите
прокси. Но это не приведет к открытию внешних клиентских IP-адресов, только внутри кластера.
IP-адреса.
23 октября 2015 г. в 17:09 «Бен Хандли» [email protected] написал:

Извините за потенциально глупый вопрос, но по поводу сохранения
клиентских IP-адресов:

@thockin https://github.com/thockin Я видел в другом выпуске 2 сентября.
что "только внутрикластерный трафик сохраняет IP клиента" - это все еще
правда для 1.2 альфа?

Запустили свежий 1.2 кластер, применили аннотацию узла, перезапустили,
и по-прежнему рассматриваем 10.244.0.1 в качестве адреса источника для всех запросов к
pod под управлением HAProxy.

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

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150725513
.

Я могу сохранить IP-адрес внешнего клиента, используя DNAT для внешнего трафика + маршрутизации через kube-proxy. Например, если ваша служебная сеть - 10.42.0.0/16 и у вас есть высокодоступный kube-proxy на IP 10.10.1.1, у вас может быть следующее правило iptable:

-A PREROUTING -i public -p tcp -m tcp --dport 25 -j DNAT --to-destination 10.42.12.34

и следующий маршрут:

10.42.0.0/16 via 10.10.1.1 dev edge 

Затем модуль за ним видит реальный IP-адрес:

Oct 24 02:41:39 email-0yr7n mail.info postfix/smtpd[469]: connect from zed.yyy.ru.[94.102.51.96]

Конечно, у вас должен быть правильный путь возврата пакета.

Да, если этот DNAT направлен на серверную часть вне машины, вы формируете треугольник без
SNAT. Это основная проблема.

Пт, 23 октября 2015 г., в 20:12, Микаэль Клюзо [email protected]
написал:

Я могу сохранить IP-адрес внешнего клиента, используя DNAT для внешнего трафика +
маршрутизация через кубе-прокси. Например, если ваша сеть обслуживания
10.42.0.0/16 и у вас есть высокодоступный kube-proxy на IP
10.10.1.1, у вас может быть следующее правило iptable:

-A PREROUTING -i public -p tcp -m tcp --dport 25 -j DNAT --to-destination 10.42.12.34

и следующий маршрут:

10.42.0.0/16 через 10.10.1.1 край разработчика

Затем модуль за ним видит реальный IP-адрес:

24 октября 02:41:39 email-0yr7n mail.info postfix / smtpd [469]: подключение с zed.yyy.ru. [94.102.51.96]

Конечно, у вас должен быть правильный путь возврата пакета.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150747217
.

Звучит интересно, есть ссылка? :-) Я пытаюсь найти способ убедиться, что пакет будет проходить через правильное правило conntrack. Я думал о репликации состояния conntrack через кластер.

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

Предполагается, что текущий прокси iptables должен работать так, что пакет
приходит в узел, мы обнаруживаем, что он не генерируется локально, помечаем его для
SNAT, выберите серверную часть, перейдите к ней с помощью SNAT, серверная часть отвечает
нам, мы отменяем SNAT, un-DNAT и отвечаем внешнему пользователю.

Пт, 23 октября 2015 г., в 21:32, Микаэль Клюсо [email protected]
написал:

Звучит интересно, есть ссылка? :-) Я пытаюсь найти способ убедиться, что
пакет будет проходить через правильное правило conntrack. Я думал о
репликация состояния conntrack через кластер.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150753147
.

Ой, извините, если мне непонятно. Я говорил о случае без SNAT. Если каждый kube-proxy имеет один и тот же список conntrack, любой из них должен иметь возможность правильно отменить DNAT, когда контейнер отвечает клиенту.

Я не мог представить себе, что было без репликации, в которой не задействован HA, чтобы сохранить линейную структуру, подобную этой:

[client] ----- [proxy in HA] ------ [node1]
                           `------- [node2]

Но если вещь в форме треугольника может работать, это должно открыть больше возможностей.

[client] ----- [proxy1] ------ [node1]
       `------ [proxy2] ------ [node2]

Это было бы мило, но кажется безумно сложным

В воскресенье, 25 октября 2015 г., в 23:20, Микаэль Клюзо [email protected]
написал:

Ой, извините, если мне непонятно. Я говорил о случае без SNAT. Если
у каждого kube-proxy один и тот же список conntrack, любой из них должен иметь возможность
un-DNAT правильно, когда контейнер отвечает клиенту.

Я не мог видеть, что это было без репликации, которая не включает HA для сохранения
Линейная структура, подобная этой:

[клиент] ----- [прокси в HA] ------ [узел1]
`------- [узел2]

Но если вещь в форме треугольника может работать, это должно открыть больше возможностей.

[клиент] ----- [прокси1] ------ [узел1]
`------ [прокси2] ------ [узел2]

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -151037663
.

Способ, которым я должен исследовать (я не спрашивал и не хочу спрашивать перед надлежащим исследованием, но поскольку субджет теперь открыт ...), является «асимметричная многопутевая маршрутизация», которую вы можете увидеть здесь: http: // conntrack-tools.netfilter.org/manual.html#sync-aa. И да, это было бы действительно здорово :-)

Самая простая вещь, которая могла бы сработать ...

  1. proxy1 получает новое соединение через хук iptables (я думаю, что где-то видел это), и его LB назначает его узлу proxy2.
  2. proxy1 отправляет запрос типа "настроить запись conntrack для {src-ip}: {src-port} -> {pod-ip}: {pod-port}"
  3. proxy2 получает запрос, настраивает запись conntrack и ACK для прокси1
  4. proxy1 позволяет пакету проходить через правило DNAT (которое также помещает запись conntrack в proxy1).
  5. когда под отвечает, хост proxy2 unDNAT соответственно.
  6. когда клиент отправляет другой пакет в этом потоке через proxy1, запись conntrack также выполняет правильный DNAT.

Таким образом, накладные расходы составляют 2 пакета на новое соединение и быстро окупаются за счет исключения не-SNAT + дополнительной маршрутизации (поскольку в противном случае пакет должен вернуться через прокси1).

Я не специалист по сетям, поэтому могу предполагать слишком много, но это кажется разумным.

В моем случае я стремился установить правила брандмауэра для каждой службы NodePort.

Похоже, я могу добавить простые правила ALLOW IP / DROP для всех остальных правил в цепочке INPUT, например:

iptables -A INPUT -s $WHITELISTED_IP -p tcp --dport $CONTAINER_PORT -j ACCEPT
iptables -A INPUT -p tcp --dport $CONTAINER_PORT -j DROP

Чтобы применить эти правила, я предполагал использовать аннотации к службам NodePort. Аннотации будут содержать IP-адреса из белого списка.

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

Есть ли здесь что-нибудь, что может вызвать проблемы? Я ненормальный?

@thockin имеет вид лучше, чем я, но я бы не стал использовать для этого аннотацию. Я думаю, что безопасность ортогональна, и ее следует отложить в сторону системы или, возможно, плагина сети / прокси. Если у вас есть Kubernetes, у вас есть etcd, поэтому вы можете просто сохранить набор правил в ключе и обновить с помощью etcdctl watch / exec:

# while true; do etcdctl watch "/iptables/$(hostname)" && etcdctl get /iptables/$(hostname) |iptables-restore --noflush; done &
# iptables -F my-filter
# iptables -nvL my-filter
Chain my-filter (0 references)
 pkts bytes target     prot opt in     out     source               destination      
# ~nwrk/go/bin/etcdctl set /iptables/$(hostname) >/dev/null <<EOF
*filter
:my-filter -
-A my-filter -j ACCEPT -s 1.2.3.4 -p tcp --dport 80
-A my-filter -j DROP -p tcp --dport 80
COMMIT
EOF
# iptables -nvL my-filter
Chain my-filter (0 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     tcp  --  *      *       1.2.3.4              0.0.0.0/0            tcp dpt:80
    0     0 DROP       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80

Я думаю ты хочешь # 14505

В понедельник, 26 октября 2015 г., в 8:53, Бен Хандли [email protected]
написал:

В моем случае я стремился установить правила брандмауэра для каждой службы NodePort.

Похоже, я могу добавить простые правила ALLOW IP / DROP все остальные правила в
цепочка INPUT, например:

iptables -A INPUT -s $ WHITELISTED_IP -p tcp --dport $ CONTAINER_PORT -j ACCEPT
iptables -A INPUT -p tcp --dport $ CONTAINER_PORT -j DROP

Чтобы применить эти правила, я предполагал использовать аннотации на
Услуги NodePort. Аннотации будут содержать IP-адреса из белого списка.

Поскольку я могу немного подождать, пока эти правила вступят в силу, я
задача cron для каждого проходящего миньона и обновление INPUT миньона
цепочка из всех аннотаций сервиса.

Есть ли здесь что-нибудь, что может вызвать проблемы? Я ненормальный?

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -151181267
.

Это был первоначальный подход, когда группы безопасности были прикреплены к балансировщикам нагрузки. Я просто довольно быстро достиг предела количества слушателей на сетевой интерфейс на AWS и столкнулся с некоторой нелепой логикой, пытаясь распространить правила брандмауэра на несколько SG и несколько ELB для одного кластера куба.

К счастью, мы подошли к лучшему решению, которое не требует возни с iptables.

Если вы только что присоединились, позвольте мне подвести итоги. Все проблемы, связанные с невозможностью получить IP-адрес клиента, были объединены в эту проблему, однако предложенное (и реализованное) решение не решает ее. В настоящее время у вас нет возможности получить доступ к IP-адресу клиента. Ха.

@ shaylevi2 в настоящее время просто нет хорошего способа получить IP-адрес клиента при переходе через облачный LB на nodePort. Как только облако LB догонит, я прыгну прямо на него. Но это ДЕЙСТВИТЕЛЬНО сохраняет IP-адрес клиента в кластере.

Но это ДЕЙСТВИТЕЛЬНО сохраняет IP-адрес клиента в кластере.

Это зависит от того, как именно настроена сеть кластера; например, в данный момент это не работает правильно в OpenShift, потому что правила iptables не работают с внутренним трафиком OVS. Таким образом, пакеты получают DNAT, идущие в конечную точку службы, но поскольку исходный IP-адрес является внутренним кластером, ответ останется в OVS, поэтому он больше не попадет в iptables, поэтому DNAT не будет отменен, поэтому клиентский модуль не распознает пакеты. На данный момент простейший обходной путь для этого - полностью замаскировать пакеты, поступающие в конечную точку, заставляя их снова отказываться от OVS на выходе. (Я работаю над тем, чтобы как-то обойти это.)

Есть ли у OVS внутреннее понятие VIP? Вы могли бы просто избавиться от
kube-proxy (cf opencontrail)

Пт, 20 ноября 2015 г., в 7:09, Дэн Уиншип [email protected]
написал:

Но это ДЕЙСТВИТЕЛЬНО сохраняет IP-адрес клиента в кластере.

Это зависит от того, как именно настроена сеть кластера; например, это не
работают прямо в OpenShift на данный момент, потому что правила iptables не запускаются
по внутреннему трафику OVS. Таким образом, пакеты получают DNAT, идущие в службу.
конечная точка, но поскольку исходный IP-адрес является внутренним кластером, ответ будет
оставаться в OVS, чтобы он больше не попадал в iptables, поэтому DNAT не
меняются местами, поэтому клиентский модуль не распознает пакеты. На
На данный момент самый простой обходной путь для этого - полностью замаскировать пакеты
входя в конечную точку, заставляя их снова отказываться от OVS на
выход. (Я работаю над тем, чтобы как-то обойти это.)

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -158426296
.

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

(На данный момент похоже, что мы можем заставить его работать, добавив бесплатный дополнительный переход из OVS для пакетов с исходным IP + портом, соответствующим известной конечной точке службы, которые поступают из интерфейса контейнера; тогда узел, возможно, отключит DNAT от него. , а затем вернуть его обратно в OVS, где он может быть правильно доставлен обратно в клиентский модуль.)

Я надеюсь написать документ об абстракции Service VIP и сделать его
ясно, что это абстракция, которую можно заменить (и она должна быть
случаи).

В понедельник, 23 ноября 2015 г., в 6:54, Дэн Уиншип [email protected]
написал:

Мы говорили о том, чтобы сделать, по сути, эквивалент
pure-iptables-proxying полностью внутри OVS, но для этого требуется OVS conntrack
поддержка, для которой требуется самое последнее ядро, от которого мы не хотим зависеть
пока нет. Хотя, вероятно, это долгосрочный план.

(На данный момент похоже, что мы можем заставить его работать, добавив бесплатную дополнительную
выходить из OVS для пакетов с исходным IP + портом, совпадающим с известной службой
конечные точки, поступающие из интерфейса контейнера; тогда узел будет
возможно, отмените DNAT, а затем верните его обратно в OVS, где он сможет получить
доставлен обратно в клиентский модуль правильно.)

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -158959014
.

Хотя iptables / nftables решит задачи балансировки нагрузки как TCP, так и UDP, я лично считаю, что IPVS https://github.com/kubernetes/kubernetes/issues/17470 будет намного лучше, потому что он специально создан для балансировки нагрузки. (читайте: меньше текущих изменений / поддержки для команды k8s), предлагает более богатый набор алгоритмов балансировки нагрузки, доказал стабильность на скоростях, близких к линейной, у amd также есть библиотеки golang, готовые манипулировать правилами.

@thockin , другие, согласно https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150743158, я сделал аннотацию, но, как правильно упомянуто, внешний клиентский IP по-прежнему не виден приложением, находящимся в контейнере .

Как этого добиться, т.е. получить внешний IP-адрес клиента? В моей настройке нет внешнего LB, служба отображается как nodeport, а клиент выполняет простое TCP (не http / Websocket) соединение с моим контейнерным приложением.

@ashishvyas какая у вас версия kube-proxy?

Я использую v1.1.3

Следуйте инструкциям в https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -143280584 и https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150743158, но вместо аннотации с именем net.beta.kubernetes.io/proxy-mode , используйте аннотацию с именем net.experimental.kubernetes.io/proxy-mode .

for node in $(kubectl get nodes -o name); do
  kubectl annotate $node net.experimental.kubernetes.io/proxy-mode=iptables;
done

Вы должны увидеть операторы журнала в начале запуска kube-proxy, такие как «Найдена экспериментальная аннотация» и «Аннотация разрешает прокси iptables».

Первый выпуск, который сделал https://github.com/kubernetes/kubernetes/commit/da9a9a94d804c5bfdf3cc86ee76a2bc1a2742d16, был 1.1.4, поэтому net.beta.kubernetes.io/proxy-mode для многих не работает. Вы не первый, кто сталкивается с этим.

Из-за того, как работает прокси, мы теряем клиентский IP, когда он проходит
порт узла. Я знаю, что это не очень хорошо. Я очень много думаю о том, как
исправить это правильно, но в основном это сводится к возможностям
балансировщики нагрузки (или другие способы, которыми трафик достигает узла, например
как DNS-RR)

В среду, 13 января 2016 г., в 10:25, Майк Данезе [email protected]
написал:

Следуйте инструкциям в № 3760 (комментарий)
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -143280584
и # 3760 (комментарий)
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150743158
но вместо использования аннотации с именем
net.beta.kubernetes.io/proxy-mode используйте аннотацию с именем
net.experimental.kubernetes.io/proxy-mode.

для узла в $ (kubectl get nodes -o name); делать
kubectl аннотировать $ node net.experimental.kubernetes.io/proxy-mode=iptables;
сделано

Вы должны увидеть операторы журнала в начале запуска kube-proxy.
например, "Найдена экспериментальная аннотация" и "Аннотации разрешают прокси iptables"

Первый выпуск, который da9a9a9
https://github.com/kubernetes/kubernetes/commit/da9a9a94d804c5bfdf3cc86ee76a2bc1a2742d16
превратили в 1.1.4. Вы не первый, кто сталкивается с этим.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -171387997
.

@thockin , возможно ли какое-либо временное решение этой проблемы прямо сейчас? Если да, я бы порекомендовал предоставить подробные инструкции для меня, и другие в этой теме могут помочь.

Нет, в настоящее время нет реального обходного пути. Проблема сводится к
тот факт, что каждый прокси-сервер kube может выбирать серверную часть на другом узле.
Перенаправление трафика с исходным IP-адресом клиента будет иметь другой узел
ответить напрямую, что явно не сработает.

«Исправление» состоит в том, чтобы _только_ отправлять трафик для службы S на узлы, которые имеют
минимум 1 серверная часть для S _и_ для отправки трафика пропорционально количеству
бэкэнды есть у каждого узла. Затем Kube-proxy мог выбирать локальные серверы.
исключительно.

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

В среду, 13 января 2016 г., в 12:17, Ашиш Вьяс [email protected]
написал:

@thockin https://github.com/thockin , любое временное решение
обратиться к этому можно прямо сейчас? Если да, то рекомендую предоставить
подробные шаги для меня и других в этой теме помогут.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -171420567
.

@mikedanese ,

$ sudo docker pull gcr.io/google_containers/ hyperkube: v1.1.4
Извлечение репозитория gcr.io/google_containers/hyperkube
Тег v1.1.4 не найден в репозитории gcr.io/google_containers/hyperkube
$ sudo docker pull gcr.io/google_containers/ hyperkube: v1.1.3
v1.1.3: Получение из google_containers / hyperkube
Дайджест: sha256: 004dde049951a4004d99e12846e1fc7274fdc5855752d50288e3be4748778ca2
Статус: изображение обновлено для gcr.io/google_containers/ hyperkube: v1.1.3

@thockin Прошу прощения за длинный ответ, я хотел осветить оба метода, которые мы пытались решить, чтобы другие могли понять проблемы, с которыми мы столкнулись с обоими.

В качестве фона: наше основное приложение - это высокопроизводительная интеллектуальная DNS-платформа (т.е. для нее требуется UDP и требуется выполнение не менее 100 тыс. Запросов в секунду для каждого модуля), а также поддерживающее ее приложение в прокси-сервере SNI, которому необходимо видеть клиентов в реальном времени. IP-адрес (для нас это шоу-пробка). Мы не хотели использовать разные сетевые подходы для разных приложений, поэтому мы решили стандартизировать единый сетевой метод для всех, и мы решили использовать IPVS по причинам, которые я упомянул выше (производительность / стабильность / гибкость / SLB для целевой сборки) , но вы, вероятно, могли бы что-то взломать, используя только iptables в тех же самых строках. Мы используем vxlan (быстрый, простой, работает между сайтами), но оба этих метода также должны работать с GRE / VXLAN с OVS или со стандартной сетью хостов уровня 2 (при условии, что все ваши хосты находятся в одной сети L2).

Мы распределяем входящий трафик конечных пользователей, используя сочетание anycast и DNS, в зависимости от требований к скорости переключения при отказе или того, что лучше всего подходит для конкретного типа службы, поэтому у нас есть довольно равномерное распределение трафика конечных пользователей, поступающего на наши узлы, но Проблема, как вы указали, состоит в том, чтобы обеспечить равномерное распределение трафика между модулями, независимо от их местоположения. Другая проблема - убедиться, что сервисы, взаимодействующие с другими сервисами, эффективно балансируют нагрузку.

Мы попытались решить эту проблему с помощью двух моделей:

Первый метод, который мы попробовали, - это 2 слоя VIP. Внешние виртуальные IP-адреса (по 1 на службу), которые распределяют трафик между узлами (на основе количества модулей для этой службы на узле), а затем внутренние виртуальные IP-адреса (которые работают на узле с модулями), которые распределяют нагрузку внутри узлов (обычно равномерно по стручкам). Ограничением этой модели было то, что узлам, на которых выполнялись внешние виртуальные IP-адреса, требовалось запускать два разных сетевых пространства имен или запускать свои собственные физические узлы. Хорошая вещь с IPVS в режиме DSR (прямой возврат сервера) заключается в том, что ему не нужно видеть обратный трафик, трафик идет:

Consumer >> (over L3) >> External VIP node >> (1) >> Internal VIP node >> (2) >> Container >> (any which way you want) >> Consumer

(1) IPVS (в режиме DSR) на хосте с внешним VIP выбирает _node_ для отправки трафика («реальный сервер» в терминах IPVS) и изменяет только MAC-адрес DST пакета (т. Е. IP-пакет приходит без изменений на узел k8s). Он распределяет нагрузку между узлами в зависимости от количества модулей, на которых запущена эта служба на узле.
(2) IPVS (также в режиме DSR) на узле k8s распределяет нагрузку между модулями (через veths к узлу). Ответы из контейнеров (TCP и UDP) отправляются напрямую потребителю службы.

Плюс этой модели в том, что она была действительно простой в использовании и набором правил было очень легко управлять. Обратной стороной этой модели является то, что она концентрирует все наши запросы на обслуживание (но не ответы) через несколько узлов, на которых работают внешние VIP. Нам нравится "без общего доступа", поэтому введите версию 2:

Вторая модель теперь интересна - это один уровень VIP с более умной конфигурацией IPVS и iptables.

Consumer >> Any node/local node >> (1) >> Container >> (any which way you want) >> Consumer
или он может перейти на другой узел:
Consumer >> Any node/local node >> (1) >> Remote Node >> (2) >> Container >> (any which way you want) >> Consumer

(1) Трафик попадает на основной VIP, нагрузка распределяется по всем модулям в кластере.
(2) Трафик попадает на вторичный VIP, нагрузка балансируется только между всеми локальными модулями. Этот вторичный виртуальный IP-адрес используется только для трафика, поступающего от других хостов в сети (его VIP-идентификатор FWMARK). Мы отмечаем трафик, поступающий на любой внешний интерфейс, с помощью FWMARK = 1234, и это заставляет трафик переходить на другой набор правил, что предотвращает образование петель между узлами.

Основной VIP имеет список локальных модулей и удаленных хостов с модулями (с весом 100 для каждого локального модуля и 100 * количество модулей для удаленных узлов). Так, например, если 3 модуля работают локально на nodeA, и есть два модуля, работающих на nodeB, набор правил на nodeA будет выглядеть следующим образом:

Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP service.ip.address:0 rr persistent 360
-> pod1.on.nodeA.ip:80 Route 100 0 0
-> pod2.on.nodeA.ip:80 Route 100 0 0
-> pod2.on.nodeA.ip:80 Route 100 0 0
-> interfaceip.of.nodeB:80 Route 200 0 0
FWM 1234 rr
-> pod1.on.nodeA.ip:80 Route 100 0 0
-> pod2.on.nodeA.ip:80 Route 100 0 0
-> pod3.on.nodeA.ip:80 Route 100 0 0

Однако на nodeB конфигурация IPVS будет выглядеть немного иначе, потому что у нее только два локальных модуля и три удаленных модуля на nodeA:

Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP service.ip.address:0 rr persistent 360
-> pod1.on.nodeB.ip:80 Route 100 0 0
-> pod2.on.nodeB.ip:80 Route 100 0 0
-> interfaceip.of.nodeA:80 Route 300 0 0
FWM 1234 rr
-> pod1.on.nodeB.ip:80 Route 100 0 0
-> pod2.on.nodeB.ip:80 Route 100 0 0

Другой способ - переключить FWMARK и использовать iptables для FWMARK чего-либо в интерфейсах veth + (совпадение с подстановочными знаками) и использовать совпадение FWMARK только для локальной балансировки нагрузки.

Поскольку здесь нет NAT, вам нужно добавить IP-адреса SVC_XXX_YYY в среде в петлевой или фиктивный интерфейс при запуске каждого модуля, но вы, вероятно, также можете изменить IPVS VIP, чтобы также выполнять DNAT, я не вижу почему это не сработает.

Конечным результатом является наиболее прямая работа в сети без необходимости централизовать обработку / маршрутизацию запросов, поэтому масштабирование становится намного лучше. Обратной стороной является дополнительный ум при создании правил IPVS. Для всего этого мы используем небольшой демон (golang), но я бы подумал о написании для этого модуля k8s, если бы у меня было время и был бы достаточный интерес.

Я поздно погрузился в эту проблему и, вероятно, не прочитал достаточно подробно полный курс , но на всякий случай это помогает: если я понял сообщение

@lxpollitt Правильно, исходный IP-адрес сохраняется при использовании IPVS, однако имейте в виду, что с помощью этого метода нам пришлось в значительной степени самостоятельно выполнять все сетевые операции, поскольку конфигурация IPVS не поддерживается kube-proxy. Вы также можете сохранить исходный IP-адрес с помощью iptables, однако вам понадобятся два уровня IPtables DNAT, чтобы вы могли "отключить" трафик на обратном пути.

Со своей стороны, с фланелью (в режиме vxlan), управляющей моей контейнерной сетью, я использую kube-proxy (в режиме iptables, а не маскарадинг) + фланель в пространстве имен на моих узлах маршрутизации. Внешние запросы передаются через DNAT на служебные IP-адреса, а затем перенаправляются через пространство имен с помощью kube-proxy. Я не проводил тестирование кластера активного / активного маршрутизатора, но эта настройка позволяет мне сохранить внешний IP-адрес. Я упоминаю об этом FWIW, но понимаю, что это не «самая прямая сеть».

Я понимаю, что если бы kube-proxy мог управлять им, это было бы неплохо, но, учитывая ваши конкретные потребности и особенно тот факт, что балансировка нагрузки уже находится за пределами kube-proxy, не имеет ли смысла кодировать клиентский менеджер iptables-rules наблюдение за состоянием кластера kubernetes и настройка правил для DNAT VIP только для модулей работающего хоста? Это также может быть режим для kube-proxy, например ... ну ... Я не разбираюсь в именах ... --proxy-mode = iptables-to-node-pods-only.

Спасибо за подробный отзыв. Ваше решение интересно, и я потратил
у меня сегодня много времени подумать об этом. К сожалению, ты
пересекли на очень специфическую территорию, которая не работает в общем смысле.
Облака, такие как GCE, не могут использовать режим шлюза IPVS из-за маршрутизируемой
сеть. Даже если шлюз работал, он не поддерживает переназначение портов,
что делает Kubernetes, поэтому он применяется только в том случае, если порт службы == target
порт.

Основная задача кубернетов - найти способы справиться с
тип ситуации в целом или чтобы не мешать вам и дать вам возможность
настраивай сам. Может быть, мы могли бы что-нибудь сделать с режимом ipvs encap,
но я не знаю, как это повлияет на производительность.

14 января 2016 г. в 3:37 qoke [email protected] написал:

@thockin https://github.com/thockin Прошу прощения за длинный ответ, я
хотел охватить оба метода, с помощью которых мы пытались решить эту проблему, чтобы другие могли
понять проблемы, с которыми мы столкнулись с обоими.

Немного предыстории, наше основное приложение имеет очень высокую производительность.
интеллектуальная платформа DNS (т.е. ей нужен UDP и требуется не менее 100 тыс. +
запросов / сек на модуль) и его вспомогательное приложение в прокси-сервере SNI.
который должен видеть реальный IP-адрес клиента (это ограничитель показа для
нас). Мы не хотели использовать разные сетевые подходы для разных
приложений, поэтому мы решили стандартизировать единый сетевой метод для
все, и мы решили использовать IPVS по причинам, упомянутым выше
(производительность / стабильность / гибкость / цель сборки SLB), но вы могли бы
возможно, взломайте что-нибудь вместе, используя только iptables в этих же строках
тоже. Мы используем vxlan (быстро, легко, работает между сайтами), но оба эти
методы также должны работать с GRE / VXLAN с OVS или со стандартным уровнем 2
сеть хостов тоже (при условии, что все ваши хосты находятся в одной сети L2).

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

Мы попытались решить эту проблему с помощью двух моделей:

Первый метод, который мы попробовали, - это 2 слоя VIP. Внешние VIP-персоны (1 на
сервис), которые распределяют трафик между узлами (на основе количества контейнеров для
эта служба на узле), а затем внутренние VIP (которые работают на узле
с модулями), которые распределяют нагрузку внутри узлов (обычно равномерно
через капсулы). Ограничением этой модели было то, что узлы, работающие на внешнем
VIP должны были запускать два разных сетевых пространства имен или запускать свои собственные
физические узлы. Хорошая вещь с IPVS в режиме DSR (прямой возврат сервера)
режим такой, что не нужно видеть обратный трафик, трафик идет:

Потребитель >> (через L3) >> Внешний VIP-узел >> (1) >> Внутренний VIP-узел >>
(2) >> Контейнер >> (любым способом) >> Потребительский

(1) IPVS (в режиме DSR) на хосте с внешним VIP выбирает _node_ для
отправлять трафик на («настоящий сервер» в терминах IPVS) и меняет только DST MAC
адрес пакета (т.е. IP-пакет поступает в узел k8s без изменений). Это загрузка
балансирует между узлами в зависимости от количества модулей, на которых запущена эта служба.
узел.
(2) IPVS (также в режиме DSR) на узле k8s распределяет нагрузку между
стручки (через ветки к узлу). Ответы из контейнеров (TCP и UDP) идут
непосредственно обратно потребителю услуги.

Плюс этой модели в том, что она была действительно простой в использовании, а
набором правил было очень легко управлять. Обратной стороной этой модели является то, что она
концентрирует все наши запросы на обслуживание (но не ответы) через
количество узлов, на которых работают внешние VIP. Нам нравится "ничего не поделить", поэтому
введите версию 2:

Вторая модель сейчас развлекательная - это один слой VIP с
более умная настройка IPVS и iptables.

Потребитель >> Любой узел / локальный узел >> (1) >> Контейнер >> (любым способом
хочу) >> Потребитель
или он может перейти на другой узел:
Потребитель >> Любой узел / локальный узел >> (1) >> Удаленный узел >> (2) >> Контейнер

(как хотите) >> Потребитель

(1) Трафик попадает в основной VIP, трафик распределяется по всем модулям в
кластер.
(2) Трафик попадает на вторичный VIP, трафик распределяется по нагрузке только по всем
местные капсулы. Этот вторичный виртуальный IP-адрес используется только для трафика, поступающего из
другие хосты в сети (это VIP-идентификатор FWMARK). Мы отмечаем входящий трафик
любой внешний интерфейс с FWMARK = 1234, и это заставляет трафик идти
к другому набору правил, которые предотвращают зацикливание между узлами.

У основного VIP есть список локальных модулей и удаленных хостов с модулями (с
вес 100 для каждого локального модуля и 100 * количество контейнеров для
удаленные узлы). Так, например, если 3 модуля работают локально на nodeA, и
на nodeB работают два модуля, набор правил на nodeA будет выглядеть так:
это:

Prot LocalAddress: флаги планировщика портов
-> RemoteAddress: Port Forward Weight ActiveConn InActConn
TCP service.ip.address: 0 rr постоянный 360
-> pod1.on.nodeA.ip: 80 Маршрут 100 0 0
-> pod2.on.nodeA.ip: 80 Маршрут 100 0 0
-> pod2.on.nodeA.ip: 80 Маршрут 100 0 0
-> interfaceip.of.nodeB: 80 Маршрут 200 0 0
FWM 1234 рр
-> pod1.on.nodeA.ip: 80 Маршрут 100 0 0
-> pod2.on.nodeA.ip: 80 Маршрут 100 0 0
-> pod3.on.nodeA.ip: 80 Маршрут 100 0 0

Однако на nodeB конфигурация IPVS будет выглядеть немного иначе, потому что она
имеет только два локальных модуля и три удаленных модуля на nodeA:

Prot LocalAddress: флаги планировщика портов
-> RemoteAddress: Port Forward Weight ActiveConn InActConn
TCP service.ip.address: 0 rr постоянный 360
-> pod1.on.nodeB.ip: 80 Маршрут 100 0 0
-> pod2.on.nodeB.ip: 80 Маршрут 100 0 0
-> interfaceip.of.nodeA: 80 Маршрут 300 0 0
FWM 1234 рр
-> pod1.on.nodeB.ip: 80 Маршрут 100 0 0
-> pod2.on.nodeB.ip: 80 Маршрут 100 0 0

Другой способ - переключить FWMARK и использовать iptables для
FWMARK что угодно в интерфейсах veth + (совпадение с подстановочными знаками) и иметь FWMARK
match используется только для локальной балансировки нагрузки.

Конечным результатом является максимально прямое сетевое взаимодействие без необходимости централизации.
обработка / маршрутизация запросов, поэтому масштабируется намного лучше. Обратной стороной является некоторые
дополнительные умения при создании правил IPVS.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -171619663
.

Думаю, было бы интересно попробовать режим iptables-to-node-pods-only ,
но в нем много волн. Потенциал дисбаланса вполне реален и
по крайней мере, сервисный контроллер должен знать, как программировать
внешние балансировщики нагрузки.

В четверг, 14 января 2016 г., в 15:59, Микаэль Клюзо [email protected]
написал:

Со своей стороны, используя фланель (в режиме vxlan), управляющую моей контейнерной сетью, я
использовать kube-proxy (в режиме iptables и без маскарадинга) + фланель в
пространство имен на моих узлах маршрутизации. Внешние запросы передаются на обслуживание через DNAT.
IP-адреса, а затем перенаправляются через пространство имен с помощью kube-proxy. Я не
выполнено тестирование кластера активного / активного маршрутизатора, но эта настройка позволяет мне сохранить
внешний IP. Я упоминаю об этом FWIW, но понимаю, что это не самый
прямые сети ".

Я понимаю, что если бы kube-proxy справился с этим, было бы неплохо, но
учитывая ваши конкретные потребности и особенно тот факт, что балансировка нагрузки
уже находится за пределами kube-proxy, не имеет ли смысла кодировать клиента
диспетчер iptables-rules, отслеживающий состояние кластера kubernetes и настраивающий
правила для DNAT VIP только для модулей работающего хоста? Это могло, это может
также быть режимом для kube-proxy, хотя вроде ... ну .. я не умею
имена ... --proxy-mode = iptables-to-node-pods-only.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -171821603
.

@thockin Вы имеете в виду, например, если 2 реплики находятся на одном узле? Я думаю, что мы могли бы вынести случай «программировать внешние балансировщики нагрузки» за рамки kube-proxy, поскольку он имеет несколько экземпляров, а внешний LB-программист, вероятно, должен находиться в режиме «одного ведущего». Таким образом, включение режима kube-proxy «iptables-to-node-pods-only» - это только первый из двух этапов процесса.

Думаю, я мог бы попробовать реализовать что-то подобное завтра: режим «iptables-to-node-pods-only» в kube-proxy, плюс contrib / ip-route-elb, который будет поддерживать таблицу маршрутизации Linux с одним маршрутом для каждой службы. , с правильным весом для каждого узла в зависимости от того, сколько конечных точек имеет узел для данной службы.

@thockin Например, вы имеете в виду, что 2 реплики находятся на одном узле? Я думаю, мы могли бы поставить случай "запрограммировать
внешние балансировщики нагрузки »за пределами kube-proxy, так как он имеет несколько экземпляров и внешний LB
программист, вероятно, должен быть в режиме «единственного мастера». Таким образом, разрешив режим kube-proxy "iptables-to-node-
только для стручков "- это только первый из двух этапов процесса.

«Только прокси для локальных модулей» должен быть вторым этапом процесса. Шаг 1
должен изменить сервисный контроллер, чтобы отправлять только балансировщики нагрузки
к узлам, которые имеют 1 или несколько бэкэндов для данной Услуги. Этот шаг
само по себе ВЕРОЯТНО разумно, но для
убедитесь, что мы все поняли правильно. Я думаю, что мы хотим это сделать в конце концов,
в любом случае.

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

Думаю, я мог бы попробовать реализовать что-то вроде этого завтра: режим "iptables-to-node-pods-only" в kube-proxy,
плюс contrib / ip-route-elb, который будет поддерживать таблицу маршрутизации Linux с одним маршрутом для каждой службы с правильным весом
для каждого узла в зависимости от того, сколько конечных точек имеет узел для данной службы.

Если ELB поддерживает веса, то в некоторых отношениях он будет работать лучше, чем
GCE, чего нет. Ничего страшного, я просто не думал, что он поддерживает
веса. Я не думаю, что это можно внести, но это довольно
фундаментальная часть системы.

16.01.2016 в 05:19 Тим Хокин написал:

«Только прокси для локальных модулей» должен быть вторым этапом процесса. Шаг 1
должен изменить сервисный контроллер, чтобы отправлять только балансировщики нагрузки
к узлам, которые имеют 1 или несколько бэкэндов для данной Услуги. Этот шаг
само по себе ВЕРОЯТНО разумно, но для
убедитесь, что мы все поняли правильно. Я думаю, что мы хотим это сделать в конце концов,
в любом случае.

В этом есть смысл.

Как только это будет сделано, [...]

Так что посмотрим, когда это будет сделано :-)

Если ELB поддерживает веса, то в некоторых отношениях он будет работать лучше, чем
GCE, чего нет. Ничего страшного, я просто не думал, что он поддерживает
веса.

Так как это из руководства, и у вас, вероятно, больше, чем в 10 раз больше, чем у меня.
Имея опыт работы в такого рода сетях, я должен полностью игнорировать загвоздку.
Man ip-route говорит следующее:

           nexthop NEXTHOP
                  the nexthop of a multipath route.  NEXTHOP is a 

сложное значение с собственным синтаксисом, аналогичным спискам аргументов верхнего уровня:

                          via [ FAMILY ] ADDRESS - is the nexthop 

роутер.

                          dev NAME - is the output device.

                          weight NUMBER - is a weight for this 

элемент многолучевого маршрута, отражающий его относительную полосу пропускания или качество.

Я не думаю, что это можно внести, но это довольно
фундаментальная часть системы.

Поскольку "E" означает "внешний", я подумал, что это может начаться там,
по крайней мере, чтобы получить код для поддержки идей.

Пт, 15 января 2016 г., 14:55, Микаэль Клюзо
[email protected] написал:

16.01.2016 в 05:19 Тим Хокин написал:

«Только прокси для локальных модулей» должен быть вторым этапом процесса. Шаг 1
должен изменить сервисный контроллер, чтобы отправлять только балансировщики нагрузки
к узлам, которые имеют 1 или несколько бэкэндов для данной Услуги. Этот шаг
само по себе ВЕРОЯТНО разумно, но для
убедитесь, что мы все поняли правильно. Я думаю, что мы хотим это сделать в конце концов,
в любом случае.

В этом есть смысл.

Я сегодня больше об этом подумал, не думаю, что это будет очень сложно.
Просто средней жесткости.

Как только это будет сделано, [...]

Так что посмотрим, когда это будет сделано :-)

честно говоря, я просто хочу знать, где идет набор изменений :)

Если ELB поддерживает веса, то в некоторых отношениях он будет работать лучше, чем
GCE, чего нет. Ничего страшного, я просто не думал, что он поддерживает
веса.

Так как это из руководства, и у вас, вероятно, больше, чем в 10 раз больше, чем у меня.
Имея опыт работы в такого рода сетях, я должен полностью игнорировать загвоздку.
Man ip-route говорит следующее:

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

через [СЕМЕЙНЫЙ] АДРЕС - следующий магазин
роутер.

dev NAME - устройство вывода.

НОМЕР веса - вес для этого
элемент многолучевого маршрута, отражающий его относительную полосу пропускания или качество.

Однако на самом деле мы не используем понятие IP-маршрутизации в Linux. Ни один из
Во всяком случае, реализации LB, о которых я знаю, используют. GCE использует облако Google
балансир, не имеющий весов. Я не знаю, это Amazon ELB
делает.

Я не думаю, что это можно внести, но это довольно
фундаментальная часть системы.

Поскольку "E" означает "внешний", я подумал, что это может начаться там,
по крайней мере, чтобы получить код для поддержки идей.

Конечно, мы можем НАЧАТЬ в Contrib :)

Кроме того, если вы хотите добиться этого, вы должны открыть 2 ошибки, например:

1) балансировщики нагрузки для Сервиса должны нацеливаться только на узлы, которые на самом деле
иметь серверную часть для этой службы

2) чтобы сохранить IP-адрес клиента в балансировщиках нагрузки, kube-proxy должен
всегда предпочитайте локальный бэкэнд, если он присутствует (xref # 1)

а затем объясните намерение и направление

В пятницу, 15 января 2016 г., в 17:11 Тим Хокин [email protected] написал:

Пт, 15 января 2016 г., 14:55, Микаэль Клюзо
[email protected] написал:

16.01.2016 в 05:19 Тим Хокин написал:

«Только прокси для локальных модулей» должен быть вторым этапом процесса. Шаг 1
должен изменить сервисный контроллер, чтобы отправлять только балансировщики нагрузки
к узлам, которые имеют 1 или несколько бэкэндов для данной Услуги. Этот шаг
само по себе ВЕРОЯТНО разумно, но для
убедитесь, что мы все поняли правильно. Я думаю, что мы хотим это сделать в конце концов,
в любом случае.

В этом есть смысл.

Я сегодня больше об этом подумал, не думаю, что это будет очень сложно.
Просто средней жесткости.

Как только это будет сделано, [...]

Так что посмотрим, когда это будет сделано :-)

честно говоря, я просто хочу знать, где идет набор изменений :)

Если ELB поддерживает веса, то в некоторых отношениях он будет работать лучше, чем
GCE, чего нет. Ничего страшного, я просто не думал, что он поддерживает
веса.

Так как это из руководства, и у вас, вероятно, больше, чем в 10 раз больше, чем у меня.
Имея опыт работы в такого рода сетях, я должен полностью игнорировать загвоздку.
Man ip-route говорит следующее:

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

через [СЕМЕЙНЫЙ] АДРЕС - следующий магазин
роутер.

dev NAME - устройство вывода.

НОМЕР веса - вес для этого
элемент многолучевого маршрута, отражающий его относительную полосу пропускания или качество.

Однако на самом деле мы не используем понятие IP-маршрутизации в Linux. Ни один из
Во всяком случае, реализации LB, о которых я знаю, используют. GCE использует облако Google
балансир, не имеющий весов. Я не знаю, это Amazon ELB
делает.

Я не думаю, что это можно внести, но это довольно
фундаментальная часть системы.

Поскольку "E" означает "внешний", я подумал, что это может начаться там,
по крайней мере, чтобы получить код для поддержки идей.

Конечно, мы можем НАЧАТЬ в Contrib :)

Риск PR без документации состоит в том, что он идет не в том направлении. это
намного проще рассматривать что-то как предложение. Я посмотрю на твою
PR, когда у меня будет возможность, надеюсь, скоро.
15 января 2016 г. в 19:02 «Микаэль Клюзо» [email protected] написал:

Можно ли открывать пул-реквест для (1) напрямую с этим именем и некоторыми
объяснения?

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172149777
.

К сожалению, вы перешли на очень специфическую территорию, которая не работает в общем смысле.
Облака, такие как GCE, не могут использовать режим шлюза IPVS из-за маршрутизируемой сети. Даже если шлюз работал, он не поддерживает переназначение портов, что делает Kubernetes, поэтому он применяется только в том случае, если порт службы == целевой порт.

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

Исправьте ограничение в режиме DSR: порт службы == целевой порт, но на самом деле это не проблема, если у вас нет двух приложений _ в одном контейнере_, которые должны работать на одном и том же порте (мы потратили много времени, думая о это, и, предполагая рекомендацию «1 приложение на контейнер», мы не смогли найти ни одного варианта использования для этого). У нас есть много контейнеров, работающих на одних и тех же узлах, со службами внутри них, все на одних и тех же портах, и все они хорошо сбалансированы. Если вам действительно нужно переназначить порты (хотя я хотел бы понять настоящие причины этого), вы можете использовать режим IPVS NAT вместо режима «МАРШРУТ».

Задача, лежащая в основе кубернетов, состоит в том, чтобы найти способы справиться с вашей ситуацией в целом или уйти с дороги и дать вам возможность настроить ее самостоятельно. Возможно, мы могли бы что-то сделать с режимом ipvs encap, но я не знаю, как это повлияет на производительность.

То, что мы сделали, является настолько универсальным, насколько это возможно (работает здесь, работает в Amazon, и я уверен, что это будет работать в GCE, когда у нас возникнет необходимость в расширении), с единственным ограничением для DSR, что приложение работа в модуле / контейнере должна выполняться на том же порту, что и служба, что после долгого внутреннего обсуждения никто не смог найти сценарий, в котором это будет ограничивать с точки зрения стека приложений E2E.

С учетом сказанного, если вы удалите DSR (режим IPVS Route) из уравнения и вместо этого будете использовать «режим NAT» IPVS, тогда порты можно будет переназначить, и вы по-прежнему получите преимущества, связанные с функциями / производительностью / т. Д. IPVS. Единственным недостатком является то, что NAT добавляет некоторый налог на производительность, но (а) он поддерживает UDP, и (б) он по-прежнему молниеносен по сравнению с решением для пользовательского пространства.

@brendandburns @thockin Ранее в теме вы просили

https://docs.google.com/presentation/d/1vv5Zszt4HDGbuyVlvOe76unHskxPuZQseQnarNbhQVc

DNAT был включен на IPVS для справедливого сравнения с двумя другими решениями (это также означает, что порт службы может отличаться от порта целевой службы). Наши рабочие нагрузки могут показаться некоторым немного необычными, но наши целевые показатели производительности, вероятно, не отличаются от других (т. Е. Выжать из оборудования все, что вы можете получить).

Спасибо!

Я не уверен, откуда взялась идея, что kube-proxy не поддерживает UDP - это
абсолютно работает, хотя, возможно, и не идеально (без подключения
вплоть до таймаутов).

Также стоит прояснить iptables (новый) kube-proxy и пользовательское пространство.
(устаревший) режим.

В субботу, 16 января 2016 г., в 21:45 qoke [email protected] написал:

@thockin https://github.com/thockin Ранее в теме вы просили
некоторые показатели производительности. Я бы не назвал это самым полным набором
тестов, но я полагаю, что HTTP - одна из наиболее распространенных рабочих нагрузок в
контейнеры, поэтому вот несколько номеров apache-bench в качестве отправной точки:

https://docs.google.com/presentation/d/1vv5Zszt4HDGbuyVlvOe76unHskxPuZQseQnarNbhQVc

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

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172293881
.

Хороший отзыв о новом и устаревшем режиме - отмечен и обновлен.

Также, что касается UDP, спасибо за разъяснения; Я не знал, что UDP полностью поддерживается в kube-proxy до сих пор. Когда мы впервые попробовали kube-proxy с UDP, у нас было много зависаний. Не знаю, почему, но мы увеличили таймауты, но проблемы все еще были. Нам нужно было быстро найти решение, поэтому мы решили обойти его с помощью IPVS, а не отлаживать его. В то время это работало только для рабочих нагрузок с довольно низкой частотой пакетов в секунду (менее 1 тыс. Пакетов в секунду), но в последнее время мы не тестировали повторно.

Основная проблема с iptables и любой высокоскоростной службой UDP - это заполнение таблиц netfilter conntrack. Даже если вы увеличите размер conntrack до 1 миллиона, некоторые зараженные вредоносными программами конечные пользователи атакуют вас или пытаются использовать вас для атаки с усилением DNS, и тогда ваша таблица conntrack снова заполняется. Вообще говоря, лучшая практика для DNS-серверов (или любых высокоскоростных служб UDP) - отключить conntrack (используя -j NOTRACK в необработанной таблице), и если вы отключите conntrack, iptables NAT и материалы с отслеживанием состояния (-m состояние) прерываются.

Где, помимо репозитория GIT, лучше всего поискать, прежде чем пытаться создать модуль / пакет k8s.io/kubernetes/pkg/proxy/ipvs? или лучше оставить это тому, кто лучше знает код?

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

17.01.2016 20:50 qoke написал:

Помимо репозитория GIT, где было бы лучше всего поискать раньше
пытаетесь создать модуль / пакет "k8s.io/kubernetes/pkg/proxy/ipvs"?

Я считаю, что вы тоже можете начать с Contrib.

FWIW ... Я использовал списки и магазины undelta, чтобы создать независимую
binay реагирует на состояние кластера в
https://github.com/kubernetes/kubernetes/pull/19755. Если информация
в
https://github.com/kubernetes/kubernetes/pull/19755/files#diff -0becc97ac222c3f2838fbfe8446d5375R26
достаточно, вам нужно только изменить вызов несколькими строками ниже
(https://github.com/kubernetes/kubernetes/pull/19755/files#diff-0becc97ac222c3f2838fbfe8446d5375R44).

Обратите внимание, что в этом PoC я поддерживаю только службы clusterIP.

К сожалению, вы перешли на очень специфическую территорию, которая не работает в общем смысле.
Облака, такие как GCE, не могут использовать режим шлюза IPVS из-за маршрутизируемой сети. Даже если шлюз работал, он не работает.
поддерживает переназначение портов, что и делает Kubernetes, поэтому оно применяется только в том случае, если порт службы == целевой порт.

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

Я не знаю, как это может работать. Статические маршруты на уровне машины не работают
в ГЦЭ. Возможно, мне не хватает какой-то техники, которую вы применили. я
свободно признаюсь, что я НЕ эксперт в этом :)

Исправьте ограничение: порт службы == целевой порт, но на самом деле это не проблема, если у вас нет двух приложений в
тот же контейнер, который должен работать на том же порту (мы потратили много времени на размышления об этом и предположили, что "1 приложение
на контейнер ", мы не смогли найти ни одного варианта использования для этого). У нас много контейнеров, работающих на одних и тех же узлах.
со службами внутри них, все на одних и тех же портах, и вся нагрузка хорошо сбалансирована. Одним словом, используемый нами подход вас не останавливает.
от запуска нескольких служб на одних и тех же портах на одном узле.

Это также применимо, если у вас есть серверы, которые меняют версии (например,
переход между etcd1 и etcd2) или в любой другой ситуации, когда
бэкэнд-порт просто должен быть другим. Проблема в том, что
Kubernetes позволяет это выражать, поэтому мы должны убедиться, что люди
может фактически использовать его (или отказаться от него и прекратить использование функции, которая
кажется маловероятным).

Суть кубернетов заключается в том, чтобы найти способы справиться с ситуацией в целом или уйти с дороги.
и дадут вам возможность настроить его самостоятельно. Может быть, мы могли бы что-нибудь сделать с режимом ipvs encap, но я не знаю, как
последствия этого.

То, что мы сделали, является настолько универсальным, насколько это возможно (работает здесь, работает в Amazon, и я уверен, что это будет работать в
GCE, когда у нас есть необходимость в расширении), с единственным ограничением, что приложение, работающее в модуле / контейнере, должно> работать на том же порту, что и служба, которая после длительного внутреннего обсуждения никому не удалось найти сценарий, где
это было бы ограничением с точки зрения стека приложений E2E.

Я действительно хочу понять, как это сделать. Есть ли у вас что-нибудь более пошаговое?

Также, что касается UDP, спасибо за разъяснения; Я не знал, что UDP полностью поддерживается в kube-proxy до сих пор.
Когда мы впервые попробовали kube-proxy с UDP, у нас было много зависаний. Не знаю почему, но мы увеличили таймауты и
все еще были проблемы. Нам нужно было быстро найти решение, поэтому мы решили обойти его с помощью IPVS, а не отлаживать его. На
время он работал только для рабочих нагрузок с довольно низкой частотой пакетов в секунду (менее 1 тыс. пакетов в секунду), но в последнее время мы не тестировали повторно.

Основная проблема с iptables и любой высокоскоростной службой UDP - это заполнение таблиц netfilter conntrack. Даже если вы увеличите
conntrack до 1 миллиона, затем некоторые зараженные вредоносным ПО конечные пользователи атакуют вас или пытаются использовать вас для усиления DNS.
атака, а затем ваша таблица conntrack снова заполнится. В общем, лучшая практика для DNS-серверов (или любых высокоскоростных
UDP services) - отключить conntrack (используя -j NOTRACK в необработанной таблице), а если вы отключите conntrack, iptables NAT и
состояние с сохранением состояния (-m состояние) прерывается.

Да, NAT для UDP действительно неудачный. Поиск не-conntrack
решение было бы отличным, но оно должно применяться ко всем
среды или параметризоваться платформой (что само по себе сложно
способ).

Помимо репозитория GIT, где лучше всего посмотреть, прежде чем пытаться создать
Модуль / пакет "k8s.io/kubernetes/pkg/proxy/ipvs"? или лучше оставить это тому, кто лучше знает код?

Я открыл проблему на github по поводу IPVS, но использовал маскарад (NAT)
режим, потому что я не мог заставить его работать на GCE без (и из-за
функция переназначения портов). Если переназначение портов привело к менее идеальному
режим балансировки, я, вероятно, мог бы жить с этим и просто задокументировать это
как таковой.

Мы должны переместить сюда эту колонну - здесь она заблудится.

18.01.2016 12:34 Тим Хокин написал:

Да, NAT для UDP действительно неудачный. Поиск не-conntrack
решение было бы отличным, но оно должно применяться ко всем
среды или параметризоваться платформой (что само по себе сложно
способ).

может работать NAT без сохранения состояния в случае, когда пара (под, порт) имеет
Самая одна служба (много контейнеров в одну службу)?

Это выглядело бы так:

{from: clientIP: clientPort, to: externalIP: externalPort} --- [прокси выбирает случайный модуль] ---> {from: clientIP: clientPort, to: podIP: targetPort} ---> [маршрутизируется через правильный хост ...]

На обратном пути у брандмауэра будет правило, говорящее о пакете {от:
podIP: targetPort , to: any} должен быть привязан к {from:
e xternalIP: externalPort , к: без изменений}.

Чтобы выразить это на диалекте iptables:

iptables -t nat -N stateless-svc-in

iptables -t nat -N stateless-svc-out

iptables -t nat -A stateless-svc-in  -j DNAT -s 1.2.3.4  -p udp --dport 53 --to-destination 10.1.0.1 -m statistic --mode random --probability 0.3333

iptables -t nat -A stateless-svc-in  -j DNAT -s 1.2.3.4  -p udp --dport 53 --to-destination 10.2.0.1 -m statistic --mode random --probability 0.5

iptables -t nat -A stateless-svc-in  -j DNAT -s 1.2.3.4  -p udp --dport 53 --to-destination 10.2.0.2 -m statistic --mode random --probability 1

iptables -t nat -A stateless-svc-out -j SNAT -s 10.1.0.1 -p udp --sport 53 --to-source 1.2.3.4

iptables -t nat -A stateless-svc-out -j SNAT -s 10.2.0.1 -p udp --sport 53 --to-source 1.2.3.4

iptables -t nat -A stateless-svc-out -j SNAT -s 10.2.0.2 -p udp --sport 53 --to-source 1.2.3.4

Не вижу, где это не работает, когда пакет приходит извне
кластер.

Способ выражения Сервисов в Kubernetes позволяет
обслуживается любым количеством Сервисов, поэтому это не работает - мы не знаем, что
в SNAT в.

В воскресенье, 17 января 2016 г., в 18:13, Микаэль Клюзо [email protected]
написал:

18.01.2016 12:34 Тим Хокин написал:

Да, NAT для UDP действительно неудачный. Поиск не-conntrack
решение было бы отличным, но оно должно применяться ко всем
среды или параметризоваться платформой (что само по себе сложно
способ).

может работать NAT без сохранения состояния в случае, когда пара (под, порт) имеет
Самая одна служба (много контейнеров в одну службу)?

Это выглядело бы так:

{from: clientIP: clientPort, to: externalIP: externalPort} --- [прокси выбирает
случайный модуль] ---> {from: clientIP: clientPort, to: podIP: targetPort} --->
[маршрутизируется через правильный хост ...]

На обратном пути у брандмауэра будет правило, говорящее о пакете {от:
podIP: targetPort , to: any} должен быть привязан к {from:
e xternalIP: externalPort , к: без изменений}.

Чтобы выразить это на диалекте iptables:

iptables -t nat -N stateless-svc-in

iptables -t nat -N stateless-svc-out

iptables -t nat -A stateless-svc-in -j DNAT -s 1.2.3.4 -p udp --dport 53
--to-destination 10.1.0.1 -m statistic --mode random --probability 0.3333

iptables -t nat -A stateless-svc-in -j DNAT -s 1.2.3.4 -p udp --dport 53
--to-destination 10.2.0.1 -m statistic --mode random --probability 0.5

iptables -t nat -A stateless-svc-in -j DNAT -s 1.2.3.4 -p udp --dport 53
--to-destination 10.2.0.2 -m statistic --mode random --probability 1

iptables -t nat -A stateless-svc-out -j SNAT -s 10.1.0.1 -p udp --sport 53
--to-source 1.2.3.4

iptables -t nat -A stateless-svc-out -j SNAT -s 10.2.0.1 -p udp --sport 53
--to-source 1.2.3.4

iptables -t nat -A stateless-svc-out -j SNAT -s 10.2.0.2 -p udp --sport 53
--to-source 1.2.3.4

Не вижу, где это не работает, когда пакет приходит извне
кластер.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172408290
.

18.01.2016 15:31 Тим Хокин написал:

Способ выражения Сервисов в Kubernetes позволяет использовать один модуль.
быть
обслуживается любым количеством Сервисов, поэтому это не работает - мы не знаем
какие
в SNAT в.

Вот почему я ограничился случаем «многие к одному» (мое первое предложение :-)).
Я просто пытаюсь провести черту вокруг того, что можно сделать, а что нет.

Конечно, у меня просто неудачная работа - указать, почему это не
достаточно общее решение :(

В воскресенье, 17 января 2016 г., в 20:34, Микаэль Клюзо [email protected]
написал:

18.01.2016 15:31 Тим Хокин написал:

Способ выражения Сервисов в Kubernetes позволяет использовать один модуль.
быть
обслуживается любым количеством Сервисов, поэтому это не работает - мы не знаем
какие
в SNAT в.

Вот почему я ограничился случаем «многие к одному» (мое первое предложение :-)).
Я просто пытаюсь провести черту вокруг того, что можно сделать, а что нет.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172421828
.

18.01.2016 15:46 Тим Хокин написал:

Конечно, у меня просто неудачная работа - указать, почему это не
достаточно общее решение :(

Да ... но это FAQ. Мы также могли бы указать где-нибудь "if len (services)
== 1 {реализовать без сохранения состояния} else {реализовать с отслеживанием состояния} ". Но это может
выглядят беспорядком для новичков. Я также мог бы быть contrib / elbs / чем-то ...

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

В воскресенье, 17 января 2016 г., в 20:51, Микаэль Клюзо [email protected]
написал:

18.01.2016 15:46 Тим Хокин написал:

Конечно, у меня просто неудачная работа - указать, почему это не
достаточно общее решение :(

Да ... но это FAQ. Мы также могли бы указать где-нибудь "if len (services)
== 1 {реализовать без сохранения состояния} else {реализовать с отслеживанием состояния} ". Но это может
выглядят беспорядком для новичков. Я также мог бы быть
contrib / elbs / что-то ...

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172425404
.

18.01.2016 16:07 Тим Хокин написал:

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

Я согласен, но пока не знаю лучше :-(

Я полагаю, что даже специально созданная SDN должна что-то отслеживать. Может быть
решения на основе этикеток, такие как MPLS ..?

18.01.2016 16:18 Микаэль Клюзо написал:

Я полагаю, что даже специально созданная SDN должна что-то отслеживать.
Может быть, решения на основе этикеток вроде MPLS ..?

В идее маркировки вещей ... если мы назначим один IP для каждой службы + один
IP для каждой конечной точки (пара сервис + модуль) и добавьте эти IP-адреса конечной точки в
pods, он должен работать полностью без сохранения состояния:

`` `` `

  • Внешний для хоста: {from: clientIP: clientPort, to: externalIP: servicePort} ----- [ELB
    выбирает одну конечную точку] --------> {from: clientIP: clientPort, to:
    endpointServiceIP: podPort} -> маршрут к хосту
  • От хоста к поду: {from: clientIP: clientPort, to: endpointServiceIP: podPort} - [стандартный
    маршрутизация к контейнерам] -> {from: clientIP: clientPort , to:
    конечная точка ServiceIP: podPort }

  • Под на хост: {from: endpointServiceIP: podPort, to: clientIP: clientPort}
    -------- [стандартная маршрутизация к маршрутизаторам] -----> {от:
    endpointServiceIP: podPort, to: clientIP: clientPort} - От хоста до внешнего: {from: endpointServiceIP: podPort, to: clientIP: clientPort} -------- [ELB
    SNAT назад] ------------------> {from: clientIP: clientPort , to:
    e xternalIP: servicePort } ``

Думаю, мы можем сделать это и для IP-адресов кластера.
`` `` `

Я не могу заставить это работать на GCE, и я не уверен в AWS - есть
доступно ограниченное количество статических маршрутов.

Интересно, смогу ли я сделать это, объединив 2 диапазона IP в один
маршрут. Приходится тратить много IP-адресов, но я думаю, это имеет значение только для UDP.
Придется попробовать.

Изменить: я попробовал это и не смог заставить его работать, но мне что-то не хватает.
Придется добавлять / удалять IP-адреса в контейнерах в ответ на поступающие сервисы.
и собираюсь, но я не мог заставить работать "лишние" IP-адреса в контейнере (это могло
ping, но не TCP или UDP, не знаю почему).

Мне придется когда-нибудь попробовать еще раз.

В вс, 17 января 2016 г., 22:22, Микаэль Клюсо [email protected]
написал:

18.01.2016 16:18 Микаэль Клюзо написал:

Я полагаю, что даже специально созданная SDN должна что-то отслеживать.
Может быть, решения на основе этикеток вроде MPLS ..?

В идее маркировки вещей ... если мы назначим один IP для каждой службы + один
IP для каждой конечной точки (пара сервис + модуль) и добавьте эти IP-адреса конечной точки в
pods, он должен работать полностью без сохранения состояния:

`` `` `

  • Внешний для хоста: {from: clientIP: clientPort, to: externalIP: servicePort}
    ----- [ELB
    выбирает одну конечную точку] --------> {from: clientIP: clientPort, to:
    endpointServiceIP: podPort} -> маршрут к хосту
  • От хоста к поду: {from: clientIP: clientPort, to: endpointServiceIP: podPort}
    - [стандарт
    маршрутизация к контейнерам] -> {from: clientIP: clientPort , to:
    конечная точка ServiceIP: podPort }

  • Под на хост: {from: endpointServiceIP: podPort, to: clientIP: clientPort}
    -------- [стандартная маршрутизация к маршрутизаторам] -----> {от:
    endpointServiceIP: podPort, to: clientIP: clientPort} - Хост для
    external: {from: endpointServiceIP: podPort, to: clientIP: clientPort}
    -------- [ELB
    SNAT назад] ------------------> {from: clientIP: clientPort , to:
    e xternalIP: servicePort } ``

Думаю, мы можем сделать это и для IP-адресов кластера.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment-172438133
.

`` `` `

Я пытаюсь на своей стороне что-то получить (с чистыми netns на моем локальном хосте
теперь).

Я пробую подход, в котором я влияю на диапазоны IP-адресов служб для хостов,
уменьшить количество записей маршрутизации:

cli - elb - h1 - c1

| `--- c2

`--- h2 - c2

h1_ep_ip_ranges = (10.1.1.0/24 10.1.2.0/24)
h2_ep_ip_ranges = (10.1.3.0/24)

Нет ping ATM (пакеты не проходят через цепочку PREROUTING ...), и
нужно спать. Подробнее об этом завтра;)

18.01.2016 18:28 Тим Хокин написал:

Я не могу заставить это работать на GCE, и я не уверен в AWS - есть
доступно ограниченное количество статических маршрутов.

Интересно, смогу ли я сделать это, объединив 2 диапазона IP в один
маршрут. Приходится тратить много IP-адресов, но я думаю, это имеет значение только для UDP.
Придется попробовать.

Изменить: я попробовал это и не смог заставить его работать, но мне что-то не хватает.
Придется добавлять / удалять IP-адреса в контейнерах в ответ на поступающие сервисы.
и собираюсь, но я не мог заставить работать "лишние" IP-адреса в контейнере (это могло
ping, но не TCP или UDP, не знаю почему).

Мне придется когда-нибудь попробовать еще раз.

Я прошел немного дальше, но кое-что, что я должен был предвидеть, произошло.

Я установил модуль с 10.244.2.8/25 в качестве основного интерфейса и 10.244.2.250/25
в качестве интерфейса «в процессе эксплуатации». Я надеялся, что смогу отправить UDP на
.250 и обнаруживать ответы, чтобы SNAT им. Но, конечно, если клиент
не в том же / 25 (что не может быть) срабатывает маршрут по умолчанию, который
происходит с адреса .8. tcpdump подтверждает, что ответы поступают из .8
при использовании UDP.

Я снова нахожусь в том месте, где не знаю, как заставить его работать. подумаю
подробнее об этом.

В пн, 18 января 2016 г., в 2:59, Микаэль Клюзо [email protected]
написал:

Я пытаюсь на своей стороне что-то получить (с чистыми netns на моем локальном хосте
теперь).

Я пробую подход, в котором я влияю на диапазоны IP-адресов служб для хостов,
уменьшить количество записей маршрутизации:

cli - elb - h1 - c1

| `--- c2

`--- h2 - c2

h1_ep_ip_ranges = (10.1.1.0/24 10.1.2.0/24)
h2_ep_ip_ranges = (10.1.3.0/24)

Нет ping ATM (пакеты не проходят через цепочку PREROUTING ...), и
нужно спать. Подробнее об этом завтра;)

18.01.2016 18:28 Тим Хокин написал:

Я не могу заставить это работать на GCE, и я не уверен в AWS - есть
доступно ограниченное количество статических маршрутов.

Интересно, смогу ли я сделать это, объединив 2 диапазона IP в один
Один
маршрут. Приходится тратить много IP-адресов, но я думаю, это имеет значение только для UDP.
Придется попробовать.

Изменить: я попробовал и не смог заставить его работать, но мне не хватает
что-то.
Придется добавлять / удалять IP-адреса в контейнерах в ответ на поступающие сервисы.
и собираюсь, но я не мог заставить работать "лишние" IP-адреса в контейнере (это могло
ping, но не TCP или UDP, не знаю почему).

Мне придется когда-нибудь попробовать еще раз.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172497456
.

До меня доходит (через Абхишека), что даже если это сработает, мы все еще должны
трек где-то течет, так что в любом случае это не апатрид.

В понедельник, 18 января 2016 г., в 21:50 Тим Хокин [email protected] написал:

Я прошел немного дальше, но кое-что, что я должен был предвидеть, произошло.

Я установил модуль с 10.244.2.8/25 в качестве основного интерфейса и
10.244.2.250/25 в качестве интерфейса «в рабочем состоянии». Я надеялся, что я
может отправлять UDP на .250 и обнаруживать ответы, чтобы их SNAT. Но конечно,
если клиент не находится в том же / 25 (что не может быть) по умолчанию
начинает действовать route, который исходит из адреса .8. tcpdump подтверждает, что
ответы приходят из .8 при использовании UDP.

Я снова нахожусь в том месте, где не знаю, как заставить его работать. подумаю
подробнее об этом.

В пн, 18 января 2016 г., в 2:59, Микаэль Клюзо [email protected]
написал:

Я пытаюсь на своей стороне что-то получить (с чистыми netns на моем локальном хосте
теперь).

Я пробую подход, в котором я влияю на диапазоны IP-адресов служб для хостов,
уменьшить количество записей маршрутизации:

cli - elb - h1 - c1

| `--- c2

`--- h2 - c2

h1_ep_ip_ranges = (10.1.1.0/24 10.1.2.0/24)
h2_ep_ip_ranges = (10.1.3.0/24)

Нет ping ATM (пакеты не проходят через цепочку PREROUTING ...), и
нужно спать. Подробнее об этом завтра;)

18.01.2016 18:28 Тим Хокин написал:

Я не могу заставить это работать на GCE, и я не уверен в AWS - есть
доступно ограниченное количество статических маршрутов.

Интересно, смогу ли я сделать это, объединив 2 диапазона IP в один
Один
маршрут. Приходится тратить много IP-адресов, но я думаю, это имеет значение только для UDP.
Придется попробовать.

Изменить: я попробовал и не смог заставить его работать, но мне не хватает
что-то.
Придется добавлять / удалять IP-адреса в контейнерах в ответ на сервисы
приходящий
и собираюсь, но я не мог заставить работать "лишние" IP в контейнере (это
мог
ping, но не TCP или UDP, не знаю почему).

Мне придется когда-нибудь попробовать еще раз.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172497456
.

Это прискорбно :-( Не знаю, кстати, почему. Тогда я попробую что-нибудь с MPLS, я все равно хочу этому научиться.

Если у вас есть 2 серверных модуля для обслуживания, и вы хотите отправить более одного
пакет, вам нужно каким-то образом отслеживать потоки, не так ли? Или вы
предполагая, что распылять пакеты на разных серверах безопасно?

В среду, 20 января 2016 г., в 12:24, Микаэль Клюзо [email protected]
написал:

Это прискорбно :-( кстати не знаю почему. Я попробую что-нибудь с
Итак, MPLS, я все равно хочу его изучить.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -173348973
.

Я как бы предположил, что для рабочих нагрузок UDP - да. Также может быть необязательным переход без сохранения состояния даже для UDP. @qoke есть какие-нибудь комментарии по этому поводу?

Кроме того, мы могли бы использовать такие вещи, как хеширование IP-адресов клиента, чтобы сделать поток более стабильным, но при этом сбалансированным (я не знаю, можно ли это назвать «своего рода отслеживанием» :-)).

@MikaelCluseau мы используем поведение IPVS по умолчанию, которое делает очень легкую "липкость" UDP ...

Для планирования дейтаграмм UDP балансировщик нагрузки IPVS записывает расписание дейтаграмм UDP с настраиваемым тайм-аутом, а тайм-аут UDP по умолчанию составляет 300 секунд. Перед тайм-аутом UDP-соединения все дейтаграммы UDP из одного и того же сокета (протокол, IP-адрес и порт) будут направлены на один и тот же сервер.

- Цитируется с http://kb.linuxvirtualserver.org/wiki/IPVS.

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

Мы балансируем нагрузку на большой трафик DNS и RADIUS - DNS обычно попадает в первую категорию (много клиентов или клиентов с большим количеством исходных портов), а RADIUS обычно попадает в более позднюю категорию (несколько клиентов, много пакетов, все из тот же IP / порт). Вместо того, чтобы использовать хэш без сохранения состояния для RADIUS, мы вместо этого решили рандомизировать исходные порты, чтобы получить равномерное распределение.

Прочитав всю ветку, я все еще не могу понять, должна ли активация режима iptables для kube-proxy решить проблему скрытия внешних IP-адресов (# 10921) или нет. Мы включили режим iptables с v1.1, как предлагается здесь, но мы все еще видим IP-адреса из кластера, а не настоящие от пользователей.

Наш кластер находится в GCE, и нам просто нужен балансировщик нагрузки с поддержкой HTTPS, прежде чем мы начнем работать. Поскольку GCE не поддерживает альфа-версию 1.2, мы не можем использовать новый Ingress (который AFAIK поддерживает балансировщики нагрузки HTTPS), поэтому Network Load Balancer - наш единственный вариант. Но очевидно, что мы не можем работать без возможности регистрации реальных IP-адресов наших пользователей.

Были бы признательны за некоторые разъяснения по этому поводу для новых пользователей. Для многих из нас поддержка HTTPS является обязательной. Спасибо!

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

Мы до сих пор обошли эту проблему, запустив наш интерфейсный прокси-сервер HTTP / HTTPS, работающий в режиме сети хоста, чтобы он видел исходный IP-адрес.

@maclof благодарит за отзыв. Не могли бы вы поделиться дополнительной информацией о своем обходном пути? Что вы имеете в виду под своим HTTP / HTTPS, работающим в хост-сети?

@javiercr мы используем спецификацию модуля примерно так: http://pastie.org/private/zpdelblsob654zif7xus5g

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

Это означает, что когда наш сервер nginx привязывается к порту 80/443, он будет прослушивать IP-адрес хоста и видеть исходные IP-адреса.

Я использую kubernetes 1.1, /opt/bin/kube-proxy ... --proxy-mode=iptables --masquerade-all=false и маршрутизирую IP-сеть cluser через хост, имеющий kube-proxy. В этой настройке мои службы видят внешний IP-адрес. Я использую высокодоступное сетевое пространство имен, у которого есть внешний IP-адрес и маршрут к хостам:

I0221 01:20:32.695440       1 main.go:224] <A6GSXEKN> Connection from 202.22.xxx.yyy:51954 closed.

Я многому научился, читая эту ветку!

В качестве справки в этом документе говорится, что AWS ELB использует циклический перебор для TCP-подключений и наименьшее количество подключений для http / https: http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/how-elb-works.html# запрос- маршрутизация

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

Что касается работы с балансировщиком нагрузки, который не поддерживает взвешивание, вы можете решить эту проблему с помощью своего контроллера репликации, пытаясь всегда поддерживать одинаковое количество модулей на узле (если их больше 1 на узел), а затем равномерно распределять их между их, даже если это означает, что в определенных ситуациях придется перемещать модули с узла и разрешать только определенное количество реплик. например, для 4-узлового кластера со службой, подключенной к балансировщику нагрузки, единственное количество приемлемых реплик пода будет 1,2,3,4,6,8,9,12,16,20 и т. д.

Мы также ищем решение, чтобы трафик направлялся только к локальным модулям. Я был бы в порядке, если бы узел nodeport уходил на узел в то время, когда локально не присутствуют поды для службы. Таким образом, простая проверка работоспособности TCP балансировщика нагрузки предотвратит поступление запросов на эти узлы. Я думаю, что если мы сможем решить эту проблему, по крайней мере, в части iptables \ kube-proxy, то мы узнаем, каковы будут последствия для балансировки нагрузки, когда модули не сбалансированы по кластеру. Я думаю, что есть способы решить эту проблему с балансировщиками нагрузки без необходимости устанавливать вес для каждого узла с вызовом API.

Балансировщики нагрузки уже справляются с этим с помощью других динамических методов. Кроме того, в зависимости от того, что служба, которую вы используете, на самом деле делает внутри этого контейнера для каждого вызова API, она может быть не в состоянии поддерживать двукратный трафик, когда на узле 2 модуля по сравнению с одним в любом случае. Если установлены ограничения Kubernetes и если на подузле достигнуты максимальные уровни использования, это тоже может сыграть роль, что добавляет еще один уровень сложности к поиску правильной настройки веса на внешнем балансировщике нагрузки.

Я бы сказал, держитесь подальше от этого уровня сложности и не пытайтесь установить вес балансировщика нагрузки из кубернетов.

@yoshiwaan Могу я предложить открыть новую проблему для предложения о межузловом трафике, поскольку эта проблема теперь закрыта. Лично я считаю, что первым шагом было бы убедиться, что _ если_ модуль запущен на локальном узле, мы направляем его на локальный модуль. Я подозреваю, что этого будет достаточно, потому что вы можете масштабировать свой RC так, чтобы на каждом узле были поды.

@justinsb +1, также мы сейчас

Это могло быть слишком наивно, но мне было интересно, в чем разница между режимом пользовательского пространства и iptables? Я не могу точно сказать из пользовательского документа .

Пользовательский режим означает, что kube-proxy сам обрабатывает соединения, получая запрос на соединение от клиента и открывая сокет для сервера, который (1) потребляет гораздо больше ЦП и памяти и (2) ограничен количеством портов, которые может открытый (<65k). Режим iptables работает на более низком уровне в ядре и вместо этого использует отслеживание соединений, поэтому он намного легче и обрабатывает намного больше соединений *.

(править) (*) Пока вы не проходите пакеты SNAT, что, в свою очередь, требует настройки, при которой вы уверены, что пакеты будут пересекать правила отслеживания соединений, связанные с ними. Например, использование схемы маршрутизированного доступа позволяет избежать SNAT, что означает, что конечная точка службы будет видеть IP-адрес реального клиента.

@MikaelCluseau
Это означает, что kube-proxy отвечает только за настройку и поддержание правил iptables, и мы больше не получаем случайный локальный порт для каждой службы в режиме iptables, верно?

19.04.2016, 22:51, Эмма написала:

это означает, что kube-proxy отвечает только за настройку и поддержку
iptables, и мы больше не получаем случайный локальный порт для каждой службы в
режим iptables, верно?

да.

Извините, но я совершенно пропустил это раньше.

(править) (*) Пока вы не проходите пакеты SNAT, что, в свою очередь, требует настройки, при которой вы уверены, что пакеты будут пересекать правила отслеживания соединений, связанные с ними. Например, использование схемы маршрутизированного доступа позволяет избежать SNAT, что означает, что конечная точка службы будет видеть IP-адрес реального клиента.

@MikaelCluseau Я думал, что iptables принимает SNAT и DNAT, что, по вашему мнению, не так. Не могли бы вы прояснить это для меня?

20.04.2016 13:59, Эмма Он написал:

@MikaelCluseau https://github.com/MikaelCluseau Я думал
iptables использует SNAT и DNAT, что, по вашему мнению, не так.
Не могли бы вы прояснить это для меня?

Это сложная часть.

(1) Для использования служебных / внешних IP-адресов требуется DNAT.
(2) Если вы уверены, что ответные пакеты будут проходить через один и тот же conntrack
(например, тот же сетевой стек или реплицированная таблица conntrack), вы
можно пропустить часть SNAT (т.е. правила MASQUERADE).

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

Например, учитывая

  • клиент 1.0.1.1,
  • сервис 1.0.2.1,
  • модуль, реализующий службу 1.0.3.1.

Потом,

  1. Ваш маршрутизатор / брандмауэр / балансировщик нагрузки / хост / все, что получает пакет
    для сервиса, чтобы он видел пакет «1.0.1.1 -> 1.0.2.1»;
  2. Он отправляет его через DNAT в конечную точку (модуль), поэтому пакет будет «1.0.1.1 ->
    1.0.3.1 »в кластерной сети;
  3. Под отвечает пакетом «1.0.3.1 -> 1.0.1.1»;
  4. Пакет проходит через маршрутизатор / брандмауэр / балансировщик нагрузки / хост / что угодно
    имея правило conntrack, система conntrack перезаписывает пакет
    на "1.0.2.1 -> 1.0.1.1" перед отправкой обратно клиенту.

Если условие (2) не может быть выполнено, вы должны использовать SNAT / MASQUERADING.
чтобы быть уверенным, что пакет вернется через
маршрутизатор / брандмауэр / балансировщик нагрузки / хост / что угодно.

@MikaelCluseau -
что-то для тебя

Во вторник, 19 апреля 2016 г., в 20:20, Микаэль Клюсо [email protected]
написал:

20.04.2016 13:59, Эмма Он написал:

@MikaelCluseau https://github.com/MikaelCluseau Я думал
iptables использует SNAT и DNAT, что, по вашему мнению, не так.
Не могли бы вы прояснить это для меня?

Это сложная часть.

(1) Для использования служебных / внешних IP-адресов требуется DNAT.
(2) Если вы уверены, что ответные пакеты будут проходить через один и тот же conntrack
(например, тот же сетевой стек или реплицированная таблица conntrack), вы
можно пропустить часть SNAT (т.е. правила MASQUERADE).

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

Например, учитывая

  • клиент 1.0.1.1,
  • сервис 1.0.2.1,
  • модуль, реализующий службу 1.0.3.1.

Потом,

  1. Ваш маршрутизатор / брандмауэр / балансировщик нагрузки / хост / все, что получает пакет
    для сервиса, чтобы он видел пакет «1.0.1.1 -> 1.0.2.1»;
  2. Он отправляет его через DNAT в конечную точку (модуль), поэтому пакет будет «1.0.1.1 ->
    1.0.3.1 »в кластерной сети;
  3. Под отвечает пакетом «1.0.3.1 -> 1.0.1.1»;
  4. Пакет проходит через маршрутизатор / брандмауэр / балансировщик нагрузки / хост / что угодно
    имея правило conntrack, система conntrack перезаписывает пакет
    на "1.0.2.1 -> 1.0.1.1" перед отправкой обратно клиенту.

Если условие (2) не может быть выполнено, вы должны использовать SNAT / MASQUERADING.
чтобы быть уверенным, что пакет вернется через
маршрутизатор / брандмауэр / балансировщик нагрузки / хост / что угодно.

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -212230959

@justinsb @yoshiwaan Кто-нибудь когда-нибудь создавал для этого проблему? Моя поисковая фу меня подводит, и у меня есть аналогичная потребность.

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

Я сам не поднимал

Ааааааааааааааааааааааааааааааааааааааааааааааачалаваетсядаетдаетдаетваетсяваетсяваетсяировка, что это особенность / исправление: https://github.com/kubernetes/features/issues/27

Похоже на бета-версию 1.5.x.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги