Service.spec.externalIPs is deprecated upstream in Kubernetes v1.36 (KEP-5707, kubernetes#137293). The AllowServiceExternalIPs feature gate is expected to default to off around v1.40 and the implementation to be removed around v1.43. For bare-metal installs that rely on externalIPs today, cozystack needs a migration path. This change adds an opt-in 'loadBalancer' exposure mode for the ingress-nginx Service: - New platform value 'publishing.exposure' (enum: externalIPs | loadBalancer, default externalIPs). Plumbed through cozystack-values into each tenant's ingress HelmRelease via the new 'expose-mode' key. - Unknown values and loadBalancer with an empty externalIPs list fail the chart render with explicit error messages, rather than silently producing a broken Service. - When exposure=loadBalancer and the current namespace matches publishing.ingressName, the Service becomes type: LoadBalancer with externalTrafficPolicy: Local. - A new template renders a CiliumLoadBalancerIPPool whose blocks come from publishing.externalIPs (IPv4 addresses get /32, IPv6 addresses get /128) and whose serviceSelector uses Cilium's synthetic io.kubernetes.service.namespace key combined with the standard app.kubernetes.io/name: ingress-nginx label. No custom label is written to the Service itself, avoiding cross-tenant collisions from user-defined labels. Default behaviour is unchanged: without opting in, the Service is still ClusterIP + spec.externalIPs as today. Scope: only ingress-nginx is migrated by this setting. Other cozystack components that still write Service.spec.externalIPs directly (notably the vpn app) must be migrated separately before the v1.40 feature gate flip. Tests: packages/extra/ingress/tests/exposure_test.yaml adds 13 helm-unittest cases covering both modes, IPv4/IPv6, empty-token filtering, unknown-mode rejection, and the non-matching-namespace fallback. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la>
137 lines
5.1 KiB
YAML
137 lines
5.1 KiB
YAML
sourceRef:
|
|
kind: OCIRepository
|
|
name: cozystack-platform
|
|
namespace: cozy-system
|
|
path: /
|
|
migrations:
|
|
enabled: false
|
|
image: ghcr.io/cozystack/cozystack/platform-migrations:v1.3.0@sha256:555e4b76421361805a84bc9088b01b23a9c4a9430bd8ebd2db82ef9677d7008c
|
|
targetVersion: 39
|
|
# Bundle deployment configuration
|
|
bundles:
|
|
system:
|
|
enabled: false
|
|
variant: "isp-full" # Options: "isp-full", "isp-full-generic", "isp-hosted", "distro-full"
|
|
iaas:
|
|
enabled: false
|
|
paas:
|
|
enabled: false
|
|
naas:
|
|
enabled: false
|
|
disabledPackages: []
|
|
enabledPackages: []
|
|
# Network configuration
|
|
networking:
|
|
clusterDomain: "cozy.local"
|
|
podCIDR: "10.244.0.0/16"
|
|
podGateway: "10.244.0.1"
|
|
serviceCIDR: "10.96.0.0/16"
|
|
joinCIDR: "100.64.0.0/16"
|
|
# KubeOVN master nodes override (optional)
|
|
# By default, KubeOVN helm chart uses `lookup` to find control-plane nodes
|
|
# by label `node-role.kubernetes.io/control-plane`. On fresh clusters or
|
|
# during initial deployment, lookup may return empty results.
|
|
# Set this to comma-separated list of master node IPs to override.
|
|
kubeovn:
|
|
MASTER_NODES: ""
|
|
# Service publishing and ingress configuration
|
|
publishing:
|
|
host: "example.org"
|
|
ingressName: tenant-root
|
|
exposedServices:
|
|
- api
|
|
- dashboard
|
|
- vm-exportproxy
|
|
- cdi-uploadproxy
|
|
apiServerEndpoint: "" # example: "https://api.example.org"
|
|
externalIPs: []
|
|
# Exposure mode for the ingress-nginx Service. When "externalIPs" (current
|
|
# default) is selected, the Service is created as ClusterIP with
|
|
# Service.spec.externalIPs set from publishing.externalIPs. When
|
|
# "loadBalancer" is selected, the Service is type: LoadBalancer and a
|
|
# CiliumLoadBalancerIPPool makes those same addresses allocatable via LB IPAM.
|
|
#
|
|
# Service.spec.externalIPs is deprecated upstream in Kubernetes v1.36
|
|
# (KEP-5707). The AllowServiceExternalIPs feature gate is expected to default
|
|
# to false around v1.40 and the implementation removed around v1.43 — switch
|
|
# to "loadBalancer" before upgrading past v1.40.
|
|
#
|
|
# Caveats for the "loadBalancer" mode:
|
|
# - publishing.externalIPs must contain at least one non-empty address,
|
|
# otherwise the chart render fails with an explicit error (a LoadBalancer
|
|
# Service without a pool would sit in <pending> forever).
|
|
# - The ingress-nginx Service is created with externalTrafficPolicy: Local
|
|
# to preserve the client source IP. Traffic arriving on a node that does
|
|
# not host an ingress-nginx pod is dropped, so the external IP must be
|
|
# routed to a node that runs the ingress pod (floating IP / keepalived /
|
|
# upstream router / podAntiAffinity).
|
|
# - Cilium does NOT announce the IP on its own unless L2 announcements or
|
|
# BGP are enabled in the Cilium values (disabled by default in Cozystack).
|
|
# This mode assumes the operator already routes the externalIPs to a
|
|
# cluster node; enabling announcements is out of scope for this setting.
|
|
# - Switching this value on a running cluster causes the ingress-nginx
|
|
# Service to be recreated (the HelmRelease has upgrade.force: true and
|
|
# the Service kind changes between ClusterIP and LoadBalancer). Expect a
|
|
# brief interruption of ingress traffic during the flip.
|
|
#
|
|
# Scope: this setting only controls the ingress-nginx Service. Other
|
|
# cozystack components that currently write Service.spec.externalIPs directly
|
|
# (e.g. the vpn app at packages/apps/vpn/templates/service.yaml) are NOT
|
|
# migrated by flipping this value and must be addressed separately before
|
|
# the AllowServiceExternalIPs feature gate flips to off in ~v1.40.
|
|
exposure: externalIPs # "externalIPs" or "loadBalancer"
|
|
certificates:
|
|
solver: http01 # "http01" or "dns01"
|
|
issuerName: letsencrypt-prod
|
|
# Authentication configuration
|
|
authentication:
|
|
oidc:
|
|
enabled: false
|
|
insecureSkipVerify: false
|
|
keycloakExtraRedirectUri: ""
|
|
# Internal URL to access KeyCloak realm for backend-to-backend requests (bypasses external DNS).
|
|
# When set, oauth2-proxy uses --skip-oidc-discovery and routes all backend calls (token, jwks,
|
|
# userinfo, logout) through this URL while keeping browser redirects on the external URL.
|
|
# Example: http://keycloak-http.cozy-keycloak.svc:8080/realms/cozy
|
|
keycloakInternalUrl: ""
|
|
# Pod scheduling configuration
|
|
scheduling:
|
|
globalAppTopologySpreadConstraints: ""
|
|
# UI branding configuration
|
|
branding: {}
|
|
# Container registry mirrors configuration
|
|
#
|
|
# Example:
|
|
# registries:
|
|
# mirrors:
|
|
# docker.io:
|
|
# endpoints:
|
|
# - http://10.0.0.1:8082
|
|
# ghcr.io:
|
|
# endpoints:
|
|
# - http://10.0.0.1:8083
|
|
# gcr.io:
|
|
# endpoints:
|
|
# - http://10.0.0.1:8084
|
|
# registry.k8s.io:
|
|
# endpoints:
|
|
# - http://10.0.0.1:8085
|
|
# quay.io:
|
|
# endpoints:
|
|
# - http://10.0.0.1:8086
|
|
# cr.fluentbit.io:
|
|
# endpoints:
|
|
# - http://10.0.0.1:8087
|
|
# docker-registry3.mariadb.com:
|
|
# endpoints:
|
|
# - http://10.0.0.1:8088
|
|
# config:
|
|
# "10.0.0.1:8082":
|
|
# tls:
|
|
# insecureSkipVerify: true
|
|
registries: {}
|
|
# Resource allocation ratios
|
|
resources:
|
|
cpuAllocationRatio: 10
|
|
memoryAllocationRatio: 1
|
|
ephemeralStorageAllocationRatio: 40
|