Стадия жизненного цикла модуля: General Availability
У модуля есть требования для установки

Внимание! При изменении сетевой конфигурации убедитесь, что cert-manager issuer и модуль Code используют один и тот же Ingress class.

  • Проверьте spec.network.ingressClass в CodeInstance.
  • Проверьте Ingress class в конфигурации cert-manager Issuer/ClusterIssuer.
  • После смены Ingress class при необходимости перевыпустите сертификаты.

Настройка работы Git SSH через порт 22

По умолчанию в кластере Deckhouse используется встроенный Ingress-контроллер — d8-ingress-nginx. Этот контроллер предоставляет доступ к веб-интерфейсу (UI) через стандартные порты HTTP (80) и HTTPS (443). Однако d8-ingress-nginx не поддерживает проксирование TCP-портов.

Для проксирования внешнего TCP-трафика через порт 22 (Git SSH) предусмотрена специальная опция в конфигурации модуля. При её использовании разворачивается Haproxy с сервисом типа LoadBalancer. Haproxy перенаправляет трафик с порта 22 на соответствующий Git SSH Pod. Порты 80 и 443 продолжают обрабатываться d8-ingress-nginx, где происходит терминация TLS-трафика.

Самоподписные сертификаты (сертификаты выпущенные внутренним УЦ)

Чтобы использовать самоподписные сертификаты в различных подключениях (HTTPS, rediss, SMTPS и т.д.), создайте secret или configmap в пространстве d8-code с необходимыми сертификатами и объявите в CR:

...
spec:
  network:
    certificates:
      customCAs:
       - secret: custom-tls-ca
         keys:
           - ca.crt
           - tls.crt
       - secret: more-custom-CAs
         keys:
           - custom-ca-1.crt
       - configMap: custom-CA-cm
       - configMap: more-custom-CAs-cm
         keys:
           - custom-ca-2.crt
           - custom-ca-3.crt
...

Настройка пользовательского сертификата для web UI

Чтобы использовать собственный TLS-сертификат для web endpoint, создайте TLS Secret в d8-code и укажите его в spec.network.web.https.

  1. Создайте TLS Secret в d8-code:
kubectl -n d8-code create secret generic code-web-tls \
    --from-file=tls.crt=tls.crt \
    --from-file=tls.key=tls.key \
    --from-file=ca.crt=ca.crt
  1. Настройте CodeInstance на использование этого Secret для web UI и добавьте сертификат в network.certificates.customCAs, чтобы распространить доверие на все контейнеры:
apiVersion: deckhouse.io/v1
kind: CodeInstance
metadata:
  name: code
spec:
  network:
    certificates:
      customCAs:
        - secret: code-web-tls
          keys:
            - tls.crt
    web:
      hostname: code.example.com
      https:
        mode: CustomCertificate
        customCertificate:
          secretName: code-web-tls

Secret должен быть в формате kubernetes.io/tls, а сертификат должен быть валиден для указанного hostname. Если сертификат выпущен приватным УЦ, предпочтительно указывать в customCAs сертификат/цепочку УЦ.

Настройка gzip сжатия

По умолчанию настройки наследуются из ресурса IngressNginxController, в котором заданы следующие значения по умолчанию:

  • gzip_comp_level 1
  • gzip_types application/atom+xml application/javascript application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/javascript text/plain text/x-component

Настроить сжатие можно с помощью ресурса IngressNginxController, задав соответствующие настройки в секции spec.config. Пример:

...
spec:
  config:
     gzip-level: "5"
     gzip-types: "font/opentype image/svg+xml image/x-icon text/css text/plain text/x-component"
...

Настройка ownLoadBalancer

Особенности использования опции ownLoadBalancer

Внимание! ownLoadBalancer НЕ ПОДДЕРЖИВАЕТ следующие режимы: HostPort, HostPortWithSSLPassthrough, HostPortWithProxyProtocol и HostWithFailover Режимы Ingress-nginx контроллера. Эти режимы относятся к способам приема трафика из внешней сети d8-ingress-nginx IngressNginxController . Если в кластере используется один из них, не включайте ownLoadBalancer.

  1. Отдельный IP-адрес: При активации опции ownLoadBalancer.enabled для модуля Code выделяется отдельный IP-адрес, отличный от основного IP-адреса Deckhouse. Для этого адреса необходимо создать отдельную DNS-запись. По этой DNS-записи будут доступны:

    • Веб-интерфейс (UI) на портах 80 и 443.
    • Git SSH на порту 22.
  2. Игнорирование параметров: При включении опции ownLoadBalancer.enabled следующие параметры игнорируются:

    • spec.network.gitSsh.hostname
    • spec.network.gitSsh.service.type
    • spec.network.gitSsh.service.nodePort

    Вместо этого сервис shell получает тип LoadBalancer, а Git SSH становится доступным по тому же домену, что и веб-сервис.

  3. Значение по умолчанию: ownLoadBalancer.enabled имеет значение true по умолчанию.

Настройка ownLoadBalancer.httpBackends

Используйте spec.network.ownLoadBalancer.httpBackends, чтобы явно указать, в какие экземпляры IngressNginxController HAProxy LoadBalancer модуля Code должен отправлять HTTP(S)-трафик.

  • Если список пустой, имена backend-сервисов рассчитываются автоматически на основе выбранного Ingress class.
  • Используйте этот параметр, если в кластере несколько ingress-контроллеров и нужно закрепить трафик Code за конкретными контроллерами.

Пример:

apiVersion: deckhouse.io/v1
kind: CodeInstance
metadata:
  name: code
spec:
  network:
    ownLoadBalancer:
      enabled: true
      httpBackends:
        - system-controller

Пример конфигурации

Ниже приведён пример включения Haproxy для проксирования Git SSH в CodeInstance:

