1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/kubewharf-kubegateway

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
design.md 20 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 26.11.2024 19:04 de3ef5f

Дизайн-документ

Имена и определения

Имя Значение
Upstream APIServer Все APIServer, которые проксируются KubeGateway, называются Upstream APIServer.
Upstream Cluster Группа из нескольких APIServer называется Upstream Cluster.
Endpoint Адрес одного Upstream APIServer в формате schema://host:port, например https://192.168.0.1:6443.
impersonate Это особый механизм, предоставляемый Kubernetes APIServer, который позволяет одному пользователю имитировать другого для выполнения запросов.

Архитектура
В архитектуре выделяются два уровня:

  • Контрольный уровень: полная логическая цепочка kube-apiserver, которая предоставляет проксирование кластера и маршрутизацию CRUD-операций.
  • Прокси: проксирует трафик к upstream cluster, обеспечивает частичную аутентификацию и авторизацию, предоставляет гибкие правила маршрутизации и ограничения трафика.

Контрольный уровень архитектуры
На контрольном уровне kubeGateway эквивалентен полному kube-apiserver:

  1. Имеет полноценную аутентификацию и авторизацию.
  2. Предоставляет операции CRUD для управления ресурсами контрольного уровня.
  3. Поддерживает операции list/watch, что позволяет использовать client-go для настройки изменений без дополнительного SDK.

Прокси-уровень архитектуры
После аутентификации на прокси-уровне запрос направляется на соответствующий upstream kube-apiserver через следующие шаги:

  • Определение информации о пользователе запроса, при необходимости — проверка авторизации.
  • Маршрутизация запроса к соответствующему upstream kube-apiserver.
  • Управление трафиком: определение необходимости ограничения трафика и выбор подходящего upstream kube-apiserver с использованием алгоритма балансировки нагрузки RoundRobin.
  • Отправка запроса через предварительно созданный HTTP2-канал к backend kube-apiserver.

Детали контрольного уровня
API

// UpstreamClusterSpec определяет желаемое состояние UpstreamCluster.
type UpstreamClusterSpec struct {
    // Servers содержит группу upstream api серверов.
    Servers []UpstreamClusterServer `json:"servers,omitempty" protobuf:"bytes,1,rep,name=servers"`

    // Client connection config для upstream api серверов.
    ClientConfig ClientConfig `json:"clientConfig,omitempty" protobuf:"bytes,2,opt,name=clientConfig"`

    // Secures serving config для upstream кластера.
    SecureServing SecureServing `json:"secureServing,omitempty" protobuf:"bytes,3,opt,name=secureServing"`

    // Клиентские настройки управления потоком, например qps и burst.
    FlowControl FlowControl `json:"flowControl,omitempty" protobuf:"bytes,4,opt,name=flowControl"`

    // DispatchPolicies описывает, как направлять запросы к upsteams.
    // Будет соответствовать только одна политика диспетчеризации.
    // Маршрутизатор будет следовать порядку DispatchPolicies, то есть предыдущая политика имеет более высокий приоритет.
    DispatchPolicies []DispatchPolicy `json:"dispatchPolicies,omitempty" protobuf:"bytes,5,rep,name=dispatchPolicies"`
}

Мы разработали ресурс UpstreamCluster для представления кластера, который должен быть проксирован KubeGateway. Он включает в себя:

  • Список backend кластеров.
  • Информацию о клиенте KubeGateway для доступа к backend кластерам.
  • Сертификаты сервера и CA для обеспечения динамического SNI.
  • Настройки управления трафиком.
  • Правила маршрутизации.

Дополнительные сведения об API см. по ссылке TODO.

Разрешения ClientConfig
При настройке clientConfig для upstream cluster необходимо предоставить kube-gateway достаточные разрешения для нормальной работы. Основные действия kube-gateway включают:

  • Проверка работоспособности.
  • Запросы аутентификации (TokenReview) и авторизации (SubjectReview).
  • Запрос к upstream с олицетворением другого пользователя.

Поэтому минимальные необходимые разрешения:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kube-gateway
rules:
- apiGroups: [""]
  resources: ["users", "groups", "serviceaccounts"]
  verbs: ["impersonate"]
# Может устанавливать заголовки "Impersonate-Extra-scopes" и "Impersonate-Uid".
- apiGroups: ["authentication.k8s.io"]
  resources: ["userextras/scopes", "uids"]
  verbs: ["impersonate"]
- apiGroups: ["authentication.k8s.io"]
  resources: ["tokenreviews", subjectaccessreviews]
  verbs: ["create"]
