Skip to content

Commit 307195d

Browse files
authored
Ingress Changes (#263)
* feat: implement Gateway API with HTTPRoute for ACME challenge and web traffic routing * refactor: restructure HTTPRoutes and ReferenceGrants for improved namespace management * bug: yaml error * refactor: update HTTPRoute to use internal-gateway for improved routing * feat: migrate from Istio VirtualServices to Gateway API HTTPRoutes with dual gateway access * bug: configmap script syntax * bug: configmap script syntax * bug: configmap script syntax * bug: virtual service * bug: virtual service * add: ingressclass * add: ingressclass * fix: update public IP retrieval in post-provision script to prefer DNS name
1 parent a66a2f6 commit 307195d

28 files changed

Lines changed: 662 additions & 211 deletions

charts/istio-certs/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Istio Certs Helm Chart
22

3-
This chart configures DNS labels for Azure Kubernetes Service (AKS) LoadBalancer IPs, enabling automatic FQDN assignment for OSDU services.
3+
This chart configures DNS labels for Azure Kubernetes Service (AKS) LoadBalancer IPs associated with Gateway API gateways, enabling automatic FQDN assignment for OSDU services with Let's Encrypt certificate provisioning.
44

55
--------------------------------------------------------------------------------
66

@@ -20,8 +20,8 @@ Modify the `values.yaml` for the chart or create a `custom_values.yaml` with the
2020
azure:
2121
region: <your_azure_region> # Azure region, e.g. eastus
2222
dnsName: <your_dns_label> # Unique DNS label for the cluster
23-
istioServiceName: istio-ingressgateway # Name of the Istio service
24-
istioNamespace: istio-system # Namespace of the Istio service
23+
gatewayServiceName: external-gateway-istio # Name of the Gateway API service (LoadBalancer)
24+
gatewayNamespace: istio-system # Namespace of the Gateway API service
2525
maxRetries: 30 # Max retries for waiting on LoadBalancer IP
2626
retryInterval: 10 # Seconds between retries
2727
```

charts/istio-certs/templates/access_control.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ rules:
1616
- apiGroups: ["cert-manager.io"]
1717
resources: ["certificates"]
1818
verbs: ["get", "create", "update", "patch", "apply"]
19+
# Gateway API permissions for Gateway and HTTPRoute management
20+
- apiGroups: ["gateway.networking.k8s.io"]
21+
resources: ["gateways", "httproutes"]
22+
verbs: ["get", "list", "watch", "create", "update", "patch"]
1923
---
2024
apiVersion: rbac.authorization.k8s.io/v1
2125
kind: RoleBinding

charts/istio-certs/templates/configmap.yaml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ data:
99
configure-dns.sh: |
1010
#!/usr/bin/env bash
1111
set -euo pipefail
12-
1312
echo "================================================================="
1413
echo " Starting DNS + Cert Configuration for AKS LoadBalancer"
1514
echo "================================================================="
@@ -22,13 +21,13 @@ data:
2221
}
2322
2423
wait_for_loadbalancer_ip() {
25-
echo "Waiting for LoadBalancer IP on service istio-ingress-external in istio-system..."
24+
echo "Waiting for LoadBalancer IP on service external-gateway-istio in istio-system..."
2625
for ((i=0; i<60; i++)); do
27-
EXTERNAL_IP=$(kubectl get svc istio-ingress-external -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null || :)
26+
EXTERNAL_IP=$(kubectl get svc external-gateway-istio -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null || :)
2827
if [[ -n "$EXTERNAL_IP" ]]; then
2928
echo "Found IP: $EXTERNAL_IP"
3029
return 0
31-
fi
30+
fi
3231
echo "…retry $((i+1))/60"
3332
sleep 5
3433
done
@@ -38,7 +37,7 @@ data:
3837
3938
annotate_service_with_dns() {
4039
echo "Annotating service with DNS label ${DNS_NAME}..."
41-
kubectl annotate svc istio-ingress-external -n istio-system \
40+
kubectl annotate svc external-gateway-istio -n istio-system \
4241
service.beta.kubernetes.io/azure-dns-label-name="${DNS_NAME}" --overwrite
4342
}
4443
@@ -58,7 +57,6 @@ data:
5857
}
5958
6059
main "$@"
61-
6260
istio-certificate.yaml: |
6361
apiVersion: cert-manager.io/v1
6462
kind: Certificate
@@ -71,10 +69,18 @@ data:
7169
renewBefore: 360h # 15 days
7270
subject:
7371
organizations:
74-
- Example Organization
72+
- OSDU Developer
7573
commonName: __FQDN__
7674
dnsNames:
7775
- __FQDN__
7876
issuerRef:
7977
name: letsencrypt-staging
8078
kind: ClusterIssuer
79+
# Use HTTP-01 challenge which will work with Gateway API HTTPRoute
80+
# The ACME challenge solver will create temporary pods that need routing
81+
privateKey:
82+
algorithm: RSA
83+
size: 2048
84+
usages:
85+
- digital signature
86+
- key encipherment

charts/istio-certs/values.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ azure:
1616
dnsName: "" # DNS name to be used for the LoadBalancer IP
1717

1818
################################################################################
19-
# Istio configuration values
19+
# Gateway API configuration values
2020
#
21-
istioServiceName: "istio-ingressgateway" # Name of the Istio service
22-
istioNamespace: "istio-system" # Namespace of the Istio service
23-
maxRetries: 30 # Max retries for waiting on LoadBalancer IP
24-
retryInterval: 10 # Seconds between retries
21+
gatewayServiceName: "external-gateway-istio" # Name of the Gateway API service (LoadBalancer)
22+
gatewayNamespace: "istio-system" # Namespace of the Gateway API service
23+
maxRetries: 30 # Max retries for waiting on LoadBalancer IP
24+
retryInterval: 10 # Seconds between retries
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Certificate will be created by the istio-certs chart after DNS configuration
2+
# This ensures proper FQDN is available for Let's Encrypt validation
3+
# The istio-certs Job handles:
4+
# 1. Waiting for LoadBalancer IP
5+
# 2. Setting DNS label annotation
6+
# 3. Creating Certificate with correct FQDN
7+
# 4. HTTP-01 challenge routing via Gateway API
Lines changed: 83 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,95 @@
11
{{- define "gateway" -}}
2-
apiVersion: networking.istio.io/v1alpha3
2+
apiVersion: gateway.networking.k8s.io/v1
33
kind: Gateway
44
metadata:
55
name: {{ .name | default (printf "%s-gateway" .gatewayType) }}
66
namespace: istio-system
77
spec:
8-
selector:
9-
{{- .selector | default (dict "istio" (printf "ingress-%s" .gatewayType)) | toYaml | nindent 4 }}
10-
servers:
11-
- port:
12-
name: http2
13-
number: 80
14-
protocol: HTTP2
15-
hosts:
16-
{{- if .hosts }}
17-
{{- range .hosts }}
18-
- {{ . | quote }}
19-
{{- end }}
20-
{{- else }}
21-
- "*"
22-
{{- end }}
23-
- port:
24-
name: https
25-
number: 443
26-
protocol: HTTPS
27-
hosts:
28-
{{- if .hosts }}
29-
{{- range .hosts }}
30-
- {{ . | quote }}
31-
{{- end }}
32-
{{- else }}
33-
- "*"
34-
{{- end }}
8+
gatewayClassName: istio
9+
listeners:
10+
- name: http
11+
protocol: HTTP
12+
port: 80
13+
allowedRoutes:
14+
namespaces:
15+
from: All
16+
- name: https
17+
protocol: HTTPS
18+
port: 443
19+
hostname: {{ printf "%s.%s.cloudapp.azure.com" .azure.dnsName .azure.region | quote }}
3520
tls:
36-
{{- if .requireSSL }}
37-
httpsRedirect: true # sends 301 redirect for http requests
38-
{{- end }}
39-
{{- with .tls }}
40-
{{- toYaml . | nindent 8 }}
41-
{{- end }}
21+
mode: Terminate
22+
certificateRefs:
23+
- kind: Secret
24+
name: {{ .tls.credentialName | quote }}
25+
namespace: istio-system
26+
allowedRoutes:
27+
namespaces:
28+
from: All
4229
{{- end }}
4330

44-
{{- if .Values.ingress }}
45-
{{- if hasKey .Values.ingress "internalGateway" }}
46-
{{- if .Values.ingress.internalGateway.enabled }}
31+
{{- if .Values.ingress.externalGateway.enabled }}
4732
---
48-
{{- $internalGateway := merge (dict "gatewayType" "internal" "requireSSL" .Values.ingress.internalGateway.requireSSL) .Values.ingress.internalGateway -}}
49-
{{ include "gateway" $internalGateway }}
50-
{{- end }}
51-
{{- end }}
33+
apiVersion: gateway.networking.k8s.io/v1
34+
kind: Gateway
35+
metadata:
36+
name: external-gateway
37+
namespace: istio-system
38+
labels:
39+
{{- include "istio-ingress.labels" . | nindent 4 }}
40+
istio.io/gateway-name: external-gateway
41+
spec:
42+
gatewayClassName: istio
43+
listeners:
44+
- name: http
45+
protocol: HTTP
46+
port: 80
47+
allowedRoutes:
48+
namespaces:
49+
from: All
50+
- name: https
51+
protocol: HTTPS
52+
port: 443
53+
tls:
54+
mode: Terminate
55+
certificateRefs:
56+
- kind: Secret
57+
name: {{ .Values.ingress.externalGateway.tls.credentialName | quote }}
58+
namespace: istio-system
59+
allowedRoutes:
60+
namespaces:
61+
from: All
62+
{{- end }}
5263

53-
{{- if hasKey .Values.ingress "externalGateway" }}
54-
{{- if .Values.ingress.externalGateway.enabled }}
64+
{{- if .Values.ingress.internalGateway.enabled }}
5565
---
56-
{{- $externalGateway := merge (dict "gatewayType" "external" "requireSSL" .Values.ingress.externalGateway.requireSSL) .Values.ingress.externalGateway -}}
57-
{{ include "gateway" $externalGateway }}
58-
{{- end }}
59-
{{- end }}
60-
{{- end }}
66+
apiVersion: gateway.networking.k8s.io/v1
67+
kind: Gateway
68+
metadata:
69+
name: internal-gateway
70+
namespace: istio-system
71+
labels:
72+
{{- include "istio-ingress.labels" . | nindent 4 }}
73+
istio.io/gateway-name: internal-gateway
74+
spec:
75+
gatewayClassName: istio
76+
listeners:
77+
- name: http
78+
protocol: HTTP
79+
port: 80
80+
allowedRoutes:
81+
namespaces:
82+
from: All
83+
- name: https
84+
protocol: HTTPS
85+
port: 443
86+
tls:
87+
mode: Terminate
88+
certificateRefs:
89+
- kind: Secret
90+
name: {{ .Values.ingress.internalGateway.tls.credentialName | quote }}
91+
namespace: istio-system
92+
allowedRoutes:
93+
namespaces:
94+
from: All
95+
{{- end }}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# HTTPRoutes for ACME challenge handling with Gateway API
2+
#
3+
# Note: For Gateway API, cert-manager typically uses one of these approaches:
4+
# 1. Creates temporary Ingress resources that get converted to HTTPRoutes
5+
# 2. Uses Gateway API native challenge solvers (experimental)
6+
# 3. Relies on application HTTPRoutes to handle challenge paths
7+
#
8+
# Since this is infrastructure-level routing, we'll let individual applications
9+
# handle ACME challenge routing in their own HTTPRoutes, or cert-manager
10+
# will create temporary resources as needed.
11+
#
12+
# This avoids namespace dependency issues during deployment.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# ReferenceGrants are now managed by individual application charts
2+
# to avoid namespace dependency issues during deployment:
3+
# - web-site ReferenceGrant is in software/applications/web-site/
4+
# - cert-manager ReferenceGrant is managed by cert-manager operator
5+
#
6+
# This approach ensures that:
7+
# 1. istio-ingress can deploy without waiting for application namespaces
8+
# 2. Each application manages its own cross-namespace access permissions
9+
# 3. No circular dependencies between infrastructure and applications

charts/istio-ingress/values.yaml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@ ingress:
99
- "*"
1010
tls:
1111
mode: SIMPLE
12-
credentialName: wild-card-tls
12+
credentialName: istio-ingressgateway-certs # Match the secret created by istio-certs chart
1313
externalGateway:
1414
enabled: true
15-
hosts:
16-
- "*"
1715
tls:
1816
mode: SIMPLE
19-
credentialName: wild-card-tls
17+
credentialName: istio-ingressgateway-certs # Match the secret created by istio-certs chart
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{{- $namespace := .Release.Namespace }}
2+
{{- if and .Values.hosts .Values.gateways }}
3+
---
4+
apiVersion: gateway.networking.k8s.io/v1
5+
kind: HTTPRoute
6+
metadata:
7+
name: osdu-auth-route
8+
namespace: {{ $namespace }}
9+
spec: parentRefs:
10+
{{- range .Values.gateways }}
11+
{{- $parts := split "/" . }}
12+
{{- if eq (len $parts) 2 }}
13+
- name: {{ index $parts 1 }}
14+
namespace: {{ index $parts 0 }}
15+
group: gateway.networking.k8s.io
16+
kind: Gateway
17+
{{- else }}
18+
- name: {{ . }}
19+
namespace: istio-system
20+
group: gateway.networking.k8s.io
21+
kind: Gateway
22+
{{- end }}
23+
{{- end }}
24+
rules:
25+
# Auth SPA route
26+
- matches:
27+
- path:
28+
type: PathPrefix
29+
value: {{ .Values.path }}spa/
30+
backendRefs:
31+
- name: osdu-auth-spa
32+
port: 80
33+
weight: 100
34+
# Main auth route
35+
- matches:
36+
- path:
37+
type: PathPrefix
38+
value: {{ .Values.path }}
39+
backendRefs:
40+
- name: osdu-auth
41+
port: 80
42+
weight: 100
43+
{{- end }}

0 commit comments

Comments
 (0)