apiVersion: deckhouse.io/v1
kind: CodeInstance
metadata:
  name: code
spec:
...
  network:
    ownLoadBalancer:
      enabled: true
...

Чеклист проверки

После применения изменений проверьте:

kubectl -n d8-code get svc shell webservice-default
  • У нужного сервиса(ов) назначен внешний IP LoadBalancer.
  • DNS A-запись указывает на этот внешний IP.
  • Доступ по Git SSH работает:
ssh -T git@<host> -p 22

Схема работы Haproxy

Haproxy внутри кластера Deckhouse работает по следующей схеме:

Istio service mesh

Модуль Code поддерживает работу в Istio service mesh. При включении оператор переводит всё внутреннее взаимодействие между компонентами Code с прикладного TLS на Istio mTLS (обеспечивается Envoy-сайдкарами). Оператор также создаёт ресурс PeerAuthentication для принудительного включения mTLS.

Включение Istio

Установите spec.network.istio.enabled в true в CodeInstance:

apiVersion: deckhouse.io/v1
kind: CodeInstance
metadata:
  name: code
spec:
  network:
    istio:
      enabled: true
      strict: true

Предварительные требования: должен быть установлен модуль Deckhouse Istio. Оператор управляет инъекцией сайдкаров на уровне подов через лейбл sidecar.istio.io/inject: "true" — namespace d8-code не нужно помечать лейблами для namespace-wide инъекции.

Режим Strict

При strict: true оператор:

  • Создаёт PeerAuthentication с STRICT режимом mTLS — plain text отклоняется на всех портах, кроме metrics (9090, 9254) и shell SSH (22, только при ownLoadBalancer.enabled=false).
  • Настраивает Ingress-аннотации для маршрутизации через Istio sidecar (service-upstream, upstream-vhost, backend-protocol: http) на всех Ingress-ресурсах (webservice, pages, registry).

Критическое требование: ingress-контроллер должен находиться в Istio mesh — установите IngressNginxController.spec.enableIstioSidecar=true. См. документацию Deckhouse: Включение Istio для приложений. Без этого веб-интерфейс, Pages и Registry будут недоступны, так как ingress-контроллер не сможет достучаться до сервисов по plain HTTP на порту 8181 (STRICT).

При strict: false (по умолчанию) оператор:

  • Создаёт PeerAuthentication с PERMISSIVE режимом mTLS — принимается и mTLS, и plain text на всех портах.
  • Настраивает Ingress-аннотации с service-upstream и backend-protocol: http (без upstream-vhost), что работает без ingress-контроллера в mesh.

Что делает оператор

При включении Istio оператор:

  1. Инъектирует сайдкары во все Pod’ы Code, добавляя лейбл sidecar.istio.io/inject: "true" и аннотацию proxy.istio.io/config: {"holdApplicationUntilProxyStarts":true}.
  2. Переключает внутренние URL на HTTP — компоненты общаются по plain HTTP; mTLS обеспечивается сайдкарами.
  3. Убирает прикладной TLS — внутренние TLS-сертификаты для webservice, Gitaly и Praefect не создаются.
  4. Создаёт PeerAuthentication с именем d8-code-istio-mtls в namespace d8-code:
    • STRICT режим mTLS для всех workload’ов Code (выбираются по лейблу app.kubernetes.io/managed-by=code-operator) — только при spec.network.istio.strict: true. При strict: false (по умолчанию) режим PERMISSIVE.
    • Исключения PERMISSIVE на портах, принимающих трафик вне mesh — см. ниже (эти исключения применяются только в STRICT режиме).

При выключении Istio оператор удаляет PeerAuthentication и восстанавливает прикладной TLS.

Порты в PERMISSIVE

Следующие порты настроены в PERMISSIVE, потому что они принимают трафик от источников вне Istio mesh, или от Pod DNS, для которых auto-mTLS не применяется:

Порт Компонент Причина
9090 Gitaly metrics Prometheus scraping (kube-rbac-proxy), обычно не в mesh
9254 webservice metrics Prometheus scraping (kube-rbac-proxy), обычно не в mesh
22 shell SSH Только приownLoadBalancer.enabled=false: shell Service типа LoadBalancer, внешний SSH-трафик идёт напрямую. При ownLoadBalancer.enabled=true (по умолчанию): HAProxy в mesh, трафик идёт HAProxy → shell через mTLS, порт в STRICT

Внимание! PERMISSIVE-порты принимают как mTLS (от mesh-workload’ов), так и plain text (от источников вне mesh). Это означает, что любой клиент с прямым доступом к этим портам (например, kubectl port-forward) может отправлять plain text-запросы без mTLS.

Важно! Порт 8181 (webservice workhorse) находится в режиме STRICT — но только при spec.network.istio.strict: true. Это означает, что ingress-контроллер (nginx) должен находиться в Istio mesh, либо использоваться Istio Ingress Gateway, для доступа к веб-интерфейсу. См. документацию Deckhouse: Включение Istio для приложений за инструкциями по включению инъекции сайдкаров для ingress-nginx.

Рекомендация: перевести ingress-контроллер в mesh

Порт 8181 (webservice workhorse) находится в режиме STRICT при spec.network.istio.strict: true — ingress-контроллер (nginx) должен находиться в Istio mesh для доступа к веб-интерфейсу. См. документацию Deckhouse: Включение Istio для приложений за инструкциями по включению инъекции сайдкаров для ingress-nginx.

Проверка

# Проверить, что PeerAuthentication создан
kubectl -n d8-code get peerauthentication d8-code-istio-mtls -o yaml

# Проверить, что сайдкары инъектированы
kubectl -n d8-code get pods -o jsonpath='{.items[0].spec.containers[*].name}'
# В списке должен быть "istio-proxy" рядом с app-контейнерами