- nonResourceURLs: ["/healthz*", "/readyz*", "/livez*"]
  verbs: ["get"]

Затем связать с пользователем kube-gateway:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kube-gateway
subjects:
- kind: User
  name: kube-gateway # Это должно быть имя вашего клиента config user.
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: kube-gateway
  apiGroup: rbac.authorization.kio

Управление трафиком
Предоставляются три метода управления трафиком:

  • Exempt: не ограничивает.
  • MaxRequestsInflight: ограничивает максимальное количество одновременных запросов, которое отличается от qps и представляет собой максимальное количество ожидающих обработки запросов.
  • TokenBucket: использует токены для ограничения количества запросов и допускает всплески. Перевод текста:
json:"strategy,omitempty" protobuf:"bytes,1,opt,name=strategy,casttype=Strategy"
// UpsteamSubset указывает на список восходящих конечных точек. Пустой набор
// означает использование всех восходящих потоков
// +optional
UpsteamSubset []string `json:"upsteamSubset,omitempty" protobuf:"bytes,2,rep,name=upsteamSubset"`
// Rules содержит все DispatchPolicyRules для этой политики
// Gateway сопоставляет правила в соответствии с порядком списка, предыдущие правила
// имеют более высокий приоритет
// +optional
Rules []DispatchPolicyRule `json:"rules,omitempty" protobuf:"bytes,3,rep,name=rules"`
// FlowControlSchemaName указывает, к какой схеме управления потоком в spec.FlowControl будет
// применяться эта политика
// Если не установлено, ограничения нет
FlowControlSchemaName string `json:"flowControlSchemaName,omitempty" protobuf:"bytes,4,opt,name=flowControlSchemaName"`
}
  • Правила — это маршрутизирующие правила, использующие синтаксис, аналогичный PolicyRule в rbac.
  • Стратегия определяет, какую стратегию следует использовать после попадания в эту политику для выбора одной из восходящих линий. В настоящее время предоставляется только RoundRobin.
  • UpstreamSubset если пусто, то после попадания в эту политику выбор конечной точки будет осуществляться из всех серверов, иначе — из этого подмножества.
  • FlowControlSchemaName означает, что эта политика должна следовать правилам flowControlSchema.

Маршрутизация API правил соответствия выглядит следующим образом: каждое поле связано отношением «и», а несколько PolicyRule связаны отношением «или».

