diff --git a/charts/netbird-proxy/Chart.yaml b/charts/netbird-proxy/Chart.yaml new file mode 100644 index 0000000..56b6973 --- /dev/null +++ b/charts/netbird-proxy/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: netbird-proxy +description: NetBird reverse proxy with ACME certificate management +type: application +version: 0.1.0 +appVersion: "0.1.0" diff --git a/charts/netbird-proxy/templates/NOTES.txt b/charts/netbird-proxy/templates/NOTES.txt new file mode 100644 index 0000000..deb67fe --- /dev/null +++ b/charts/netbird-proxy/templates/NOTES.txt @@ -0,0 +1,32 @@ +NetBird Proxy has been deployed. + +{{- if eq .Values.service.type "LoadBalancer" }} + +The proxy is exposed via a LoadBalancer service. +It may take a few minutes for the external IP to be provisioned. + + kubectl get svc {{ include "netbird-proxy.fullname" . }} -n {{ .Release.Namespace }} -w + +{{- else if eq .Values.service.type "NodePort" }} + +The proxy is exposed via NodePort. + + export NODE_PORT=$(kubectl get svc {{ include "netbird-proxy.fullname" . }} -n {{ .Release.Namespace }} -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}') + export NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="ExternalIP")].address}') + echo "https://${NODE_IP}:${NODE_PORT}" + +{{- else }} + +The proxy is using a ClusterIP service. To access it from outside the cluster, +configure an Ingress resource or use port-forwarding: + + kubectl port-forward svc/{{ include "netbird-proxy.fullname" . }} {{ .Values.service.port }}:{{ .Values.service.port }} -n {{ .Release.Namespace }} + +{{- end }} + +{{- if .Values.acme.enabled }} + +ACME certificate management is enabled ({{ .Values.acme.directory }}). +Certificates are stored in {{ .Values.certDir }}. +Lock method: {{ .Values.acme.certLockMethod }} +{{- end }} diff --git a/charts/netbird-proxy/templates/_helpers.tpl b/charts/netbird-proxy/templates/_helpers.tpl new file mode 100644 index 0000000..9df529f --- /dev/null +++ b/charts/netbird-proxy/templates/_helpers.tpl @@ -0,0 +1,92 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "netbird-proxy.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "netbird-proxy.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "netbird-proxy.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels. +*/}} +{{- define "netbird-proxy.labels" -}} +helm.sh/chart: {{ include "netbird-proxy.chart" . }} +{{ include "netbird-proxy.selectorLabels" . }} +app.kubernetes.io/component: proxy +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels. +*/}} +{{- define "netbird-proxy.selectorLabels" -}} +app: {{ include "netbird-proxy.fullname" . }} +app.kubernetes.io/name: {{ include "netbird-proxy.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use. +*/}} +{{- define "netbird-proxy.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "netbird-proxy.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Name of the Secret containing the proxy token. +*/}} +{{- define "netbird-proxy.secretName" -}} +{{- if .Values.existingSecret }} +{{- .Values.existingSecret }} +{{- else }} +{{- include "netbird-proxy.fullname" . }} +{{- end }} +{{- end }} + +{{/* +Extract the port number from an address string. +Handles ":8443", "0.0.0.0:8443", and "[::1]:8443". +*/}} +{{- define "netbird-proxy.port" -}} +{{- mustRegexFind "[0-9]+$" . -}} +{{- end -}} + +{{/* +Name of the Secret containing the OIDC client secret. +*/}} +{{- define "netbird-proxy.oidcSecretName" -}} +{{- if .Values.oidc.existingOidcSecret }} +{{- .Values.oidc.existingOidcSecret }} +{{- else }} +{{- printf "%s-oidc" (include "netbird-proxy.fullname" .) }} +{{- end }} +{{- end }} diff --git a/charts/netbird-proxy/templates/deployment.yaml b/charts/netbird-proxy/templates/deployment.yaml new file mode 100644 index 0000000..344ce28 --- /dev/null +++ b/charts/netbird-proxy/templates/deployment.yaml @@ -0,0 +1,227 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "netbird-proxy.fullname" . }} + labels: + {{- include "netbird-proxy.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "netbird-proxy.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "netbird-proxy.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + # Shutdown budget: 5s pre-stop LB drain + 30s HTTPS drain + 5s service stop + 30s client stop + 5s buffer + terminationGracePeriodSeconds: 75 + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "netbird-proxy.serviceAccountName" . }} + {{- with .Values.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + {{- with .Values.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: proxy + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: https + containerPort: {{ include "netbird-proxy.port" .Values.proxy.address | default 8443 }} + protocol: TCP + - name: health + containerPort: {{ include "netbird-proxy.port" .Values.health.address | default 8080 }} + protocol: TCP + {{- if .Values.acme.enabled }} + - name: acme-http + containerPort: {{ include "netbird-proxy.port" .Values.acme.address | default 80 }} + protocol: TCP + {{- end }} + {{- if .Values.debug.enabled }} + - name: debug + containerPort: {{ include "netbird-proxy.port" .Values.debug.address | default 8444 }} + protocol: TCP + {{- end }} + env: + - name: USER + value: "netbird" + - name: HOME + value: "/tmp" + - name: NB_PROXY_ADDRESS + value: {{ .Values.proxy.address | quote }} + - name: NB_PROXY_MANAGEMENT_ADDRESS + value: {{ .Values.managementAddress | quote }} + - name: NB_PROXY_HEALTH_ADDRESS + value: {{ .Values.health.address | quote }} + - name: NB_PROXY_CERTIFICATE_DIRECTORY + value: {{ .Values.certDir | quote }} + - name: NB_PROXY_TOKEN + valueFrom: + secretKeyRef: + name: {{ include "netbird-proxy.secretName" . }} + key: token + {{- if .Values.allowInsecure }} + - name: NB_PROXY_ALLOW_INSECURE + value: "true" + {{- end }} + {{- if .Values.logging.debug }} + - name: NB_PROXY_DEBUG_LOGS + value: "true" + {{- end }} + {{- if .Values.proxy.url }} + - name: NB_PROXY_URL + value: {{ .Values.proxy.url | quote }} + {{- end }} + {{- if and .Values.proxy.forwardedProto (ne .Values.proxy.forwardedProto "auto") }} + - name: NB_PROXY_FORWARDED_PROTO + value: {{ .Values.proxy.forwardedProto | quote }} + {{- end }} + {{- if .Values.proxy.trustedProxies }} + - name: NB_PROXY_TRUSTED_PROXIES + value: {{ .Values.proxy.trustedProxies | quote }} + {{- end }} + {{- if .Values.acme.enabled }} + - name: NB_PROXY_ACME_CERTIFICATES + value: "true" + - name: NB_PROXY_ACME_ADDRESS + value: {{ .Values.acme.address | quote }} + - name: NB_PROXY_ACME_DIRECTORY + value: {{ .Values.acme.directory | quote }} + - name: NB_PROXY_CERT_LOCK_METHOD + value: {{ .Values.acme.certLockMethod | quote }} + {{- else }} + - name: NB_PROXY_CERTIFICATE_FILE + value: {{ .Values.tls.certFile | quote }} + - name: NB_PROXY_CERTIFICATE_KEY_FILE + value: {{ .Values.tls.keyFile | quote }} + {{- end }} + {{- if .Values.oidc.clientId }} + - name: NB_PROXY_OIDC_CLIENT_ID + value: {{ .Values.oidc.clientId | quote }} + {{- end }} + {{- if or .Values.oidc.clientSecret .Values.oidc.existingOidcSecret }} + - name: NB_PROXY_OIDC_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: {{ include "netbird-proxy.oidcSecretName" . }} + key: oidc-client-secret + {{- end }} + {{- if .Values.oidc.endpoint }} + - name: NB_PROXY_OIDC_ENDPOINT + value: {{ .Values.oidc.endpoint | quote }} + {{- end }} + {{- if .Values.oidc.scopes }} + - name: NB_PROXY_OIDC_SCOPES + value: {{ .Values.oidc.scopes | quote }} + {{- end }} + {{- if .Values.debug.enabled }} + - name: NB_PROXY_DEBUG_ENDPOINT + value: "true" + - name: NB_PROXY_DEBUG_ENDPOINT_ADDRESS + value: {{ .Values.debug.address | quote }} + {{- end }} + {{- with .Values.extraEnv }} + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: certs + mountPath: {{ .Values.certDir }} + - name: tmp + mountPath: /tmp + {{- with .Values.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + livenessProbe: + httpGet: + path: /healthz/live + port: health + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /healthz/ready + port: health + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + startupProbe: + httpGet: + path: /healthz/startup + port: health + periodSeconds: 2 + timeoutSeconds: 10 + # 60 * 2s = 120s for ACME certs + management sync + client startup + failureThreshold: 60 + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumes: + - name: certs + {{- if .Values.certVolume.hostPath }} + hostPath: + path: {{ .Values.certVolume.hostPath }} + type: DirectoryOrCreate + {{- else if .Values.certVolume.existingClaim }} + persistentVolumeClaim: + claimName: {{ .Values.certVolume.existingClaim }} + {{- else if .Values.certVolume.enabled }} + persistentVolumeClaim: + claimName: {{ include "netbird-proxy.fullname" . }}-certs + {{- else }} + emptyDir: {} + {{- end }} + - name: tmp + emptyDir: {} + {{- with .Values.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if not .Values.affinity }} + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + {{- include "netbird-proxy.selectorLabels" . | nindent 20 }} + topologyKey: kubernetes.io/hostname + {{- else }} + affinity: + {{- toYaml .Values.affinity | nindent 8 }} + {{- end }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/netbird-proxy/templates/hpa.yaml b/charts/netbird-proxy/templates/hpa.yaml new file mode 100644 index 0000000..6e2b5c1 --- /dev/null +++ b/charts/netbird-proxy/templates/hpa.yaml @@ -0,0 +1,32 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "netbird-proxy.fullname" . }} + labels: + {{- include "netbird-proxy.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "netbird-proxy.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/charts/netbird-proxy/templates/networkpolicy.yaml b/charts/netbird-proxy/templates/networkpolicy.yaml new file mode 100644 index 0000000..48eb5c3 --- /dev/null +++ b/charts/netbird-proxy/templates/networkpolicy.yaml @@ -0,0 +1,31 @@ +{{- if .Values.networkPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "netbird-proxy.fullname" . }} + labels: + {{- include "netbird-proxy.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "netbird-proxy.selectorLabels" . | nindent 6 }} + policyTypes: + - Ingress + ingress: + - ports: + - port: https + protocol: TCP + {{- if .Values.acme.enabled }} + - port: acme-http + protocol: TCP + {{- end }} + - port: health + protocol: TCP + {{- if .Values.debug.enabled }} + - port: debug + protocol: TCP + {{- end }} + {{- with .Values.networkPolicy.additionalIngress }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/netbird-proxy/templates/pdb.yaml b/charts/netbird-proxy/templates/pdb.yaml new file mode 100644 index 0000000..b6bf4af --- /dev/null +++ b/charts/netbird-proxy/templates/pdb.yaml @@ -0,0 +1,18 @@ +{{- if .Values.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "netbird-proxy.fullname" . }} + labels: + {{- include "netbird-proxy.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "netbird-proxy.selectorLabels" . | nindent 6 }} + {{- if .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} + {{- end }} +{{- end }} diff --git a/charts/netbird-proxy/templates/pvc.yaml b/charts/netbird-proxy/templates/pvc.yaml new file mode 100644 index 0000000..37ef299 --- /dev/null +++ b/charts/netbird-proxy/templates/pvc.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.certVolume.enabled (not .Values.certVolume.existingClaim) (not .Values.certVolume.hostPath) }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "netbird-proxy.fullname" . }}-certs + labels: + {{- include "netbird-proxy.labels" . | nindent 4 }} +spec: + accessModes: + - {{ .Values.certVolume.accessMode | default "ReadWriteMany" }} + {{- if .Values.certVolume.storageClass }} + storageClassName: {{ .Values.certVolume.storageClass }} + {{- end }} + resources: + requests: + storage: {{ .Values.certVolume.size | default "256Mi" }} +{{- end }} diff --git a/charts/netbird-proxy/templates/role.yaml b/charts/netbird-proxy/templates/role.yaml new file mode 100644 index 0000000..abf054c --- /dev/null +++ b/charts/netbird-proxy/templates/role.yaml @@ -0,0 +1,12 @@ +{{- if and .Values.rbac.create .Values.serviceAccount.create (eq .Values.acme.certLockMethod "k8s-lease") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "netbird-proxy.fullname" . }} + labels: + {{- include "netbird-proxy.labels" . | nindent 4 }} +rules: + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "create", "update"] +{{- end }} diff --git a/charts/netbird-proxy/templates/rolebinding.yaml b/charts/netbird-proxy/templates/rolebinding.yaml new file mode 100644 index 0000000..b42127b --- /dev/null +++ b/charts/netbird-proxy/templates/rolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.rbac.create .Values.serviceAccount.create (eq .Values.acme.certLockMethod "k8s-lease") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "netbird-proxy.fullname" . }} + labels: + {{- include "netbird-proxy.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ include "netbird-proxy.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: Role + name: {{ include "netbird-proxy.fullname" . }} + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/charts/netbird-proxy/templates/secret.yaml b/charts/netbird-proxy/templates/secret.yaml new file mode 100644 index 0000000..0cd4d93 --- /dev/null +++ b/charts/netbird-proxy/templates/secret.yaml @@ -0,0 +1,23 @@ +{{- if not .Values.existingSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "netbird-proxy.fullname" . }} + labels: + {{- include "netbird-proxy.labels" . | nindent 4 }} +type: Opaque +data: + token: {{ .Values.proxyToken | b64enc | quote }} +{{- end }} +--- +{{- if and .Values.oidc.clientSecret (not .Values.oidc.existingOidcSecret) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "netbird-proxy.oidcSecretName" . }} + labels: + {{- include "netbird-proxy.labels" . | nindent 4 }} +type: Opaque +data: + oidc-client-secret: {{ .Values.oidc.clientSecret | b64enc | quote }} +{{- end }} diff --git a/charts/netbird-proxy/templates/service.yaml b/charts/netbird-proxy/templates/service.yaml new file mode 100644 index 0000000..d4ac814 --- /dev/null +++ b/charts/netbird-proxy/templates/service.yaml @@ -0,0 +1,45 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "netbird-proxy.fullname" . }} + labels: + {{- include "netbird-proxy.labels" . | nindent 4 }} + {{- with .Values.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + {{- if and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancer.ip }} + loadBalancerIP: {{ .Values.service.loadBalancer.ip }} + {{- end }} + {{- if and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancer.sourceRanges }} + loadBalancerSourceRanges: + {{- toYaml .Values.service.loadBalancer.sourceRanges | nindent 4 }} + {{- end }} + {{- if and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancer.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.service.loadBalancer.externalTrafficPolicy }} + {{- end }} + selector: + {{- include "netbird-proxy.selectorLabels" . | nindent 4 }} + ports: + - name: https + port: {{ .Values.service.port }} + targetPort: https + protocol: TCP + {{- if .Values.acme.enabled }} + - name: acme-http + port: {{ .Values.service.acmePort }} + targetPort: acme-http + protocol: TCP + {{- end }} + - name: health + port: {{ include "netbird-proxy.port" .Values.health.address | default 8080 }} + targetPort: health + protocol: TCP + {{- if .Values.debug.enabled }} + - name: debug + port: {{ include "netbird-proxy.port" .Values.debug.address | default 8444 }} + targetPort: debug + protocol: TCP + {{- end }} diff --git a/charts/netbird-proxy/templates/serviceaccount.yaml b/charts/netbird-proxy/templates/serviceaccount.yaml new file mode 100644 index 0000000..ed8f704 --- /dev/null +++ b/charts/netbird-proxy/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "netbird-proxy.serviceAccountName" . }} + labels: + {{- include "netbird-proxy.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automount | default true }} +{{- end }} diff --git a/charts/netbird-proxy/templates/servicemonitor.yaml b/charts/netbird-proxy/templates/servicemonitor.yaml new file mode 100644 index 0000000..5758c83 --- /dev/null +++ b/charts/netbird-proxy/templates/servicemonitor.yaml @@ -0,0 +1,32 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "netbird-proxy.fullname" . }} + labels: + {{- include "netbird-proxy.labels" . | nindent 4 }} + {{- with .Values.serviceMonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.serviceMonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "netbird-proxy.selectorLabels" . | nindent 6 }} + endpoints: + - port: health + path: {{ .Values.serviceMonitor.path }} + {{- with .Values.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with .Values.serviceMonitor.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/netbird-proxy/values.yaml b/charts/netbird-proxy/values.yaml new file mode 100644 index 0000000..8d7a1e9 --- /dev/null +++ b/charts/netbird-proxy/values.yaml @@ -0,0 +1,235 @@ +replicaCount: 2 + +image: + repository: netbird-proxy + tag: "" + pullPolicy: IfNotPresent + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +# -- Proxy token for management server authentication. +# Ignored if existingSecret is set. +proxyToken: "" + +# -- Use an existing Secret for the proxy token. +# The secret must contain a key named "token". +existingSecret: "" + +managementAddress: "https://api.netbird.io:443" + +# -- Allow proxy token over non-TLS management connections. +allowInsecure: false + +proxy: + # -- Listen address for the HTTPS reverse proxy. + address: ":8443" + # -- Public URL of the proxy (used for ACME and client access). + # Leave empty to auto-derive from the proxy address. + url: "" + # -- X-Forwarded-Proto behaviour: auto, http, or https. + forwardedProto: "auto" + # -- Comma-separated CIDR ranges of trusted upstream proxies. + trustedProxies: "" + +acme: + # -- Enable ACME certificate generation. + enabled: true + # -- HTTP-01 challenge listen address. + address: ":80" + # -- ACME directory URL. + directory: "https://acme-v02.api.letsencrypt.org/directory" + # -- Certificate lock method: auto, flock, or k8s-lease. + certLockMethod: "k8s-lease" + +# -- Static TLS certificate configuration (used when acme.enabled=false). +tls: + certFile: "tls.crt" + keyFile: "tls.key" + +oidc: + clientId: "netbird-proxy" + # -- OIDC client secret. Ignored if existingOidcSecret is set. + # For production, consider using existingOidcSecret with sealed-secrets + # or external-secrets-operator instead of storing the secret in values. + clientSecret: "" + # -- Use an existing Secret for the OIDC client secret. + # The secret must contain a key named "oidc-client-secret". + existingOidcSecret: "" + endpoint: "https://api.netbird.io/oauth2" + scopes: "openid,profile,email" + +debug: + # -- Enable the debug HTTP endpoint. + enabled: false + # -- Debug endpoint listen address. + address: ":8444" + +health: + # -- Health probe listen address. + address: ":8080" + +logging: + # -- Enable debug-level logging. + debug: false + +# -- Directory where certificates are stored inside the container. +certDir: "/certs" + +# -- Certificate volume configuration. +# ACME mode with multiple replicas requires a shared volume (RWX) because autocert +# uses a DirCache and HTTP-01 challenges can arrive on any pod. +# Set enabled=true to auto-provision a PVC, or supply an existingClaim. +# For a single replica, emptyDir works but certs are lost on restart. +certVolume: + # -- Enable persistent certificate storage via PVC. + # Defaults to true when acme is enabled; override to false for single-replica emptyDir. + enabled: true + # -- Mount an existing PVC instead of creating one. + existingClaim: "" + # -- Use a hostPath volume instead of a PVC. + # Takes precedence over enabled and existingClaim. + hostPath: "" + # -- PVC access mode. ReadWriteMany is required for multi-replica ACME + # (HTTP-01 challenges can arrive on any pod). ReadWriteOnce is fine for + # a single replica. Note: changing this on an existing release requires + # deleting and recreating the PVC (access modes are immutable). + accessMode: "ReadWriteMany" + # -- Storage class. Leave empty for the cluster default. + storageClass: "" + # -- PVC size. + size: "256Mi" + +serviceAccount: + # -- Create a ServiceAccount. + create: true + # -- Annotations to add to the ServiceAccount. + annotations: {} + # -- Override the ServiceAccount name. + name: "" + # -- Automount the ServiceAccount token. Required when using k8s-lease cert locking. + # Set to false if ACME is disabled or certLockMethod is not k8s-lease. + automount: true + +rbac: + # -- Create RBAC resources for k8s-lease cert locking. + create: true + +podAnnotations: {} +podLabels: {} + +podSecurityContext: + fsGroup: 1000 + +securityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + +service: + # -- Service type: ClusterIP, LoadBalancer, or NodePort. + type: ClusterIP + # -- Annotations for the Service (e.g. cloud LB annotations). + annotations: {} + # -- HTTPS proxy port. + port: 443 + # -- ACME HTTP-01 challenge port (only exposed if acme.enabled). + acmePort: 80 + + loadBalancer: + # -- Source ranges allowed to reach the LoadBalancer. + sourceRanges: [] + # -- Request a specific LoadBalancer IP. + ip: "" + # -- External traffic policy: Cluster or Local. + # Local preserves client source IP but may cause imbalanced traffic. + externalTrafficPolicy: "" + +resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 500m + memory: 256Mi + +# -- Host aliases to inject into /etc/hosts. +hostAliases: [] +# - ip: "192.168.100.1" +# hostnames: +# - "host.docker.internal" + +# -- Pod topology spread constraints. +topologySpreadConstraints: [] + +# -- Node selector. +nodeSelector: {} + +# -- Tolerations. +tolerations: [] + +# -- Affinity overrides. When empty, a default pod anti-affinity +# (preferredDuringSchedulingIgnoredDuringExecution on hostname) is applied. +affinity: {} + +podDisruptionBudget: + # -- Create a PodDisruptionBudget. + enabled: true + # -- Minimum available pods. + minAvailable: 1 + # -- Maximum unavailable pods (mutually exclusive with minAvailable). + # maxUnavailable: 1 + +serviceMonitor: + # -- Create a Prometheus ServiceMonitor resource. + enabled: false + # -- Extra labels for ServiceMonitor selector matching. + labels: {} + # -- Annotations on the ServiceMonitor. + annotations: {} + # -- Metrics endpoint path. + path: /metrics + # -- Scrape interval (e.g. "30s"). Uses Prometheus default if empty. + interval: "" + # -- Scrape timeout (e.g. "10s"). Uses Prometheus default if empty. + scrapeTimeout: "" + # -- Namespace selector for cross-namespace monitoring. + namespaceSelector: {} + +networkPolicy: + # -- Create a NetworkPolicy restricting ingress to proxy ports. + enabled: false + # -- Additional ingress rules to append. + additionalIngress: [] + +autoscaling: + enabled: false + minReplicas: 2 + maxReplicas: 10 + targetCPUUtilizationPercentage: 70 + targetMemoryUtilizationPercentage: 80 + +# -- Extra environment variables to add to the proxy container. +extraEnv: [] +# - name: SSL_CERT_FILE +# value: "/pebble-ca/pebble-ca.pem" + +# -- Extra volumes to add to the pod. +extraVolumes: [] +# - name: pebble-ca +# secret: +# secretName: pebble-ca + +# -- Extra volume mounts to add to the proxy container. +extraVolumeMounts: [] +# - name: pebble-ca +# mountPath: /pebble-ca +# readOnly: true + +# -- Init containers to add to the pod. +initContainers: []