Переход на Cilium Gateway
Не решен вопрос с CORS
Перед переходом на Cilium Gateway необходимо выполнить шаги, описанные тут. Здесь мы рассмотрим вариант для single node редакция Enterprise версия 2026.4.42. Для редакции Hub все намного сложнее и будет описано позже.
Из справки тут создаем gateway:
kubectl apply -n kube-system -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: cilium-gateway
spec:
gatewayClassName: cilium
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
- name: https
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: elma365-tls
allowedRoutes:
namespaces:
from: All
EOF
Нам не нужен 443, т.к. у нас используется reverse proxy, который выполняет все нужные активности в части HTTPS
Поэтому в упрощенному случае у нас будет:
kubectl apply -n kube-system -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: cilium-gateway
spec:
gatewayClassName: cilium
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
EOF
Должны получить:
gateway.gateway.networking.k8s.io/cilium-gateway created
Смотрим что на самом деле:
kubectl get gateway -A
Видим, что появился gateway:
NAMESPACE NAME CLASS ADDRESS PROGRAMMED AGE
kube-system cilium-gateway cilium True 71s
Смотрим что у нас с сервисами:
kubectl get svc -n kube-system
Видим что появился LoadBalancer, но он еще не настроен (а еще какой то новый сервис hubble-peer):
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cilium-gateway-cilium-gateway LoadBalancer 10.152.183.225 <pending> 80:30514/TCP 4m13s
ck-storage-rawfile-csi-controller ClusterIP None <none> <none> 189d
ck-storage-rawfile-csi-node ClusterIP 10.152.183.56 <none> 9100/TCP 189d
coredns ClusterIP 10.152.183.238 <none> 53/UDP,53/TCP 189d
hubble-peer ClusterIP 10.152.183.166 <none> 443/TCP 189d
metrics-server ClusterIP 10.152.183.180 <none> 443/TCP 189d
Возможно можно как то настроить NodePort для ситуации single node, но эту гипотезу мы тут не проверяем.
Так же load-balancer отключен по k8s status - его нужно включить:
k8s enable load-balancer
Должны получить:
Enabling load-balancer on the cluster. This may take a few seconds, please wait.
load-balancer enabled.
# k8s status
cluster status: ready
control plane nodes: 192.168.56.83:6400 (voter)
high availability: no
datastore: etcd
network: enabled
dns: enabled at 10.152.183.238
ingress: disabled
load-balancer: enabled, L2 mode
local-storage: enabled at /var/snap/k8s/common/rawfile-storage
gateway enabled
# kubectl get pod,svc -n metallb-system
NAME READY STATUS RESTARTS AGE
pod/metallb-controller-676c8f595c-5chlt 1/1 Running 0 2m6s
pod/metallb-speaker-t2x96 1/1 Running 0 2m6s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/metallb-webhook-service ClusterIP 10.152.183.39 <none> 443/TCP 2m7s
Неоходимо для нашего LoadBalancer назначить пул IP адресов (в нашем случае у нас single node и поэтому укажем только один):
Использовать IP нашего узла НЕЛЬЗЯ. Необходимо указать свободный адрес в вашей сети. (а может и можно)!
k8s set load-balancer.cidrs=192.168.56.73-192.168.56.73
Получилось:
Configuration updated.
# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cilium-gateway-cilium-gateway LoadBalancer 10.152.183.225 192.168.56.73 80:30514/TCP 86m
ck-storage-rawfile-csi-controller ClusterIP None <none> <none> 189d
ck-storage-rawfile-csi-node ClusterIP 10.152.183.56 <none> 9100/TCP 189d
coredns ClusterIP 10.152.183.238 <none> 53/UDP,53/TCP 189d
hubble-peer ClusterIP 10.152.183.166 <none> 443/TCP 189d
metrics-server ClusterIP 10.152.183.180 <none> 443/TCP 189d
Теперь переходим непосредственно к настройке ELMA365. Правим наш values-elma365.yaml. Отключаем Ingress и включаем Gateway API:
global:
gatewayAPI:
enabled: true
parentRefs:
- name: cilium-gateway
namespace: kube-system
ingress:
enabled: false
Устанавливаем (обновляем) чарт ELMA365 как это мы делаем стандартно (у каждого свой подход), но суть - применить наши изменения.
И тут начались танцы с бубном....
helm upgrade --install elma365 ./elma365 -f values-elma365.yaml --timeout=30m --debug --wait
Получили (причем тут istio вообще?):
level=DEBUG msg="number of dependencies in the chart" chart=messenger-vkteamsbot dependencies=0
level=DEBUG msg="number of dependencies in the chart" chart=messenger-whatsapp dependencies=0
level=DEBUG msg="number of dependencies in the chart" chart=postman dependencies=0
Error: unable to build kubernetes objects from release manifest: [resource mapping not found for name: "balancer-auth" namespace: "" from "": no matches for kind "AuthorizationPolicy" in version "security.istio.io/v1"
ensure CRDs are installed first, resource mapping not found for name: "main-body-size-limit" namespace: "istio-system" from "": no matches for kind "EnvoyFilter" in version "networking.istio.io/v1alpha3"
ensure CRDs are installed first]
Изучив ~/elma365/charts/balancer/values.yaml было обнаружено интересное значение workloadSelector, про которое ничего не сказано в оффициальной справке:
global:
gatewayAPI:
enabled: false
parentRefs:
- name: main-gateway
namespace: istio-system
workloadSelector:
gateway.istio.io/managed: istio.io-gateway-controller
annotations: {}
hosts: []
Заменили значение на
Смотрим ~/elma365/charts/balancer/templates/httproute.yaml а там захаркодено если включен gatewayAPI:
---
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: {{ template "balancer.name" . }}-auth
labels:
{{- include "balancer.labels" . | nindent 4 }}
spec:
selector:
matchLabels:
app: {{ template "balancer.name" . }}
action: DENY
rules:
- to:
- operation:
ports: ["{{ $servicePort }}"]
paths: ["/balancer*"]
when:
- key: request.headers[authorization]
values: ["*"]
Пробуем удалить (далее сделаем патч к дистрибутиву и пробуем установить снова ELMA365 - эта проблема ушла но осталась вторая:
level=DEBUG msg="number of dependencies in the chart" chart=textextractor dependencies=0
level=DEBUG msg="number of dependencies in the chart" chart=widget dependencies=0
Error: unable to build kubernetes objects from release manifest: resource mapping not found for name: "main-body-size-limit" namespace: "istio-system" from "": no matches for kind "EnvoyFilter" in version "networking.istio.io/v1alpha3"
ensure CRDs are installed first
Пробуем добавить отключение envoyFilter в нашей конфигурации, ведь мы никакой Envoy не устанавливали:
gatewayAPI:
enabled: true
# annotations: {}
parentRefs:
- name: cilium-gateway
namespace: kube-system
# timeoutSeconds: "300s"
# retries:
# attempts: 3
envoyFilter:
enabled: false
# namespace: "istio-system"
Установка пошла дальше! Ура! Ждем результат...
Все поднялось без ошибок. Смотрим какие у нас появились ресурсы HTTPRoute:
kubectl get httproute -A
Получили что то похожее:
NAMESPACE NAME HOSTNAMES AGE
default balancer ["d.rmg365.ru"] 9m33s
default fileprotection ["d.rmg365.ru"] 9m33s
default front ["d.rmg365.ru"] 9m33s
default hydra-adaptor ["d.rmg365.ru"] 9m33s
default main ["d.rmg365.ru"] 9m33s
default main-publicapi ["d.rmg365.ru"] 9m33s
default notifier ["d.rmg365.ru"] 9m33s
default notigate ["d.rmg365.ru"] 9m33s
default vahter ["d.rmg365.ru"] 9m33s
default web-forms ["d.rmg365.ru"] 9m33s
Перенастроили reverse proxy на наш новый адрес, что мы указали ранее для LB и вуаля:
Давайте попробуем все же обмануть LB и указать ему адрес хоста, чтобы не плодить у себя айпишники:
k8s set load-balancer.cidrs=192.168.56.83-192.168.56.83
Вроде не ругнулось даже:
Configuration updated.
# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cilium-gateway-cilium-gateway LoadBalancer 10.152.183.225 192.168.56.83 80:30514/TCP 158m
ck-storage-rawfile-csi-controller ClusterIP None <none> <none> 190d
ck-storage-rawfile-csi-node ClusterIP 10.152.183.56 <none> 9100/TCP 190d
coredns ClusterIP 10.152.183.238 <none> 53/UDP,53/TCP 190d
hubble-peer ClusterIP 10.152.183.166 <none> 443/TCP 190d
metrics-server ClusterIP 10.152.183.180 <none> 443/TCP 190d
Эксперимент прошел удачно и мы вернули настройки reverse proxy как было в случае Ingress.
Ну вот собственно и патч для 2026.4 (актуально для 2026.4.42, покка не исплавили) - balancer-httproute.patch.2026.4
--- elma365/charts/balancer/templates/httproute.yaml 2026-07-31 09:06:50.000000000 +0300
+++ ./httproute.yaml 2026-08-02 14:13:28.294230220 +0300
@@ -43,24 +43,4 @@
- name: {{ $serviceName }}
port: {{ $servicePort }}
{{- end }}
----
-apiVersion: security.istio.io/v1
-kind: AuthorizationPolicy
-metadata:
- name: {{ template "balancer.name" . }}-auth
- labels:
- {{- include "balancer.labels" . | nindent 4 }}
-spec:
- selector:
- matchLabels:
- app: {{ template "balancer.name" . }}
- action: DENY
- rules:
- - to:
- - operation:
- ports: ["{{ $servicePort }}"]
- paths: ["/balancer*"]
- when:
- - key: request.headers[authorization]
- values: ["*"]
{{- end }}
После загрузки нового дистро применяем патч:
patch elma365/charts/balancer/templates/httproute.yaml < balancer-httproute.patch.2026.4