package c_middle const CmiiEmqxTemplate = ` --- apiVersion: v1 kind: ServiceAccount metadata: name: helm-emqxs namespace: {{ .Namespace }} --- apiVersion: v1 kind: ConfigMap metadata: name: helm-emqxs-env namespace: {{ .Namespace }} labels: cmii.type: middleware cmii.app: helm-emqxs cmii.emqx.architecture: cluster helm.sh/chart: emqx-1.1.0 app.kubernetes.io/managed-by: octopus-control app.kubernetes.io/version: {{ .TagVersion }} data: # 集群相关 EMQX_CLUSTER__DISCOVERY: "k8s" EMQX_CLUSTER__K8S__APISERVER: "https://kubernetes.default.svc.cluster.local:443" EMQX_CLUSTER__K8S__APP_NAME: "helm-emqxs" EMQX_CLUSTER__K8S__SERVICE_NAME: "helm-emqxs-headless" EMQX_CLUSTER__K8S__ADDRESS_TYPE: "dns" EMQX_CLUSTER__K8S__NAMESPACE: "{{ .Namespace }}" EMQX_CLUSTER__K8S__SUFFIX: "svc.cluster.local" # 关闭匿名,默认 ACL 不匹配拒绝 EMQX_AUTH__ALLOW_ANONYMOUS: "false" EMQX_AUTHZ__NO_MATCH: "deny" # Dashboard 初始管理员密码(只在第一次启动时生效) EMQX_DASHBOARD__DEFAULT_PASSWORD: "{{ .EmqxPassword }}" --- apiVersion: v1 kind: ConfigMap metadata: name: helm-emqxs-init-script namespace: {{ .Namespace }} labels: cmii.type: middleware cmii.app: helm-emqxs data: init-mqtt-user.sh: | #!/bin/sh set -e DASHBOARD_USER="admin" DASHBOARD_PASS="{{ .EmqxPassword }}" MQTT_USER="admin" MQTT_PASS="{{ .EmqxPassword }}" # 等待 EMQX 本地 API 就绪 EMQX_API="http://localhost:18083/api/v5" echo "等待 EMQX API 就绪..." for i in $(seq 1 120); do if curl -s -f -m 5 "${EMQX_API}/status" > /dev/null 2>&1; then echo "EMQX API 已就绪" break fi echo "等待中... ($i/120)" sleep 5 done # 修改 Dashboard 管理员密码 echo "修改 Dashboard 管理员密码..." /opt/emqx/bin/emqx ctl admins passwd "${DASHBOARD_USER}" "${DASHBOARD_PASS}" || echo "密码可能已设置" echo "Dashboard 密码设置完成" # 获取 Dashboard Token echo "获取 Dashboard Token..." TOKEN=$(curl -s -X POST "${EMQX_API}/login" \ -H 'Content-Type: application/json' \ -d "{\"username\":\"${DASHBOARD_USER}\",\"password\":\"${DASHBOARD_PASS}\"}" \ | grep -o '"token":"[^"]*' | cut -d'"' -f4) if [ -z "$TOKEN" ]; then echo "ERROR: 无法获取 Token" exit 1 fi echo "Token 获取成功" # 创建内置数据库认证器(使用 listeners 作用域) echo "检查并创建内置数据库认证器..." # 为 tcp:default listener 添加认证器 echo "为 listener tcp:default 配置认证器..." curl -s -X POST "${EMQX_API}/authentication/tcp:default" \ -H "Authorization: Bearer ${TOKEN}" \ -H 'Content-Type: application/json' \ -d '{ "mechanism": "password_based", "backend": "built_in_database", "user_id_type": "username", "password_hash_algorithm": { "name": "sha256", "salt_position": "suffix" } }' 2>/dev/null || echo "tcp:default 认证器可能已存在" # 为 ws:default listener 添加认证器 echo "为 listener ws:default 配置认证器..." curl -s -X POST "${EMQX_API}/authentication/ws:default" \ -H "Authorization: Bearer ${TOKEN}" \ -H 'Content-Type: application/json' \ -d '{ "mechanism": "password_based", "backend": "built_in_database", "user_id_type": "username", "password_hash_algorithm": { "name": "sha256", "salt_position": "suffix" } }' 2>/dev/null || echo "ws:default 认证器可能已存在" # 等待认证器创建完成 sleep 2 # 创建 MQTT 用户 echo "创建 MQTT 用户: ${MQTT_USER}..." curl -s -X POST "${EMQX_API}/authentication/password_based:built_in_database/users?listener_id=tcp:default" \ -H "Authorization: Bearer ${TOKEN}" \ -H 'Content-Type: application/json' \ -d "{\"user_id\":\"${MQTT_USER}\",\"password\":\"${MQTT_PASS}\",\"is_superuser\":true}" \ 2>/dev/null || echo "用户可能已存在,尝试更新..." # 尝试更新密码 curl -s -X PUT "${EMQX_API}/authentication/password_based:built_in_database/users/${MQTT_USER}?listener_id=tcp:default" \ -H "Authorization: Bearer ${TOKEN}" \ -H 'Content-Type: application/json' \ -d "{\"password\":\"${MQTT_PASS}\",\"is_superuser\":true}" \ 2>/dev/null || true echo "MQTT 用户创建/更新完成" # 创建授权规则 echo "配置授权规则..." # 创建内置数据库授权源 curl -s -X POST "${EMQX_API}/authorization/sources" \ -H "Authorization: Bearer ${TOKEN}" \ -H 'Content-Type: application/json' \ -d '{ "type": "built_in_database", "enable": true }' 2>/dev/null || echo "授权源可能已存在" sleep 2 # 为 admin 用户添加授权规则(使用数组格式) echo "为 ${MQTT_USER} 用户添加 ACL 规则..." curl -s -X POST "${EMQX_API}/authorization/sources/built_in_database/rules/users" \ -H "Authorization: Bearer ${TOKEN}" \ -H 'Content-Type: application/json' \ -d "[{\"username\":\"${MQTT_USER}\",\"rules\":[{\"action\":\"all\",\"permission\":\"allow\",\"topic\":\"#\"}]}]" \ 2>/dev/null && echo "ACL 规则创建成功" || echo "规则可能已存在,尝试更新..." # 尝试更新规则(PUT 请求需要单个对象,不是数组) curl -s -X PUT "${EMQX_API}/authorization/sources/built_in_database/rules/users/${MQTT_USER}" \ -H "Authorization: Bearer ${TOKEN}" \ -H 'Content-Type: application/json' \ -d "{\"rules\":[{\"action\":\"all\",\"permission\":\"allow\",\"topic\":\"#\"}]}" \ 2>/dev/null && echo "ACL 规则更新成功" || true echo "ACL 规则配置完成" echo "初始化完成!MQTT 用户: ${MQTT_USER}" echo "可通过以下方式连接:" echo " - MQTT: localhost:1883" echo " - WebSocket: localhost:8083" echo " - Dashboard: http://localhost:18083" echo " - 用户名: ${MQTT_USER}" --- apiVersion: apps/v1 kind: StatefulSet metadata: name: helm-emqxs namespace: {{ .Namespace }} labels: cmii.type: middleware cmii.app: helm-emqxs cmii.emqx.architecture: cluster helm.sh/chart: emqx-1.1.0 app.kubernetes.io/managed-by: octopus-control app.kubernetes.io/version: {{ .TagVersion }} spec: replicas: 1 serviceName: helm-emqxs-headless updateStrategy: type: RollingUpdate selector: matchLabels: cmii.type: middleware cmii.app: helm-emqxs cmii.emqx.architecture: cluster template: metadata: labels: cmii.type: middleware cmii.app: helm-emqxs cmii.emqx.architecture: cluster helm.sh/chart: emqx-1.1.0 app.kubernetes.io/managed-by: octopus-control app.kubernetes.io/version: {{ .TagVersion }} spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: uavcloud.env operator: In values: {{- if .TenantEnv }} - {{ .TenantEnv }} {{- else }} - {{ .Namespace }} {{- end }} imagePullSecrets: - name: harborsecret serviceAccountName: helm-emqxs containers: - name: helm-emqxs {{- if .HarborPort }} image: {{ .HarborIPOrCustomImagePrefix }}:{{ .HarborPort }}/cmii/emqx:5.8.8 {{- else }} image: {{ .HarborIPOrCustomImagePrefix }}emqx:5.8.8 {{- end }} imagePullPolicy: Always ports: - name: mqtt containerPort: 1883 - name: mqttssl containerPort: 8883 - name: mgmt containerPort: 8081 - name: ws containerPort: 8083 - name: wss containerPort: 8084 - name: dashboard containerPort: 18083 - name: ekka containerPort: 4370 envFrom: - configMapRef: name: helm-emqxs-env # 添加生命周期钩子 lifecycle: postStart: exec: command: - /bin/sh - -c - | # 后台执行初始化脚本,避免阻塞容器启动 nohup /bin/sh /scripts/init-mqtt-user.sh > /tmp/init.log 2>&1 & # 添加健康检查,确保 initContainer 执行时 API 已就绪 livenessProbe: httpGet: path: /status port: 18083 initialDelaySeconds: 60 periodSeconds: 30 readinessProbe: httpGet: path: /status port: 18083 initialDelaySeconds: 10 periodSeconds: 5 resources: {} volumeMounts: # 5.x 默认 data 目录,包含所有持久化数据 - name: emqx-data mountPath: "/opt/emqx/data" readOnly: false - name: init-script mountPath: /scripts volumes: - name: emqx-data claimName: helm-emqxs - name: init-script configMap: name: helm-emqxs-init-script defaultMode: 0755 --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: helm-emqxs namespace: {{ .Namespace }} rules: - apiGroups: [""] resources: - endpoints verbs: - get - watch - list --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: helm-emqxs namespace: {{ .Namespace }} subjects: - kind: ServiceAccount name: helm-emqxs namespace: {{ .Namespace }} roleRef: kind: Role name: helm-emqxs apiGroup: rbac.authorization.k8s.io --- apiVersion: v1 kind: Service metadata: name: helm-emqxs namespace: {{ .Namespace }} labels: cmii.type: middleware cmii.app: helm-emqxs cmii.emqx.architecture: cluster helm.sh/chart: emqx-1.1.0 app.kubernetes.io/managed-by: octopus-control app.kubernetes.io/version: {{ .TagVersion }} spec: type: NodePort selector: cmii.type: middleware cmii.app: helm-emqxs cmii.emqx.architecture: cluster ports: - port: 1883 name: mqtt targetPort: 1883 nodePort: {{ .EmqxNodePort }} - port: 18083 name: dashboard targetPort: 18083 nodePort: {{ .EmqxDashboardNodePort }} - port: 8083 name: mqtt-websocket targetPort: 8083 nodePort: {{ .EmqxWebSocketNodePort }} --- apiVersion: v1 kind: Service metadata: name: helm-emqxs-headless namespace: {{ .Namespace }} labels: cmii.type: middleware cmii.app: helm-emqxs cmii.emqx.architecture: cluster helm.sh/chart: emqx-1.1.0 app.kubernetes.io/managed-by: octopus-control app.kubernetes.io/version: {{ .TagVersion }} spec: type: ClusterIP clusterIP: None selector: cmii.type: middleware cmii.app: helm-emqxs cmii.emqx.architecture: cluster ports: - name: mqtt port: 1883 protocol: TCP targetPort: 1883 - name: mqttssl port: 8883 protocol: TCP targetPort: 8883 - name: mgmt port: 8081 protocol: TCP targetPort: 8081 - name: websocket port: 8083 protocol: TCP targetPort: 8083 - name: wss port: 8084 protocol: TCP targetPort: 8084 - name: dashboard port: 18083 protocol: TCP targetPort: 18083 - name: ekka port: 4370 protocol: TCP targetPort: 4370 `