setup of gateways

This commit is contained in:
James Mellors 2025-05-01 22:23:22 +01:00
parent 9790540ff7
commit e49440844f
8 changed files with 292 additions and 1 deletions

View File

@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: istio-ingress-manager
namespace: argocd
spec:
project: default # Or your specific Argo CD project
source:
repoURL: https://git.james-mellors.com/mello/Monitoring.git # Sealed Secrets chart repository
targetRevision: main # Specify the desired chart version (Check for the latest stable version!)
path: helm/istio-ingress-manager
destination:
server: https://kubernetes.default.svc
namespace: monitoring
syncPolicy:
automated: # Optional: Enable automatic sync
prune: true
selfHeal: true

View File

@ -15,6 +15,8 @@ spec:
server: https://kubernetes.default.svc
namespace: monitoring
syncPolicy:
syncOptions:
- ServerSideApply=true
automated:
prune: true
selfHeal: true

View File

@ -1,4 +1,5 @@
resources:
- uptime-karma.yaml
- ntfy.yaml
- kube-prometheus-stack.yaml
- kube-prometheus-stack.yaml
- istio-ingress-manager.yaml

View File

@ -15,6 +15,8 @@ spec:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
syncOptions:
- ServerSideApply=true
automated:
prune: true
selfHeal: true

View File

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View File

@ -0,0 +1,8 @@
apiVersion: v2
name: istio-ingress-manager
description: A Helm chart to manage Istio Gateways, VirtualServices, and Certificates for various applications
type: application
# Update version as you make changes
version: 0.1.0
# appVersion can be set but isn't strictly tied to an app here
appVersion: "1.0"

View File

@ -0,0 +1,149 @@
{{- /* Loop through each application defined in values.yaml */}}
{{- range .Values.applications }}
{{- if .enabled }}
{{- /* Define variables for easier access within the loop */}}
{{- $appName := .name }}
{{- $namespace := .namespace }}
{{- $serviceName := .serviceName }}
{{- $servicePort := .servicePort }}
{{- $gatewayName := printf "%s-gateway" $appName }}
{{- /* Determine Certificate namespace: Use override if set, otherwise default to app namespace */}}
{{- $certNamespace := .certManager.createSecretInNamespace | default $namespace }}
{{- /* Determine Issuer details: Use app specific if set, otherwise use global */}}
{{- /* Note: Handling globals requires more complex logic or a helper template */}}
{{- /* For simplicity here, we assume issuerName/Kind are defined per-app if not using simple globals */}}
{{- $issuerName := .certManager.issuerName }} {{/* Simplified: Assumes set per app */}}
{{- $issuerKind := .certManager.issuerKind }} {{/* Simplified: Assumes set per app */}}
{{- /* Determine Gateway Selector: Use app specific if set, otherwise use global */}}
{{- /* Simplified: Assumes default or set per app */}}
{{- $gatewaySelector := .istio.gatewaySelector | default (dict "istio" "ingressgateway") }}
{{- /* --- Validation --- */}}
{{- if not $namespace }}{{- fail (printf "ERROR: Application '%s' requires 'namespace' field." $appName) }}{{- end }}
{{- if not $serviceName }}{{- fail (printf "ERROR: Application '%s' requires 'serviceName' field." $appName) }}{{- end }}
{{- if not $servicePort }}{{- fail (printf "ERROR: Application '%s' requires 'servicePort' field." $appName) }}{{- end }}
{{- if not .hosts }}{{- fail (printf "ERROR: Application '%s' requires 'hosts' field." $appName) }}{{- end }}
{{- if .tls.enabled }}
{{- if not .tls.secretName }}{{- fail (printf "ERROR: Application '%s' has tls.enabled=true but requires 'tls.secretName'." $appName) }}{{- end }}
{{- if not .tls.hosts }}{{- fail (printf "ERROR: Application '%s' has tls.enabled=true but requires 'tls.hosts'." $appName) }}{{- end }}
{{- /* Validation for Cert-Manager fields only if TLS is enabled */}}
{{- if not $issuerName }}{{- fail (printf "ERROR: Application '%s' requires 'certManager.issuerName' when tls.enabled=true." $appName) }}{{- end }}
{{- if not $issuerKind }}{{- fail (printf "ERROR: Application '%s' requires 'certManager.issuerKind' when tls.enabled=true." $appName) }}{{- end }}
{{- end }}
---
# --- Istio Gateway for {{ $appName }} ---
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: {{ $gatewayName }}
namespace: {{ $namespace }} # Gateway lives in the app's namespace
labels:
app.kubernetes.io/name: {{ $appName }}-gateway
app.kubernetes.io/managed-by: {{ $.Release.Service }}
app.kubernetes.io/instance: {{ $.Release.Name }}
spec:
selector: {{ $gatewaySelector | toYaml | nindent 4 }}
servers:
# HTTP Server entry (Port 80)
- port:
number: 80
name: http-{{ $appName }}
protocol: HTTP
hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
{{- if and .tls.enabled .istio.httpRedirect }}
tls:
httpsRedirect: true
{{- end }}
{{- /* HTTPS Server entry (Port 443) - Only if TLS is enabled */}}
{{- if .tls.enabled }}
- port:
number: 443
name: https-{{ $appName }}
protocol: HTTPS
hosts:
{{- range .tls.hosts }}
- {{ . | quote }}
{{- end }}
tls:
mode: SIMPLE
# Credential name refers to the Secret name (expected in $certNamespace by Istio)
credentialName: {{ .tls.secretName }}
{{- end }}
---
# --- Istio VirtualService for {{ $appName }} ---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: {{ printf "%s-vs" $appName }}
namespace: {{ $namespace }} # VirtualService lives in the app's namespace
labels:
app.kubernetes.io/name: {{ $appName }}-vs
app.kubernetes.io/managed-by: {{ $.Release.Service }}
app.kubernetes.io/instance: {{ $.Release.Name }}
spec:
gateways:
- {{ $gatewayName }} # Link to the Gateway created above
hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
http:
{{- /* Assuming one path block per app for simplicity, extend if needed */}}
{{- range .paths }}
- match:
- uri:
{{- if eq .pathType "Prefix" }}
prefix: {{ .path }}
{{- else if eq .pathType "Exact" }}
exact: {{ .path }}
{{- else }}
prefix: {{ .path }} # Default to Prefix
{{- end }}
route:
- destination:
host: {{ $serviceName }}
port:
number: {{ $servicePort }}
{{- end }}
{{- /* --- Cert-Manager Certificate (only if TLS enabled) --- */}}
{{- if .tls.enabled }}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
# Use the secret name for the Certificate resource name for consistency
name: {{ .tls.secretName }}
# Create Certificate (and Secret) in specified namespace (app namespace or override)
namespace: {{ $certNamespace }}
labels:
app.kubernetes.io/name: {{ $appName }}-certificate
app.kubernetes.io/managed-by: {{ $.Release.Service }}
app.kubernetes.io/instance: {{ $.Release.Name }}
{{- if ne $certNamespace $namespace }}
# Optional label indicating which app namespace this cert is FOR
app.kubernetes.io/for-namespace: {{ $namespace }}
{{- end }}
spec:
secretName: {{ .tls.secretName }} # Secret name used by Gateway's credentialName
issuerRef:
name: {{ $issuerName }}
kind: {{ $issuerKind }}
dnsNames:
{{- range .tls.hosts }}
- {{ . | quote }}
{{- end }}
{{- $firstHost := first .tls.hosts -}}
{{- if $firstHost }}
commonName: {{ $firstHost | quote }}
{{- end }}
{{- end }} {{- /* End if .tls.enabled for Certificate */}}
{{- end }} {{- /* End if .enabled */}}
{{- end }} {{- /* End range .Values.applications */}}