// DispatchPolicyRule содержит информацию, описывающую правило политики
type DispatchPolicyRule struct {
     // Verbs — это список глаголов, которые применяются ко всем видам ресурсов и ограничениям атрибутов, содержащимся в этом правиле.
    // - «*» представляет все глаголы.
    // - пустой набор означает, что ничего не разрешено.
    // - используйте префикс «-», чтобы инвертировать соответствие глаголов, например, «-get» означает соответствие всем глаголам, кроме «get».
    Verbs []string `json:"verbs,omitempty" protobuf:"bytes,1,rep,name=verbs"`

    // APIGroups — это имя группы API, которая содержит ресурсы. Если указано несколько групп API, любое действие, запрошенное для одного из перечисленных ресурсов в любой группе API, будет разрешено.
    // - «*» представляет все группы API.
    // - пустой набор означает, что ничего не разрешено.
    // - используйте префикс «-», чтобы инвертировать совпадение apiGroups, например, «-apps» означает совпадение всех apiGroups, кроме «apps».
    APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,2,rep,name=apiGroups"`

    // Resources — это список ресурсов, к которым применяется это правило.
    // - «*» представляет все ресурсы.
    // - пустой набор означает, что ничего не разрешено.
    // - используйте «{resource}/{subresource}», чтобы соответствовать одному субресурсу ресурса.
    // - используйте «*/{subresource}», чтобы сопоставить все субресурсы ресурсов, но «{resource}/*» не допускается.
    // - используйте префикс «-», чтобы инвертировать сопоставление ресурсов, например, «-deployments» означает сопоставление всех ресурсов, кроме «deployments».
    Resources []string `json:"resources,omitempty" protobuf:"bytes,3,rep,name=resources"`

    // ResourceNames — это необязательный белый список имён, к которому применяется правило.
    // - «*» представляет все ResourceNames.
    // - пустой набор означает, что всё разрешено.
    // - используйте префикс «-», чтобы инвертировать сопоставление resourceNames, например, «-nginx» означает сопоставление всех resourceNames, кроме «nginx».
    // +optional
    ResourceNames []string `json:"resourceNames,omitempty" protobuf:"bytes,4,rep,name=resourceNames"`

    // Users — это список пользователей, к которым применяется данное правило.
    // - «*» представляет всех пользователей.
    // - если ServiceAccounts пуст, пустой набор означает, что всё разрешено, в противном случае это означает, что ничто не разрешено.
    // используйте префикс «-», чтобы инвертировать сопоставление пользователей, например, «-admin» означает сопоставление всех пользователей, кроме «admin».
    // +optional
    Users []string `json:"users,omitempty" protobuf:"bytes,5,rep,name=users"`

    // ServiceAccounts — это список serviceAccont пользователей, к которым применяется это правило. Его можно покрыть, если Users соответствует всему.
    // - ServiceAccounts не может использовать инвертированное сопоставление
    // - если Users пуст, пустой набор означает, что ничего не разрешено, в противном случае это означает, что ничто не разрешено.
    // - имя и пространство имён serviceAccount должны быть установлены
    // +optional
    ServiceAccounts []ServiceAccountRef `json:"serviceAccounts,omitempty" protobuf:"bytes,6,rep,name=serviceAccounts"`

    // UserGroups — это список групп пользователей... **Правило определяет основные правила для каждого поля:**

| Поле | Обязательное для запросов ресурсов | Обязательное для не-ресурсных запросов | Поддержка инвертирования | Поддержка «*» для выбора всех элементов | Другие условия |
| --- | --- | --- | --- | --- | --- |
| verbs | Да | Да | Да | Да | Соответствие HTTP метода и verbs |
| apiGroups | Да | Нет | Да | Да |  |
| resources | Да | Нет | Да | Да | Использование {resource}/{subresource} для обозначения подресурса определённого ресурса. Использование */{subresource} для обозначения всех подресурсов всех ресурсов. Не допускается использование {resource}/* для сопоставления всех подресурсов определённого ресурса |
| users | Нет | Нет | Да | Да | Если ServiceAccounts пуст, users пуст означает соответствие всем пользователям, в противном случае означает несоответствие всем пользователям |
| userGroups | Нет | Нет | Да | Да |  |
| serviceAcccounts | Нет | Нет | Нет | Нет | Когда Users пуст, ServiceAccounts пуст означает соответствие всем serviceAccounts, в противном случае означает несоответствие serviceAccountsserviceAccouts. Является специальным user+group, также может быть представлен непосредственно в users как имя пользователя serviceAccounts или сопоставлен с группой serviceAccounts в userGroups |
| nonResourceURLs | Нет | Да | Нет | Да | Поддерживает {path}/* в качестве префикса для сопоставления |

**Сопоставление всего**

Все сопоставляется с помощью подстановочного знака "*". При наличии подстановочных знаков, соответствующих всему, любые другие отдельные сопоставления игнорируются.

Например, можно сопоставить все операции над pods:

```YAML
...
spec:
  dispatchPolicies:
  - rules:
    - resources: ["pods"]
      apiGroups: ["*"]
      verbs: ["*"]```

Следует отметить, что в NonResourceURLs "*" можно использовать для сопоставления суффикса.

```YAML
...
spec:
  dispatchPolicies:
  - rules:
    - nonResourceURLs: ["/healthz", "/healthz/*"] # '*' in a nonResourceURL is a suffix glob match
      verbs: ["get", "post"]```

**Инвертирование**

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

Например, это правило соответствует всем запросам, кроме запросов к pods и deployments:

```YAML
...
spec:
  dispatchPolicies:
  - rules:
    - resources: ["-pods", "-deployments"]
      apiGroups: ["*"]
      verbs: ["*"]```

Вот пример неправильного использования, где в реальном процессе "-pods" будет проигнорировано, и это правило станет соответствовать всем запросам deployments:

```YAML
...
spec:
  dispatchPolicies:
  - rules:
    - resources: ["-pods", "deployments"]
      apiGroups: ["*"]
      verbs: ["*"]```

### Сходимость ссылок APIServer

Благодаря технологии олицетворения пользователей kube-gateway обращается к kube-apiserver с использованием фиксированного HTTP2-клиента, а прокси-сервер kube-gateway пересылает запросы и не теряет информацию о пользователе, поэтому он естественным образом может использовать возможности мультиплексирования HTTP2, то есть отправлять несколько запросов по одному TCP.

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

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/kubewharf-kubegateway.git
git@api.gitlife.ru:oschina-mirror/kubewharf-kubegateway.git
oschina-mirror
kubewharf-kubegateway
kubewharf-kubegateway
main