Позвольте мне начать с резюмирования проблемы, которую мы пытаемся решить здесь.
Проблема в том, что у вас есть собственный кластер kubernetes, и вы хотите иметь возможность создать службу типа = LoadBalancer, и вы хотите, чтобы k8s создавал для вас LB с помощью externlIP и полностью автоматизированным способом, как если бы вы использовали GKE (кубернетес как сервисное решение).
Кроме того, я должен упомянуть, что я не очень разбираюсь в kubespray, поэтому я опишу только все шаги, которые необходимо сделать, чтобы заставить его работать, а остальное оставлю вам. Так что если вы хотите внести изменения в код kubespray, это ваша ответственность. Все тесты я проводил с кластером kubeadm, но применить его к kubespray не должно быть очень сложно.
Я начну с того, что резюмирую все, что нужно сделать, в 4 этапа:
- маркировка экземпляров
- включение функциональности облачного провайдера
- IAM и сервисные аккаунты
- Дополнительная информация
Пометка экземпляров Все экземпляры рабочих узлов в GCP должны быть помечены уникальным тегом, который является именем экземпляра; эти теги позже используются для создания правил брандмауэра и целевых списков для LB. Допустим, у вас есть экземпляр с именем worker-0; вам нужно пометить этот экземпляр тегом worker-0
В противном случае это приведет к ошибке (ее можно найти в журналах диспетчера контроллеров):
Error syncing load balancer: failed to ensure load balancer: no node tags supplied and also failed to parse the given lists of hosts for tags. Abort creating firewall rule
Включение функций облачного провайдера. K8s должен быть проинформирован о том, что он работает в облаке и что это за облачный провайдер, чтобы он знал, как взаимодействовать с API.
журналы диспетчера контроллеров, информирующие вас о том, что он не будет создавать LB.
WARNING: no cloud provider provided, services of type LoadBalancer will fail
Диспетчер контроллеров отвечает за создание LoadBalancer. Может быть передан флаг --cloud-provider
. Вы можете вручную добавить этот флаг в файл манифеста модуля диспетчера контроллеров; или, как в вашем случае, поскольку вы используете kubespray, вы можете добавить этот флаг где-нибудь в коде kubespray (возможно, он уже автоматизирован и просто требует, чтобы вы установили некоторый env или sth, но вам нужно выяснить это самостоятельно).
Вот как выглядит этот файл с флагом:
apiVersion: v1
kind: Pod
metadata:
labels:
component: kube-controller-manager
tier: control-plane
name: kube-controller-manager
namespace: kube-system
spec:
containers:
- command:
- kube-controller-manager
...
- --cloud-provider=gce # <----- HERE
Как видите, значение в нашем случае - gce
, что соответствует Google Compute Engine. Он сообщает k8s, что он работает на GCE / GCP.
Учетные записи IAM и службы. Теперь, когда ваш провайдер включен и теги покрыты, я расскажу об IAM и разрешениях.
Чтобы k8s мог создавать LB в GCE, ему необходимо разрешить это делать. Каждому экземпляру GCE назначена учетная запись глухой службы. Controller Manager использует учетную запись службы экземпляра, хранящуюся в метаданных экземпляра для доступа к GCP. API.
Для этого вам необходимо установить области доступа для экземпляра GCE (главный узел; тот, на котором запущен диспетчер контроллера), чтобы он мог использовать Cloud Engine API.
Области доступа - ›Настройка доступа для каждого API -› compute Engine = Чтение и запись
Для этого экземпляр должен быть остановлен, поэтому теперь остановите экземпляр. Эти области лучше установить во время создания экземпляра, чтобы вам не приходилось выполнять ненужные действия.
Вам также необходимо перейти на страницу IAM & Admin в консоли GCP и добавить разрешения, чтобы учетной записи службы главного экземпляра была назначена Kubernetes Engine Service Agent
роль. Это предопределенная роль, которая имеет гораздо больше разрешений, чем вам, вероятно, нужно, но я обнаружил, что все работает с этой ролью, поэтому я решил использовать ее в демонстрационных целях, но вы, вероятно, захотите использовать правило минимальных прав .
дополнительная информация. Я хочу упомянуть еще одну вещь. На вас это не влияет, но при тестировании я обнаружил интересную вещь.
Сначала я создал только один кластер узлов (единственный главный узел). Несмотря на то, что это разрешено с точки зрения k8s, диспетчер контроллеров не позволяет мне создавать LB и указывать его на главный узел, на котором выполнялось мое приложение. Отсюда следует вывод, что нельзя использовать LB только с главным узлом и необходимо создать хотя бы один рабочий узел.
PS Мне пришлось разобраться в этом на собственном горьком опыте; просматривая журналы, изменяя параметры и снова просматривая журналы, чтобы увидеть, решена ли проблема. Я не нашел ни одной статьи / страницы документации, где бы это было задокументировано в одном месте. Если вам удастся решить для себя, напишите ответ для других. Спасибо.
person
Matt
schedule
21.05.2021