diff --git a/.ci/docker-compose-file/python/pytest.sh b/.ci/docker-compose-file/python/pytest.sh index eacbecc3b..0189c86ba 100755 --- a/.ci/docker-compose-file/python/pytest.sh +++ b/.ci/docker-compose-file/python/pytest.sh @@ -10,7 +10,7 @@ LB="haproxy" apk update && apk add git curl git clone -b develop-4.0 https://github.com/emqx/paho.mqtt.testing.git /paho.mqtt.testing -pip install pytest +pip install pytest==6.2.5 pytest -v /paho.mqtt.testing/interoperability/test_client/V5/test_connect.py -k test_basic --host "$LB" RESULT=$? diff --git a/deploy/charts/emqx/README.md b/deploy/charts/emqx/README.md index cca0e88bc..4837ffced 100644 --- a/deploy/charts/emqx/README.md +++ b/deploy/charts/emqx/README.md @@ -1,14 +1,14 @@ # Introduction -This chart bootstraps an emqx deployment on a Kubernetes cluster using the Helm package manager. +This chart bootstraps an [EMQ X](https://www.emqx.io/) deployment on a [Kubernetes](https://kubernetes.io/) (K8s) cluster using the [Helm](https://helm.sh/) package manager. # Prerequisites -+ Kubernetes 1.6+ -+ Helm ++ [Kubernetes](https://kubernetes.io/) 1.6+ ++ [Helm](https://helm.sh/) # Installing the Chart To install the chart with the release name `my-emqx`: -+ From github ++ From github ``` $ git clone https://github.com/emqx/emqx.git $ cd emqx/deploy/charts/emqx @@ -25,55 +25,107 @@ To install the chart with the release name `my-emqx`: # Uninstalling the Chart To uninstall/delete the `my-emqx` deployment: ``` -$ helm del my-emqx +$ helm del my-emqx ``` # Configuration -The following table lists the configurable parameters of the emqx chart and their default values. +The following sections describe the configurable parameters of the chart and their default values. +## [K8s]((https://kubernetes.io/)) specific settings +The following table lists the configurable K8s parameters of the [EMQ X](https://www.emqx.io/) chart and their default values. +Parameter | Description | Default Value +--- | --- | --- +`replicaCount` | It is recommended to have odd number of nodes in a cluster, otherwise the emqx cluster cannot be automatically healed in case of net-split. | `3` +`image.tag` | EMQ X Image tag (defaults to `.Chart.AppVersion`) | `nil` +`image.repository` | EMQ X Image repository | `emqx/emqx` +`image.pullPolicy` | The image pull policy | `IfNotPresent` +`image.pullSecrets ` | The image pull secrets (does not add image pull secrets to deployed pods) |``[]`` +`recreatePods` | Forces the recreation of pods during upgrades, which can be useful to always apply the most recent configuration. | `false` +`persistence.enabled` | Enable EMQ X persistence using PVC | `false` +`persistence.storageClass` | Storage class of backing PVC (uses alpha storage class annotation) | `nil` +`persistence.existingClaim` | EMQ X data Persistent Volume existing claim name, evaluated as a template | `""` +`persistence.accessMode` | PVC Access Mode for EMQ X volume | `ReadWriteOnce` +`persistence.size` | PVC Storage Request for EMQ X volume | `20Mi` +`initContainers` | Containers that run before the creation of EMQ X containers. They can contain utilities or setup scripts. |`{}` +`resources` | CPU/Memory resource requests/limits |`{}` +`nodeSelector` | Node labels for pod assignment |`{}` +`tolerations` | Toleration labels for pod assignment |``[]`` +`affinity` | Map of node/pod affinities |`{}` +`service.type` | Kubernetes Service type. | `ClusterIP` +`service.mqtt` | Port for MQTT. | `1883` +`service.mqttssl` | Port for MQTT(SSL). | `8883` +`service.mgmt` | Port for mgmt API. | `8081` +`service.ws` | Port for WebSocket/HTTP. | `8083` +`service.wss` | Port for WSS/HTTPS. | `8084` +`service.dashboard` | Port for dashboard. | `18083` +`service.nodePorts.mqtt` | Kubernetes node port for MQTT. | `nil` +`service.nodePorts.mqttssl` | Kubernetes node port for MQTT(SSL). | `nil` +`service.nodePorts.mgmt` | Kubernetes node port for mgmt API. | `nil` +`service.nodePorts.ws` | Kubernetes node port for WebSocket/HTTP. | `nil` +`service.nodePorts.wss` | Kubernetes node port for WSS/HTTPS. | `nil` +`service.nodePorts.dashboard` | Kubernetes node port for dashboard. | `nil` +`service.loadBalancerIP` | loadBalancerIP for Service | `nil` +`service.loadBalancerSourceRanges` | Address(es) that are allowed when service is LoadBalancer | `[]` +`service.externalIPs` | ExternalIPs for the service | `[]` +`service.annotations` | Service annotations (evaluated as a template) | `{}` +`ingress.dashboard.enabled` | Enable ingress for EMQ X Dashboard | false +`ingress.dashboard.ingressClassName` | Set the ingress class for EMQ X Dashboard +`ingress.dashboard.path` | Ingress path for EMQ X Dashboard | `/` +`ingress.dashboard.hosts` | Ingress hosts for EMQ X Mgmt API | dashboard.emqx.local +`ingress.dashboard.tls` | Ingress tls for EMQ X Mgmt API | `[]` +`ingress.dashboard.annotations` | Ingress annotations for EMQ X Mgmt API | `{}` +`ingress.mgmt.enabled` | Enable ingress for EMQ X Mgmt API | `false` +`ingress.mqtt.ingressClassName` | Set the ingress class for EMQ X Mgmt API | `nil` +`ingress.mgmt.path` | Ingress path for EMQ X Mgmt API | `/` +`ingress.mgmt.hosts` | Ingress hosts for EMQ X Mgmt API | `api.emqx.local` +`ingress.mgmt.tls` | Ingress tls for EMQ X Mgmt API | `[]` +`ingress.mgmt.annotations` | Ingress annotations for EMQ X Mgmt API | `{}` +`ingress.wss.enabled` | Enable ingress for EMQ X Mgmt API | `false` +`ingress.wss.ingressClassName` | Set the ingress class for EMQ X Mgmt API | `nil` +`ingress.wss.path` | Ingress path for EMQ X WSS | `/` +`ingress.wss.hosts` | Ingress hosts for EMQ X WSS | `wss.emqx.local` +`ingress.wss.tls` | Ingress tls for EMQ X WSS | `[]` +`ingress.wss.annotations` | Ingress annotations for EMQ X WSS | `{}` +`extraEnv` | Aditional container env vars | `[]` +`extraEnvFrom` | Aditional container env from vars (eg. [config map](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/), [secrets](https://kubernetes.io/docs/concepts/configuration/secret/) | `[]` +`extraArgs` | Additional container executable arguments | `[]` +`extraVolumes` | Additional container volumes (eg. for mounting certs from secrets) | `[]` +`extraVolumeMounts` | Additional container volume mounts (eg. for mounting certs from secrets) | `[]` -| Parameter | Description | Default Value | -| --- | --- | --- | -| `replicaCount` | It is recommended to have odd number of nodes in a cluster, otherwise the emqx cluster cannot be automatically healed in case of net-split. |3| -| `image.repository` | EMQ X Image name |emqx/emqx| -| `image.pullPolicy` | The image pull policy |IfNotPresent| -| `image.pullSecrets ` | The image pull secrets |`[]` (does not add image pull secrets to deployed pods)| -| `recreatePods` | Forces the recreation of pods during upgrades, which can be useful to always apply the most recent configuration. | false | -| `persistence.enabled` | Enable EMQX persistence using PVC |false| -| `persistence.storageClass` | Storage class of backing PVC |`nil` (uses alpha storage class annotation)| -| `persistence.existingClaim` | EMQ X data Persistent Volume existing claim name, evaluated as a template |""| -| `persistence.accessMode` | PVC Access Mode for EMQX volume |ReadWriteOnce| -| `persistence.size` | PVC Storage Request for EMQX volume |20Mi| -| `initContainers` | Containers that run before the creation of EMQX containers. They can contain utilities or setup scripts. |`{}`| -| `resources` | CPU/Memory resource requests/limits |{}| -| `nodeSelector` | Node labels for pod assignment |`{}`| -| `tolerations` | Toleration labels for pod assignment |`[]`| -| `affinity` | Map of node/pod affinities |`{}`| -| `service.type` | Kubernetes Service type. |ClusterIP| -| `service.mqtt` | Port for MQTT. |1883| -| `service.mqttssl` | Port for MQTT(SSL). |8883| -| `service.mgmt` | Port for mgmt API. |8081| -| `service.ws` | Port for WebSocket/HTTP. |8083| -| `service.wss` | Port for WSS/HTTPS. |8084| -| `service.dashboard` | Port for dashboard. |18083| -| `service.nodePorts.mqtt` | Kubernetes node port for MQTT. |nil| -| `service.nodePorts.mqttssl` | Kubernetes node port for MQTT(SSL). |nil| -| `service.nodePorts.mgmt` | Kubernetes node port for mgmt API. |nil| -| `service.nodePorts.ws` | Kubernetes node port for WebSocket/HTTP. |nil| -| `service.nodePorts.wss` | Kubernetes node port for WSS/HTTPS. |nil| -| `service.nodePorts.dashboard` | Kubernetes node port for dashboard. |nil| -| `service.loadBalancerIP` | loadBalancerIP for Service | nil | -| `service.loadBalancerSourceRanges` | Address(es) that are allowed when service is LoadBalancer | [] | -| `service.externalIPs` | ExternalIPs for the service | [] | -| `service.annotations` | Service annotations | {}(evaluated as a template)| -| `ingress.dashboard.enabled` | Enable ingress for EMQX Dashboard | false | -| `ingress.dashboard.path` | Ingress path for EMQX Dashboard | / | -| `ingress.dashboard.hosts` | Ingress hosts for EMQX Mgmt API | dashboard.emqx.local | -| `ingress.dashboard.tls` | Ingress tls for EMQX Mgmt API | [] | -| `ingress.dashboard.annotations` | Ingress annotations for EMQX Mgmt API | {} | -| `ingress.mgmt.enabled` | Enable ingress for EMQX Mgmt API | false | -| `ingress.mgmt.path` | Ingress path for EMQX Mgmt API | / | -| `ingress.mgmt.hosts` | Ingress hosts for EMQX Mgmt API | api.emqx.local | -| `ingress.mgmt.tls` | Ingress tls for EMQX Mgmt API | [] | -| `ingress.mgmt.annotations` | Ingress annotations for EMQX Mgmt API | {} | -| `emqxConfig` | Emqx configuration item, see the [documentation](https://hub.docker.com/r/emqx/emqx) | | -| `emqxAclConfig` | Emqx acl configuration item, see the [documentation](https://docs.emqx.io/broker/latest/en/advanced/acl-file.html) | | +## EMQ X specific settings +The following table lists the configurable [EMQ X](https://www.emqx.io/)-specific parameters of the chart and their default values. +Parameter | Description | Default Value +--- | --- | --- +`emqxConfig` | Map of [configuration](https://www.emqx.io/docs/en/latest/configuration/configuration.html) items expressed as [environment variables](https://www.emqx.io/docs/en/v4.3/configuration/environment-variable.html) (prefix can be omitted) or using the configuration files [namespaced dotted notation](https://www.emqx.io/docs/en/latest/configuration/configuration.html) | `nil` +`emqxLicenseSecretName` | Name of the secret that holds the license information | `nil` +`emqxAclConfig` | [ACL](https://docs.emqx.io/broker/latest/en/advanced/acl-file.html) configuration | `{allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}. {allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}. {deny, all, subscribe, ["$SYS/#", {eq, "#"}]}. {allow, all}.` +`emqxLoadedModules` | Modules to load on startup | `{emqx_mod_acl_internal, true}. {emqx_mod_presence, true}. {emqx_mod_delayed, false}. {emqx_mod_rewrite, false}. {emqx_mod_subscription, false}. {emqx_mod_topic_metrics, false}.` +`emqxLoadedPlugins` | Plugins to load on startup | `{emqx_management, true}. {emqx_recon, true}. {emqx_retainer, true}. {emqx_dashboard, true}. {emqx_telemetry, true}. {emqx_rule_engine, true}. {emqx_bridge_mqtt, false}.` + +# Examples +This section provides some examples for the configuration of common scenarios. +## Enable Websockets SSL via [nginx-ingress community controller](https://kubernetes.github.io/ingress-nginx/) +The following settings describe a working scenario for acessing [EMQ X](https://www.emqx.io/) Websockets with SSL termination at the [nginx-ingress community controller](https://kubernetes.github.io/ingress-nginx/). +```yaml +ingress: + wss: + enabled: true + # ingressClassName: nginx + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "http" + nginx.ingress.kubernetes.io/use-forwarded-headers: "true" + nginx.ingress.kubernetes.io/enable-real-ip: "true" + nginx.ingress.kubernetes.io/proxy-request-buffering: "off" + nginx.ingress.kubernetes.io/proxy-connect-timeout: "120" + nginx.ingress.kubernetes.io/proxy-http-version: "1.1" + nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" + nginx.ingress.kubernetes.io/use-proxy-protocol: "false" + nginx.ingress.kubernetes.io/proxy-protocol-header-timeout: "5s" + path: /mqtt + hosts: + - myhost.example.com + tls: + - hosts: + - myhost.example.com + secretName: myhost-example-com-tls # Name of the secret that holds the certificates for the domain +``` diff --git a/deploy/charts/emqx/templates/StatefulSet.yaml b/deploy/charts/emqx/templates/StatefulSet.yaml index c6e225e3a..e155d71e2 100644 --- a/deploy/charts/emqx/templates/StatefulSet.yaml +++ b/deploy/charts/emqx/templates/StatefulSet.yaml @@ -1,3 +1,12 @@ +{{ $configData := printf "%s\n%s\n%s\n%s" + (include (print $.Template.BasePath "/configmap.env.yaml") .) + (include (print $.Template.BasePath "/configmap.acl.yaml") .) + (include (print $.Template.BasePath "/configmap.loadedPlugins.yaml") .) + (include (print $.Template.BasePath "/configmap.loadedModules.yaml") .) }} + ## Compatible with previous misspellings +{{ $licenseSecretName := coalesce .Values.emqxLicenseSecretName .Values.emqxLicneseSecretName }} +{{ $image := printf "%s:%s" .Values.image.repository (default .Values.image.tag .Chart.AppVersion) }} + apiVersion: apps/v1 kind: StatefulSet metadata: @@ -50,28 +59,34 @@ spec: app.kubernetes.io/instance: {{ .Release.Name }} {{- if .Values.recreatePods }} annotations: - checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum | quote }} + checksum/config: {{ $configData | sha256sum | quote }} {{- end }} spec: volumes: + {{- if .Values.emqxLoadedPlugins }} - name: emqx-loaded-plugins configMap: name: {{ include "emqx.fullname" . }}-loaded-plugins items: - key: loaded_plugins path: loaded_plugins + {{- end }} + {{- if .Values.emqxLoadedModules }} - name: emqx-loaded-modules configMap: name: {{ include "emqx.fullname" . }}-loaded-modules items: - key: loaded_modules path: loaded_modules + {{- end }} + {{- if .Values.emqxAclConfig }} - name: emqx-acl configMap: name: {{ include "emqx.fullname" . }}-acl items: - key: acl.conf path: acl.conf + {{- end }} {{- if not .Values.persistence.enabled }} - name: emqx-data emptyDir: {} @@ -82,15 +97,13 @@ spec: claimName: {{ tpl . $ }} {{- end }} {{- end }} - {{- if .Values.emqxLicenseSecretName }} + {{- if .Values.extraVolumes }} +{{ toYaml .Values.extraVolumes | indent 6 }} + {{- end }} + {{- if $licenseSecretName }} - name: emqx-license secret: - secretName: {{ .Values.emqxLicenseSecretName }} - ## Compatible with previous misspellings - {{- else if .Values.emqxLicneseSecretName }} - - name: emqx-license - secret: - secretName: {{ .Values.emqxLicneseSecretName }} + secretName: {{ $licenseSecretName }} {{- end }} {{- if eq (.Values.emqxConfig.EMQX_CLUSTER__DISCOVERY | default "k8s") "k8s" }} serviceAccountName: {{ include "emqx.fullname" . }} @@ -110,7 +123,7 @@ spec: {{- end }} containers: - name: emqx - image: "{{ .Values.image.repository }}:{{ .Chart.AppVersion }}" + image: {{ $image }} imagePullPolicy: {{ .Values.image.pullPolicy }} {{- if .Values.containerSecurityContext.enabled }} securityContext: {{- omit .Values.containerSecurityContext "enabled" | toYaml | nindent 12 }} @@ -139,34 +152,47 @@ spec: - name: ekka containerPort: 4370 envFrom: - - configMapRef: - name: {{ include "emqx.fullname" . }}-env + - configMapRef: + name: {{ include "emqx.fullname" . }}-env + {{- if .Values.extraEnvFrom }} +{{ toYaml .Values.extraEnvFrom | indent 10 }} + {{- end }} + {{- if .Values.extraEnv }} + env: +{{ toYaml .Values.extraEnv | indent 10 }} + {{- end }} resources: {{ toYaml .Values.resources | indent 12 }} volumeMounts: - name: emqx-data mountPath: "/opt/emqx/data" + {{- if .Values.emqxAclConfig }} - name: emqx-acl mountPath: "/opt/emqx/etc/acl.conf" subPath: "acl.conf" + {{- end }} + {{- if .Values.emqxLoadedPlugins }} - name: emqx-loaded-plugins mountPath: "/opt/emqx/data/loaded_plugins" subPath: "loaded_plugins" + {{- end }} + {{- if .Values.emqxLoadedModules }} - name: emqx-loaded-modules mountPath: "/opt/emqx/data/loaded_modules" subPath: "loaded_modules" - {{ if .Values.emqxLicenseSecretName }} - - name: emqx-license - mountPath: "/opt/emqx/etc/emqx.lic" - subPath: "emqx.lic" - readOnly: true - ## Compatible with previous misspellings - {{ else if .Values.emqxLicneseSecretName }} + {{- end }} + {{- if $licenseSecretName }} - name: emqx-license mountPath: "/opt/emqx/etc/emqx.lic" subPath: "emqx.lic" readOnly: true {{ end }} + {{- if and .Values.extraVolumes .Values.extraVolumeMounts }} +{{ toYaml .Values.extraVolumeMounts | indent 10 }} + {{- end }} + {{- if .Values.extraArgs }} + args: {{ toYaml .Values.extraArgs | nindent 10 }} + {{- end }} readinessProbe: httpGet: path: /status diff --git a/deploy/charts/emqx/templates/configmap.acl.yaml b/deploy/charts/emqx/templates/configmap.acl.yaml new file mode 100644 index 000000000..25f67b42b --- /dev/null +++ b/deploy/charts/emqx/templates/configmap.acl.yaml @@ -0,0 +1,15 @@ +{{ if .Values.emqxAclConfig }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "emqx.fullname" . }}-acl + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "emqx.name" . }} + helm.sh/chart: {{ include "emqx.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +data: + "acl.conf": | + {{ .Values.emqxAclConfig }} +{{ end }} diff --git a/deploy/charts/emqx/templates/configmap.env.yaml b/deploy/charts/emqx/templates/configmap.env.yaml new file mode 100644 index 000000000..04a72033c --- /dev/null +++ b/deploy/charts/emqx/templates/configmap.env.yaml @@ -0,0 +1,20 @@ +{{- if .Values.emqxConfig }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "emqx.fullname" . }}-env + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "emqx.name" . }} + helm.sh/chart: {{ include "emqx.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +data: + {{- range $index, $value := .Values.emqxConfig }} + {{- if ne $value nil }} + {{- $key := (regexReplaceAllLiteral "\\." (regexReplaceAllLiteral "EMQX[_\\.]" (upper (trimAll " " $index)) "") "__") }} + {{ print "EMQX_" $key }}: "{{ tpl (printf "%v" $value) $ }}" + {{- end }} + {{- end}} + +{{- end }} diff --git a/deploy/charts/emqx/templates/configmap.loadedModules.yaml b/deploy/charts/emqx/templates/configmap.loadedModules.yaml new file mode 100644 index 000000000..45c97d4d0 --- /dev/null +++ b/deploy/charts/emqx/templates/configmap.loadedModules.yaml @@ -0,0 +1,15 @@ +{{ if .Values.emqxLoadedModules }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "emqx.fullname" . }}-loaded-modules + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "emqx.name" . }} + helm.sh/chart: {{ include "emqx.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +data: + "loaded_modules": | + {{ .Values.emqxLoadedModules }} +{{ end }} diff --git a/deploy/charts/emqx/templates/configmap.loadedPlugins.yaml b/deploy/charts/emqx/templates/configmap.loadedPlugins.yaml new file mode 100644 index 000000000..242c1ab01 --- /dev/null +++ b/deploy/charts/emqx/templates/configmap.loadedPlugins.yaml @@ -0,0 +1,15 @@ +{{ if .Values.emqxLoadedPlugins }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "emqx.fullname" . }}-loaded-plugins + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "emqx.name" . }} + helm.sh/chart: {{ include "emqx.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +data: + "loaded_plugins": | + {{ .Values.emqxLoadedPlugins }} +{{ end }} diff --git a/deploy/charts/emqx/templates/configmap.yaml b/deploy/charts/emqx/templates/configmap.yaml deleted file mode 100644 index 328df2000..000000000 --- a/deploy/charts/emqx/templates/configmap.yaml +++ /dev/null @@ -1,59 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "emqx.fullname" . }}-env - namespace: {{ .Release.Namespace }} - labels: - app.kubernetes.io/name: {{ include "emqx.name" . }} - helm.sh/chart: {{ include "emqx.chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} -data: - {{- range $index, $value := .Values.emqxConfig}} - {{$index}}: "{{ tpl (printf "%v" $value) $ }}" - {{- end}} - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "emqx.fullname" . }}-acl - namespace: {{ .Release.Namespace }} - labels: - app.kubernetes.io/name: {{ include "emqx.name" . }} - helm.sh/chart: {{ include "emqx.chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} -data: - "acl.conf": | - {{ .Values.emqxAclConfig }} - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "emqx.fullname" . }}-loaded-plugins - namespace: {{ .Release.Namespace }} - labels: - app.kubernetes.io/name: {{ include "emqx.name" . }} - helm.sh/chart: {{ include "emqx.chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} -data: - "loaded_plugins": | - {{ .Values.emqxLoadedPlugins }} - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "emqx.fullname" . }}-loaded-modules - namespace: {{ .Release.Namespace }} - labels: - app.kubernetes.io/name: {{ include "emqx.name" . }} - helm.sh/chart: {{ include "emqx.chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} -data: - "loaded_modules": | - {{ .Values.emqxLoadedModules }} diff --git a/deploy/charts/emqx/templates/ingress.yaml b/deploy/charts/emqx/templates/ingress.dashboard.yaml similarity index 51% rename from deploy/charts/emqx/templates/ingress.yaml rename to deploy/charts/emqx/templates/ingress.dashboard.yaml index c6d7f7fa1..9ea06cdc4 100644 --- a/deploy/charts/emqx/templates/ingress.yaml +++ b/deploy/charts/emqx/templates/ingress.dashboard.yaml @@ -14,10 +14,15 @@ metadata: helm.sh/chart: {{ include "emqx.chart" . }} app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} - {{- if .Values.ingress.dashboard.annotations }} + {{- if or .Values.ingress.annotations .Values.ingress.dashboard.annotations }} annotations: + {{- if .Values.ingress.annotations }} + {{- toYaml .Values.ingress.annotations | nindent 4 }} + {{- end }} + {{- if .Values.ingress.dashboard.annotations }} {{- toYaml .Values.ingress.dashboard.annotations | nindent 4 }} {{- end }} + {{- end }} spec: {{- if and .Values.ingress.dashboard.ingressClassName (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} ingressClassName: {{ .Values.ingress.dashboard.ingressClassName }} @@ -48,53 +53,3 @@ spec: {{- end }} --- {{- end }} -{{- if .Values.ingress.mgmt.enabled -}} -{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} -apiVersion: networking.k8s.io/v1 -{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} -apiVersion: networking.k8s.io/v1beta1 -{{- else -}} -apiVersion: extensions/v1beta1 -{{- end }} -kind: Ingress -metadata: - name: {{ printf "%s-%s" (include "emqx.fullname" .) "mgmt" }} - labels: - app.kubernetes.io/name: {{ include "emqx.name" . }} - helm.sh/chart: {{ include "emqx.chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - {{- if .Values.ingress.mgmt.annotations }} - annotations: - {{- toYaml .Values.ingress.mgmt.annotations | nindent 4 }} - {{- end }} -spec: -{{- if and .Values.ingress.mgmt.ingressClassName (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} - ingressClassName: {{ .Values.ingress.mgmt.ingressClassName }} -{{- end }} - rules: - {{- range $host := .Values.ingress.mgmt.hosts }} - - host: {{ $host }} - http: - paths: - - path: / - {{- if (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} - pathType: ImplementationSpecific - {{- end }} - backend: - {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} - service: - name: {{ include "emqx.fullname" $ }} - port: - number: {{ $.Values.service.mgmt }} - {{- else }} - serviceName: {{ include "emqx.fullname" $ }} - servicePort: {{ $.Values.service.mgmt }} - {{- end }} - {{- end -}} - {{- if .Values.ingress.mgmt.tls }} - tls: - {{- toYaml .Values.ingress.mgmt.tls | nindent 4 }} - {{- end }} ---- -{{- end }} \ No newline at end of file diff --git a/deploy/charts/emqx/templates/ingress.mgmt.yaml b/deploy/charts/emqx/templates/ingress.mgmt.yaml new file mode 100644 index 000000000..c9abe79a9 --- /dev/null +++ b/deploy/charts/emqx/templates/ingress.mgmt.yaml @@ -0,0 +1,54 @@ +{{- if .Values.ingress.mgmt.enabled -}} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ printf "%s-%s" (include "emqx.fullname" .) "mgmt" }} + labels: + app.kubernetes.io/name: {{ include "emqx.name" . }} + helm.sh/chart: {{ include "emqx.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- if or .Values.ingress.annotations .Values.ingress.mgmt.annotations }} + annotations: + {{- if .Values.ingress.annotations }} + {{- toYaml .Values.ingress.annotations | nindent 4 }} + {{- end }} + {{- if .Values.ingress.mgmt.annotations }} + {{- toYaml .Values.ingress.mgmt.annotations | nindent 4 }} + {{- end }} + {{- end }} +spec: +{{- if and .Values.ingress.mgmt.ingressClassName (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.ingress.mgmt.ingressClassName }} +{{- end }} + rules: + {{- range $host := .Values.ingress.mgmt.hosts }} + - host: {{ $host }} + http: + paths: + - path: {{ $.Values.ingress.mgmt.path | default "/" }} + {{- if (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} + pathType: ImplementationSpecific + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + service: + name: {{ include "emqx.fullname" $ }} + port: + number: {{ $.Values.service.mgmt }} + {{- else }} + serviceName: {{ include "emqx.fullname" $ }} + servicePort: {{ $.Values.service.mgmt }} + {{- end }} + {{- end -}} + {{- if .Values.ingress.mgmt.tls }} + tls: + {{- toYaml .Values.ingress.mgmt.tls | nindent 4 }} + {{- end }} +{{- end }} diff --git a/deploy/charts/emqx/templates/ingress.wss.yaml b/deploy/charts/emqx/templates/ingress.wss.yaml new file mode 100644 index 000000000..7c7b395a5 --- /dev/null +++ b/deploy/charts/emqx/templates/ingress.wss.yaml @@ -0,0 +1,54 @@ +{{- if .Values.ingress.wss.enabled -}} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ printf "%s-%s" (include "emqx.fullname" .) "wss" }} + labels: + app.kubernetes.io/name: {{ include "emqx.name" . }} + helm.sh/chart: {{ include "emqx.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- if or .Values.ingress.annotations .Values.ingress.wss.annotations }} + annotations: + {{- if .Values.ingress.annotations }} + {{- toYaml .Values.ingress.annotations | nindent 4 }} + {{- end }} + {{- if .Values.ingress.wss.annotations }} + {{- toYaml .Values.ingress.wss.annotations | nindent 4 }} + {{- end }} + {{- end }} +spec: +{{- if and .Values.ingress.wss.ingressClassName (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.ingress.wss.ingressClassName }} +{{- end }} + rules: + {{- range $host := .Values.ingress.wss.hosts }} + - host: {{ $host }} + http: + paths: + - path: {{ $.Values.ingress.wss.path | default "/mqtt" }} + {{- if (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} + pathType: ImplementationSpecific + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + service: + name: {{ include "emqx.fullname" $ }} + port: + number: {{ $.Values.service.ws }} + {{- else }} + serviceName: {{ include "emqx.fullname" $ }} + servicePort: {{ $.Values.service.ws }} + {{- end }} + {{- end -}} + {{- if .Values.ingress.wss.tls }} + tls: + {{- toYaml .Values.ingress.wss.tls | nindent 4 }} + {{- end }} +{{- end }} diff --git a/deploy/charts/emqx/templates/rbac.yaml b/deploy/charts/emqx/templates/rbac.yaml index 79b431442..cbd3b4f7b 100644 --- a/deploy/charts/emqx/templates/rbac.yaml +++ b/deploy/charts/emqx/templates/rbac.yaml @@ -18,8 +18,8 @@ rules: - apiGroups: - "" resources: - - endpoints - verbs: + - endpoints + verbs: - get - watch - list diff --git a/deploy/charts/emqx/values.yaml b/deploy/charts/emqx/values.yaml index 1b129cf75..d0c109b5c 100644 --- a/deploy/charts/emqx/values.yaml +++ b/deploy/charts/emqx/values.yaml @@ -22,6 +22,26 @@ recreatePods: false # To redeploy a chart with existing PVC(s), the value must be set to Parallel to avoid deadlock podManagementPolicy: Parallel +## Aditional container env vars +## +extraEnv: [] + +## Aditional container env from vars +## +extraEnvFrom: [] + +## Additional container executable args +## +extraArgs: [] + +## Additional container volumes (eg. for mounting certs from secrets) +## +extraVolumes: [] + +## Additional container volume mounts (eg. for mounting certs from secrets) +## +extraVolumeMounts: [] + persistence: enabled: false size: 20Mi @@ -42,13 +62,13 @@ resources: {} # cpu: 500m # memory: 512Mi -# Containers that run before the creation of EMQX containers. They can contain utilities or setup scripts. +# Containers that run before the creation of EMQ X containers. They can contain utilities or setup scripts. initContainers: {} # - name: mysql-probe # image: alpine # command: ["sh", "-c", "for i in $(seq 1 300); do nc -zvw1 mysql 3306 && exit 0 || sleep 3; done; exit 1"] -## EMQX configuration item, see the documentation (https://hub.docker.com/r/emqx/emqx) +## EMQ X configuration item, see the documentation (https://hub.docker.com/r/emqx/emqx) emqxConfig: EMQX_NAME: "{{ .Release.Name }}" @@ -114,7 +134,7 @@ emqxLoadedModules: > {emqx_mod_subscription, false}. {emqx_mod_topic_metrics, false}. -## EMQX Enterprise Edition requires manual creation of a Secret containing the licensed content. Write the name of Secret to the value of "emqxLicenseSecretName" +## EMQ X Enterprise Edition requires manual creation of a Secret containing the licensed content. Write the name of Secret to the value of "emqxLicenseSecretName" ## Example: ## kubectl create secret generic emqx-license-secret-name --from-file=/path/to/emqx.lic emqxLicenseSecretName: @@ -180,7 +200,10 @@ tolerations: [] affinity: {} ingress: - ## ingress for EMQX Dashboard + ## Ingress shared annotations + annotations: {} + + ## ingress for EMQ X Dashboard dashboard: enabled: false annotations: {} @@ -191,7 +214,7 @@ ingress: - dashboard.emqx.local tls: [] - ## ingress for EMQX Mgmt API + ## ingress for EMQ X Mgmt API mgmt: enabled: false annotations: {} @@ -202,6 +225,29 @@ ingress: - api.emqx.local tls: [] + ## ingress for EMQ X Mgmt API + wss: + enabled: false + # ingressClassName: nginx + annotations: {} + # Sample annotations for nginx-ingress community controller + # nginx.ingress.kubernetes.io/rewrite-target: /mqtt$1 # Use to rewrite backend path if needed + # nginx.ingress.kubernetes.io/backend-protocol: "http" + # nginx.ingress.kubernetes.io/use-forwarded-headers: "true" + # nginx.ingress.kubernetes.io/enable-real-ip: "true" + # nginx.ingress.kubernetes.io/proxy-request-buffering: "off" + # nginx.ingress.kubernetes.io/proxy-connect-timeout: "120" + # nginx.ingress.kubernetes.io/proxy-http-version: "1.1" + # nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + # nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" + # nginx.ingress.kubernetes.io/use-proxy-protocol: "false" + # nginx.ingress.kubernetes.io/proxy-protocol-header-timeout: "5s" + path: /mqtt + # path: /wss(\/.*)? + hosts: + - wss.emqx.local + tls: [] + podSecurityContext: enabled: true fsGroup: 1000 diff --git a/priv/emqx.schema b/priv/emqx.schema index 832136807..b983fb864 100644 --- a/priv/emqx.schema +++ b/priv/emqx.schema @@ -2478,12 +2478,20 @@ end}. ]}. {translation, "emqx.os_mon", fun(Conf) -> - [{cpu_check_interval, cuttlefish:conf_get("os_mon.cpu_check_interval", Conf)}, - {cpu_high_watermark, cuttlefish:conf_get("os_mon.cpu_high_watermark", Conf) * 100}, - {cpu_low_watermark, cuttlefish:conf_get("os_mon.cpu_low_watermark", Conf) * 100}, - {mem_check_interval, cuttlefish:conf_get("os_mon.mem_check_interval", Conf)}, - {sysmem_high_watermark, cuttlefish:conf_get("os_mon.sysmem_high_watermark", Conf) * 100}, - {procmem_high_watermark, cuttlefish:conf_get("os_mon.procmem_high_watermark", Conf) * 100}] + CpuHw = cuttlefish:conf_get("os_mon.cpu_high_watermark", Conf) * 100, + CpuLw = cuttlefish:conf_get("os_mon.cpu_low_watermark", Conf) * 100, + case CpuHw > CpuLw of + true -> + [{cpu_check_interval, cuttlefish:conf_get("os_mon.cpu_check_interval", Conf)}, + {cpu_high_watermark, CpuHw}, + {cpu_low_watermark, CpuLw}, + {mem_check_interval, cuttlefish:conf_get("os_mon.mem_check_interval", Conf)}, + {sysmem_high_watermark, cuttlefish:conf_get("os_mon.sysmem_high_watermark", Conf) * 100}, + {procmem_high_watermark, cuttlefish:conf_get("os_mon.procmem_high_watermark", Conf) * 100}]; + false -> + Msg = io_lib:format("high(~w)_must_greater_than_low(~w)", [CpuHw, CpuLw]), + error(lists:flatten(Msg)) + end end}. %%-------------------------------------------------------------------- @@ -2505,9 +2513,17 @@ end}. ]}. {translation, "emqx.vm_mon", fun(Conf) -> - [{check_interval, cuttlefish:conf_get("vm_mon.check_interval", Conf)}, - {process_high_watermark, cuttlefish:conf_get("vm_mon.process_high_watermark", Conf) * 100}, - {process_low_watermark, cuttlefish:conf_get("vm_mon.process_low_watermark", Conf) * 100}] + Hw = cuttlefish:conf_get("vm_mon.process_high_watermark", Conf) * 100, + Lw = cuttlefish:conf_get("vm_mon.process_low_watermark", Conf) * 100, + case Hw > Lw of + true -> + [{check_interval, cuttlefish:conf_get("vm_mon.check_interval", Conf)}, + {process_high_watermark, Hw}, + {process_low_watermark, Lw}]; + false -> + Msg = io_lib:format("high(~w)_must_greater_than_low(~w)", [Hw, Lw]), + error(lists:flatten(Msg)) + end end}. %%--------------------------------------------------------------------