[stable/unifi] Adding captive portal service (#21241)

* [stable/unifi] Adding captive portal service
Signed-off-by: Arno Dubois <arno.du@orange.fr>

Signed-off-by: Arno DUBOIS <arnodubois@sweetpunk.com>

* [stable/unifi] Annnd bumping version
Signed-off-by: Arno Dubois <arno.du@orange.fr>

Signed-off-by: Arno DUBOIS <arnodubois@sweetpunk.com>

* Added an enabled switch

Signed-off-by: Arno DUBOIS <arnodubois@sweetpunk.com>

* [stable/unifi] Fixing feedbacks

Signed-off-by: Arno DUBOIS <arnodubois@sweetpunk.com>

* [stable/unifi] Adding captive portal ingress

Signed-off-by: Arno DUBOIS <arnodubois@sweetpunk.com>

* [stable/unifi] Better table formatting

Signed-off-by: Arno DUBOIS <arnodubois@sweetpunk.com>

* [stable/unifi] Fixed ingress

Signed-off-by: Arno DUBOIS <arnodubois@sweetpunk.com>

Co-authored-by: Arno DUBOIS <arnodubois@sweetpunk.com>
This commit is contained in:
Arno DUBOIS 2020-03-06 22:35:35 +01:00 committed by Jeff Billimek
parent 6c8d01add3
commit 6a3b129a4b
No known key found for this signature in database
GPG Key ID: 214B3EF39B4956B7
7 changed files with 255 additions and 69 deletions

View File

@ -2,7 +2,7 @@ apiVersion: v1
appVersion: 5.11.50
description: Ubiquiti Network's Unifi Controller
name: unifi
version: 0.6.1
version: 0.6.2
keywords:
- ubiquiti
- unifi

View File

@ -34,74 +34,89 @@ The command removes all the Kubernetes components associated with the chart and
The following tables lists the configurable parameters of the Unifi chart and their default values.
| Parameter | Description | Default |
| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
| `image.repository` | Image repository | `jacobalberty/unifi` |
| `image.tag` | Image tag. Possible values listed [here][docker]. | `5.11.50` |
| `image.pullPolicy` | Image pull policy | `IfNotPresent` |
| `strategyType` | Specifies the strategy used to replace old Pods by new ones | `Recreate` |
| `guiService.type` | Kubernetes service type for the Unifi GUI | `ClusterIP` |
| `guiService.port` | Kubernetes port where the Unifi GUI is exposed | `8443` |
| `guiService.annotations` | Service annotations for the Unifi GUI | `{}` |
| `guiService.labels` | Custom labels | `{}` |
| `guiService.loadBalancerIP` | Loadbalance IP for the Unifi GUI | `{}` |
| `guiService.loadBalancerSourceRanges` | List of IP CIDRs allowed access to load balancer (if supported) | None |
| `guiService.externalTrafficPolicy` | Set the externalTrafficPolicy in the Service to either Cluster or Local | `Cluster` |
| `controllerService.type` | Kubernetes service type for the Unifi Controller communication | `NodePort` |
| `controllerService.port` | Kubernetes port where the Unifi Controller is exposed - this needs to be reachable by the unifi devices on the network | `8080` |
| `controllerService.annotations` | Service annotations for the Unifi Controller | `{}` |
| `controllerService.labels` | Custom labels | `{}` |
| `controllerService.loadBalancerIP` | Loadbalance IP for the Unifi Controller | `{}` |
| `controllerService.loadBalancerSourceRanges` | List of IP CIDRs allowed access to load balancer (if supported) | None |
| `controllerService.externalTrafficPolicy` | Set the externalTrafficPolicy in the Service to either Cluster or Local | `Cluster` |
| `stunService.type` | Kubernetes service type for the Unifi STUN | `NodePort` |
| `stunService.port` | Kubernetes UDP port where the Unifi STUN is exposed | `3478` |
| `stunService.annotations` | Service annotations for the Unifi STUN | `{}` |
| `stunService.labels` | Custom labels | `{}` |
| `stunService.loadBalancerIP` | Loadbalance IP for the Unifi STUN | `{}` |
| `stunService.loadBalancerSourceRanges` | List of IP CIDRs allowed access to load balancer (if supported) | None |
| `stunService.externalTrafficPolicy` | Set the externalTrafficPolicy in the Service to either Cluster or Local | `Cluster` |
| `discoveryService.type` | Kubernetes service type for AP discovery | `NodePort` |
| `discoveryService.port` | Kubernetes UDP port for AP discovery | `10001` |
| `discoveryService.annotations` | Service annotations for AP discovery | `{}` |
| `discoveryService.labels` | Custom labels | `{}` |
| `discoveryService.loadBalancerIP` | Loadbalance IP for AP discovery | `{}` |
| `discoveryService.loadBalancerSourceRanges` | List of IP CIDRs allowed access to load balancer (if supported) | None |
| `discoveryService.externalTrafficPolicy` | Set the externalTrafficPolicy in the Service to either Cluster or Local | `Cluster` |
| `unifiedService.enabled` | Use a single service for GUI, controller, STUN, and discovery | `false` |
| `unifiedService.type` | Kubernetes service type for the unified service | `ClusterIP` |
| `unifiedService.annotations` | Annotations for the unified service | `{}` |
| `unifiedService.labels` | Custom labels for the unified service | `{}` |
| `unifiedService.loadBalancerIP` | Load balancer IP for the unified service | None |
| `unifiedService.loadBalancerSourceRanges` | List of IP CIDRs allowed access to the load balancer (if supported) | None |
| `unifiedService.externalTrafficPolicy` | Set the externalTrafficPolicy in the service to either Cluster or Local | `Cluster` |
| `ingress.enabled` | Enables Ingress | `false` |
| `ingress.annotations` | Ingress annotations | `{}` |
| `ingress.labels` | Custom labels | `{}` |
| `ingress.path` | Ingress path | `/` |
| `ingress.hosts` | Ingress accepted hostnames | `chart-example.local` |
| `ingress.tls` | Ingress TLS configuration | `[]` |
| `timezone` | Timezone the Unifi controller should run as, e.g. 'America/New York' | `UTC` |
| `runAsRoot` | Run the controller as UID0 (root user); if set to false, will give container SETFCAP instead | `false` |
| `UID` | Run the controller as user UID | `999` |
| `GID` | Run the controller as group GID | `999` |
| `mongodb.enabled` | Use external MongoDB for data storage | `false` |
| `mongodb.dbUri` | external MongoDB URI | `mongodb://mongo/unifi` |
| `mongodb.statDbUri` | external MongoDB statdb URI | `mongodb://mongo/unifi_stat` |
| `mongodb.databaseName` | external MongoDB database name | `unifi` |
| `persistence.enabled` | Use persistent volume to store data | `true` |
| `persistence.size` | Size of persistent volume claim | `5Gi` |
| `persistence.existingClaim` | Use an existing PVC to persist data | `nil` |
| `persistence.storageClass` | Type of persistent volume claim | `-` |
| `persistence.accessModes` | Persistence access modes | `[]` |
| `extraConfigFiles` | Dictionary containing files mounted to `/configmap` inside the pod (See [values.yaml](values.yaml) for examples) | `{}` |
| `extraJvmOpts` | List of additional JVM options, e.g. `["-Dlog4j.configurationFile=file:/configmap/log4j2.xml"]` | `[]` |
| `resources` | CPU/Memory resource requests/limits | `{}` |
| `nodeSelector` | Node labels for pod assignment | `{}` |
| `tolerations` | Toleration labels for pod assignment | `[]` |
| `affinity` | Affinity settings for pod assignment | `{}` |
| `podAnnotations` | Key-value pairs to add as pod annotations | `{}` |
| `deploymentAnnotations` | Key-value pairs to add as deployment annotations | `{}` |
| Parameter | Default | Description |
|-------------------------------------------------|------------------------------|------------------------------------------------------------------------------------------------------------------------|
| `image.repository` | `jacobalberty/unifi` | Image repository |
| `image.tag` | `5.11.50` | Image tag. Possible values listed [here][docker]. |
| `image.pullPolicy` | `IfNotPresent` | Image pull policy |
| `strategyType` | `Recreate` | Specifies the strategy used to replace old Pods by new ones |
| `guiService.type` | `ClusterIP` | Kubernetes service type for the Unifi GUI |
| `guiService.port` | `8443` | Kubernetes port where the Unifi GUI is exposed |
| `guiService.annotations` | `{}` | Service annotations for the Unifi GUI |
| `guiService.labels` | `{}` | Custom labels |
| `guiService.loadBalancerIP` | `{}` | Loadbalance IP for the Unifi GUI |
| `guiService.loadBalancerSourceRanges` | None | List of IP CIDRs allowed access to load balancer (if supported) |
| `guiService.externalTrafficPolicy` | `Cluster` | Set the externalTrafficPolicy in the Service to either Cluster or Local |
| `captivePortalService.enabled` | `false` | Install the captive portal service (needed if you want guest captive portal) |
| `captivePortalService.type` | `ClusterIP` | Kubernetes service type for the captive portal |
| `captivePortalService.http` | `8880` | Kubernetes port where the captive portal is exposed |
| `captivePortalService.https` | `8843` | Kubernetes port where the captive portal is exposed (with SSL) |
| `captivePortalService.annotations` | `{}` | Service annotations for the captive portal |
| `captivePortalService.labels` | `{}` | Custom labels |
| `captivePortalService.loadBalancerIP` | `{}` | Loadbalance IP for the Unifi GUI |
| `captivePortalService.loadBalancerSourceRanges` | None | List of IP CIDRs allowed access to load balancer (if supported) |
| `captivePortalService.externalTrafficPolicy` | `Cluster` | Set the externalTrafficPolicy in the Service to either Cluster or Local |
| `captivePortalService.ingress.enabled` | `false` | Enables Ingress (for the captive portal, the main ingress needs to be enabled for the controller to be accessible) |
| `captivePortalService.ingress.annotations` | `{}` | Ingress annotations for the captive portal |
| `captivePortalService.ingress.labels` | `{}` | Custom labels for the captive portal |
| `captivePortalService.ingress.path` | `/` | Ingress path for the captive portal |
| `captivePortalService.ingress.hosts` | `chart-example.local` | Ingress accepted hostnames for the captive portal |
| `captivePortalService.ingress.tls` | `[]` | Ingress TLS configuration for the captive portal |
| `controllerService.type` | `NodePort` | Kubernetes service type for the Unifi Controller communication |
| `controllerService.port` | `8080` | Kubernetes port where the Unifi Controller is exposed - this needs to be reachable by the unifi devices on the network |
| `controllerService.annotations` | `{}` | Service annotations for the Unifi Controller |
| `controllerService.labels` | `{}` | Custom labels |
| `controllerService.loadBalancerIP` | `{}` | Loadbalance IP for the Unifi Controller |
| `controllerService.loadBalancerSourceRanges` | None | List of IP CIDRs allowed access to load balancer (if supported) |
| `controllerService.externalTrafficPolicy` | `Cluster` | Set the externalTrafficPolicy in the Service to either Cluster or Local |
| `stunService.type` | `NodePort` | Kubernetes service type for the Unifi STUN |
| `stunService.port` | `3478` | Kubernetes UDP port where the Unifi STUN is exposed |
| `stunService.annotations` | `{}` | Service annotations for the Unifi STUN |
| `stunService.labels` | `{}` | Custom labels |
| `stunService.loadBalancerIP` | `{}` | Loadbalance IP for the Unifi STUN |
| `stunService.loadBalancerSourceRanges` | None | List of IP CIDRs allowed access to load balancer (if supported) |
| `stunService.externalTrafficPolicy` | `Cluster` | Set the externalTrafficPolicy in the Service to either Cluster or Local |
| `discoveryService.type` | `NodePort` | Kubernetes service type for AP discovery |
| `discoveryService.port` | `10001` | Kubernetes UDP port for AP discovery |
| `discoveryService.annotations` | `{}` | Service annotations for AP discovery |
| `discoveryService.labels` | `{}` | Custom labels |
| `discoveryService.loadBalancerIP` | `{}` | Loadbalance IP for AP discovery |
| `discoveryService.loadBalancerSourceRanges` | None | List of IP CIDRs allowed access to load balancer (if supported) |
| `discoveryService.externalTrafficPolicy` | `Cluster` | Set the externalTrafficPolicy in the Service to either Cluster or Local |
| `unifiedService.enabled` | `false` | Use a single service for GUI, controller, STUN, and discovery |
| `unifiedService.type` | `ClusterIP` | Kubernetes service type for the unified service |
| `unifiedService.annotations` | `{}` | Annotations for the unified service |
| `unifiedService.labels` | `{}` | Custom labels for the unified service |
| `unifiedService.loadBalancerIP` | None | Load balancer IP for the unified service |
| `unifiedService.loadBalancerSourceRanges` | None | List of IP CIDRs allowed access to the load balancer (if supported) |
| `unifiedService.externalTrafficPolicy` | `Cluster` | Set the externalTrafficPolicy in the service to either Cluster or Local |
| `ingress.enabled` | `false` | Enables Ingress |
| `ingress.annotations` | `{}` | Ingress annotations |
| `ingress.labels` | `{}` | Custom labels |
| `ingress.path` | `/` | Ingress path |
| `ingress.hosts` | `chart-example.local` | Ingress accepted hostnames |
| `ingress.tls` | `[]` | Ingress TLS configuration |
| `timezone` | `UTC` | Timezone the Unifi controller should run as, e.g. 'America/New York' |
| `runAsRoot` | `false` | Run the controller as UID0 (root user); if set to false, will give container SETFCAP instead |
| `UID` | `999` | Run the controller as user UID |
| `GID` | `999` | Run the controller as group GID |
| `mongodb.enabled` | `false` | Use external MongoDB for data storage |
| `mongodb.dbUri` | `mongodb://mongo/unifi` | external MongoDB URI |
| `mongodb.statDbUri` | `mongodb://mongo/unifi_stat` | external MongoDB statdb URI |
| `mongodb.databaseName` | `unifi` | external MongoDB database name |
| `persistence.enabled` | `true` | Use persistent volume to store data |
| `persistence.size` | `5Gi` | Size of persistent volume claim |
| `persistence.existingClaim` | `nil` | Use an existing PVC to persist data |
| `persistence.storageClass` | `-` | Type of persistent volume claim |
| `persistence.accessModes` | `[]` | Persistence access modes |
| `extraConfigFiles` | `{}` | Dictionary containing files mounted to `/configmap` inside the pod (See [values.yaml](values.yaml) for examples) |
| `extraJvmOpts` | `[]` | List of additional JVM options, e.g. `["-Dlog4j.configurationFile=file:/configmap/log4j2.xml"]` |
| `resources` | `{}` | CPU/Memory resource requests/limits |
| `nodeSelector` | `{}` | Node labels for pod assignment |
| `tolerations` | `[]` | Toleration labels for pod assignment |
| `affinity` | `{}` | Affinity settings for pod assignment |
| `podAnnotations` | `{}` | Key-value pairs to add as pod annotations |
| `deploymentAnnotations` | `{}` | Key-value pairs to add as deployment annotations |
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
@ -123,6 +138,9 @@ Read through the [values.yaml](values.yaml) file. It has several commented out s
- `guiService`: Represents the main web UI and is what one would normally point
the ingress to.
- `captivePortalService`: This service is used to allow the captive portal webpage
to be accessible. It needs to be reachable by the clients connecting to your guest
network.
- `controllerService`: This is needed in order for the unifi devices to talk to
the controller and must be otherwise exposed to the network where the unifi
devices run. If you run this as a `NodePort` (the default setting), make sure
@ -136,10 +154,12 @@ Read through the [values.yaml](values.yaml) file. It has several commented out s
article][ubnt 4] for more information.
## Ingress and HTTPS
Unifi does [not support HTTP][unifi] so if you wish to use the guiService, you
need to ensure that you use a backend transport of HTTPS.
An example entry in `values.yaml` to achieve this is as follows:
```
ingress:
enabled: true

View File

@ -0,0 +1,39 @@
{{- if (and .Values.captivePortalService.ingress.enabled (not .Values.unifiedService.enabled)) }}
{{- $fullName := include "unifi.fullname" . -}}
{{- $ingressPath := .Values.captivePortalService.ingress.path -}}
{{- $unifiedServiceEnabled := .Values.unifiedService.enabled -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $fullName }}-captive
labels:
app.kubernetes.io/name: {{ include "unifi.name" . }}
helm.sh/chart: {{ include "unifi.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- with .Values.captivePortalService.ingress.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
spec:
{{- if .Values.captivePortalService.ingress.tls }}
tls:
{{- range .Values.captivePortalService.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.captivePortalService.ingress.hosts }}
- host: {{ . }}
http:
paths:
- path: {{ $ingressPath }}
backend:
serviceName: {{ $fullName }}-captivePortalService
servicePort: captive-http
{{- end }}
{{- end }}

View File

@ -0,0 +1,61 @@
{{ if (and .Values.captivePortalService.enabled (not .Values.unifiedService.enabled)) }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "unifi.fullname" . }}-captivePortalService
labels:
app.kubernetes.io/name: {{ include "unifi.name" . }}
helm.sh/chart: {{ include "unifi.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- if .Values.captivePortalService.labels }}
{{ toYaml .Values.captivePortalService.labels | indent 4 }}
{{- end }}
{{- with .Values.captivePortalService.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
spec:
{{- if (or (eq .Values.captivePortalService.type "ClusterIP") (empty .Values.captivePortalService.type)) }}
type: ClusterIP
{{- if .Values.captivePortalService.clusterIP }}
clusterIP: {{ .Values.captivePortalService.clusterIP }}
{{end}}
{{- else if eq .Values.captivePortalService.type "LoadBalancer" }}
type: {{ .Values.captivePortalService.type }}
{{- if .Values.captivePortalService.loadBalancerIP }}
loadBalancerIP: {{ .Values.captivePortalService.loadBalancerIP }}
{{- end }}
{{- if .Values.captivePortalService.loadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{ toYaml .Values.captivePortalService.loadBalancerSourceRanges | indent 4 }}
{{- end -}}
{{- else }}
type: {{ .Values.captivePortalService.type }}
{{- end }}
{{- if .Values.captivePortalService.externalIPs }}
externalIPs:
{{ toYaml .Values.captivePortalService.externalIPs | indent 4 }}
{{- end }}
{{- if .Values.captivePortalService.externalTrafficPolicy }}
externalTrafficPolicy: {{ .Values.captivePortalService.externalTrafficPolicy }}
{{- end }}
ports:
- port: {{ .Values.captivePortalService.http }}
targetPort: captive-http
protocol: TCP
name: captive-http
{{ if (and (eq .Values.captivePortalService.type "NodePort") (not (empty .Values.captivePortalService.nodePorts.http))) }}
nodePort: {{.Values.captivePortalService.nodePorts.http}}
{{ end }}
- port: {{ .Values.captivePortalService.https }}
targetPort: captive-https
protocol: TCP
name: captive-https
{{ if (and (eq .Values.captivePortalService.type "NodePort") (not (empty .Values.captivePortalService.nodePorts.https))) }}
nodePort: {{.Values.captivePortalService.nodePorts.https}}
{{ end }}
selector:
app.kubernetes.io/name: {{ include "unifi.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{ end }}

View File

@ -50,6 +50,14 @@ spec:
- name: stun
containerPort: 3478
protocol: UDP
{{ if .Values.captivePortalService.enabled }}
- name: captive-http
containerPort: 8880
protocol: TCP
- name: captive-https
containerPort: 8843
protocol: TCP
{{ end }}
{{- if not .Values.runAsRoot }}
securityContext:
capabilities:

View File

@ -69,6 +69,23 @@ spec:
{{ if (and (eq .Values.unifiedService.type "NodePort") (not (empty .Values.guiService.nodePort))) }}
nodePort: {{.Values.guiService.nodePort}}
{{ end }}
{{ if .Values.captivePortalService.enabled }}
- name: captive-http
port: {{ .Values.captivePortalService.http }}
protocol: TCP
targetPort: captive-http
{{ if (and (eq .Values.unifiedService.type "NodePort") (not (empty .Values.captivePortalService.http))) }}
nodePort: {{.Values.captivePortalService.nodePorts.http}}
{{ end }}
- name: captive-https
port: {{ .Values.captivePortalService.https }}
protocol: TCP
targetPort: captive-https
{{ if (and (eq .Values.unifiedService.type "NodePort") (not (empty .Values.captivePortalService.https))) }}
nodePort: {{.Values.captivePortalService.nodePorts.https}}
{{ end }}
{{ end }}
selector:
app.kubernetes.io/name: {{ include "unifi.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}

View File

@ -59,6 +59,47 @@ guiService:
## Set the externalTrafficPolicy in the Service to either Cluster or Local
# externalTrafficPolicy: Cluster
captivePortalService:
enabled: false
type: ClusterIP
http: 8880
https: 8843
## Specify the nodePort value for the LoadBalancer and NodePort service types.
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
##
# nodePort:
# http: 8880
# https: 8843
## Provide any additional annotations which may be required. This can be used to
## set the LoadBalancer service type to internal only.
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer
##
annotations: {}
labels: {}
## Use loadBalancerIP to request a specific static IP,
## otherwise leave blank
##
loadBalancerIP:
# loadBalancerSourceRanges: []
## Set the externalTrafficPolicy in the Service to either Cluster or Local
# externalTrafficPolicy: Cluster
# Ingress settings only for the captive portal
ingress:
enabled: false
annotations: {}
# nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
path: /
hosts:
- chart-example.local
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
controllerService:
type: NodePort
port: 8080