View File

@ -0,0 +1,86 @@
# Global defaults (Optional - can be overridden per application)
# global:
# istio:
# gatewaySelector:
# istio: ingressgateway # Default selector for Istio ingress pods
# certManager:
# issuerName: "letsencrypt-prod"
# issuerKind: ClusterIssuer
# createSecretInNamespace: "" # Default: empty means create in app namespace
# List of applications to configure ingress for
applications:
# --- Example for Grafana ---
- name: grafana
# Set to true to create resources for this application
enabled: true
# Namespace where the Grafana SERVICE lives (and where Gateway/VS will be created)
namespace: monitoring
# Name of the Grafana Kubernetes Service
serviceName: kube-prometheus-stack-grafana # Adjust if different
# Port the Grafana Service listens on
servicePort: 80 # The K8s service port, often 80, targets Grafana's internal port (3000)
# Hostname(s) for accessing Grafana
hosts:
- grafana.james-mellors.com
# Path configuration for routing
paths:
- path: /
pathType: Prefix # Prefix or Exact
# TLS specific configuration
tls:
# Set to true if this application uses TLS (required for certificate)
enabled: true
# Name of the Kubernetes Secret to store/read the TLS certificate
secretName: grafana-tls
# List of hosts the certificate should cover (usually matches 'hosts' above)
hosts:
- grafana.james-mellors.com
# Istio specific overrides for this application (Optional)
istio:
# Override the global gateway selector if needed
# gatewaySelector:
# istio: my-custom-gateway
# Enable HTTP->HTTPS redirect for this app's Gateway
httpRedirect: true
# Cert-Manager specific overrides for this application (Optional)
certManager:
# Override global issuer if needed
# issuerName: "my-internal-ca"
# issuerKind: Issuer
# Override where the Secret is created (e.g., "istio-system" or keep empty for app namespace)
createSecretInNamespace: "" # Default: uses 'namespace' field above
# --- Example for NTFY ---
# - name: ntfy
# enabled: true
# namespace: default # Or wherever your NTFY service lives
# serviceName: ntfy-server # Adjust if different
# servicePort: 80 # The port the K8s service listens on
# hosts:
# - ntfy.yourdomain.com
# paths:
# - path: /
# pathType: Prefix
# tls:
# enabled: true
# secretName: ntfy-tls
# hosts:
# - ntfy.yourdomain.com
# istio:
# httpRedirect: true
# certManager:
# # Using global defaults defined above (if any) or specify here
# # issuerName: "letsencrypt-prod"
# # issuerKind: ClusterIssuer
# createSecretInNamespace: "" # Default: uses 'namespace' field above
# --- Add more applications here ---
# - name: my-other-app
# enabled: false # Disabled example
# namespace: apps
# serviceName: my-other-app-svc
# ... etc ...