完成 72绵阳项目 71雄安集团监管平台 大量优化更新

This commit is contained in:
zeaslity
2026-02-03 17:07:28 +08:00
parent d962ace967
commit a8f6bda703
93 changed files with 21632 additions and 185 deletions

View File

@@ -0,0 +1,664 @@
---
---
# ============== Secret - 密码管理 ==============
apiVersion: v1
kind: Secret
metadata:
name: emqx-credentials
namespace: sc-my-uav-260202
labels:
cmii.type: middleware
cmii.app: helm-emqxs
app.kubernetes.io/managed-by: octopus-control
app.kubernetes.io/version: "2.0"
type: Opaque
stringData:
# Dashboard管理员密码
dashboard-admin-password: "odD8#Ve7.B"
# MQTT用户密码
mqtt-admin-password: "odD8#Ve7.B"
---
# ============== ServiceAccount ==============
apiVersion: v1
kind: ServiceAccount
metadata:
name: helm-emqxs
namespace: sc-my-uav-260202
---
# ============== Role - RBAC ==============
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: helm-emqxs
namespace: sc-my-uav-260202
rules:
- apiGroups: [""]
resources:
- endpoints
- pods
verbs:
- get
- watch
- list
---
# ============== RoleBinding ==============
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: helm-emqxs
namespace: sc-my-uav-260202
subjects:
- kind: ServiceAccount
name: helm-emqxs
namespace: sc-my-uav-260202
roleRef:
kind: Role
name: helm-emqxs
apiGroup: rbac.authorization.k8s.io
---
# ============== ConfigMap - Bootstrap配置文件 ==============
apiVersion: v1
kind: ConfigMap
metadata:
name: emqx-bootstrap-config
namespace: sc-my-uav-260202
labels:
cmii.type: middleware
cmii.app: helm-emqxs
data:
# 主配置文件 - 覆盖默认配置
emqx.conf: |
# 节点配置
node {
name = "emqx@${POD_NAME}.helm-emqxs-headless.sc-my-uav-260202.svc.cluster.local"
cookie = "emqx-cluster-cookie-secret"
data_dir = "/opt/emqx/data"
}
# 集群配置
cluster {
name = emqxcl
# 单节点 建议为 manual 多节点为k8s
discovery_strategy = manual
k8s {
apiserver = "https://kubernetes.default.svc.cluster.local:443"
service_name = "helm-emqxs-headless"
# 这里可以改为 hostname
address_type = dns
namespace = "sc-my-uav-260202"
suffix = "svc.cluster.local"
}
}
# 日志配置
log {
console {
enable = true
level = info
}
file {
enable = true
level = warning
path = "/opt/emqx/log"
}
}
# Dashboard配置
dashboard {
listeners.http {
bind = "0.0.0.0:18083"
}
default_username = "admin"
default_password = "public"
}
# 监听器配置
listeners.tcp.default {
bind = "0.0.0.0:1883"
max_connections = 1024000
}
listeners.ws.default {
bind = "0.0.0.0:8083"
max_connections = 1024000
websocket.mqtt_path = "/mqtt"
}
listeners.ssl.default {
bind = "0.0.0.0:8883"
max_connections = 512000
}
# 认证配置 - 使用内置数据库
authentication = [
{
mechanism = password_based
backend = built_in_database
user_id_type = username
password_hash_algorithm {
name = sha256
salt_position = suffix
}
# Bootstrap文件路径 - 用于初始化用户
bootstrap_file = "/opt/emqx/data/bootstrap_users.json"
bootstrap_type = plain
}
]
# 授权配置
authorization {
no_match = deny
deny_action = disconnect
sources = [
{
type = built_in_database
enable = true
}
]
}
# MQTT协议配置
mqtt {
max_packet_size = "1MB"
max_clientid_len = 65535
max_topic_levels = 128
max_qos_allowed = 2
max_topic_alias = 65535
retain_available = true
wildcard_subscription = true
shared_subscription = true
}
---
# ============== ConfigMap - Users & ACL (严格 JSON 格式) ==============
apiVersion: v1
kind: ConfigMap
metadata:
name: emqx-bootstrap-users
namespace: sc-my-uav-260202
data:
bootstrap_users.json: |
[
{ "user_id": "admin", "password": "odD8#Ve7.B", "is_superuser": true },
{ "user_id": "cmlc", "password": "odD8#Ve7.B", "is_superuser": false }
]
# 【修改点】既然有jq这里使用标准的 JSON 数组格式,最不容易出错
bootstrap_acl.json: |
[
{
"username": "admin",
"rules": [
{"action": "all", "permission": "allow", "topic": "#"}
]
},
{
"username": "cmlc",
"rules": [
{"action": "publish", "permission": "allow", "topic": "#"},
{"action": "subscribe", "permission": "allow", "topic": "#"}
]
}
]
---
# ============== ConfigMap - 初始化脚本 (修正版) ==============
apiVersion: v1
kind: ConfigMap
metadata:
name: emqx-init-dashboard
namespace: sc-my-uav-260202
data:
init-dashboard.sh: |
#!/bin/bash
set -e
DASHBOARD_USER="admin"
DASHBOARD_PASS="${DASHBOARD_ADMIN_PASSWORD}"
EMQX_API="http://localhost:18083/api/v5"
ACL_FILE="/bootstrap/bootstrap_acl.json"
# 辅助函数:打印带时间戳的日志
log() {
echo "[$(date +'%H:%M:%S')] $1"
}
log "======================================"
log "初始化 Dashboard 与 ACL (Debug Version)"
log "======================================"
# ----------------------------------------------------------------
# 1. 等待 EMQX API 就绪
# ----------------------------------------------------------------
log "[1/4] 等待 EMQX API 就绪..."
for i in $(seq 1 60); do
if curl -s -f -m 5 "${EMQX_API}/status" > /dev/null 2>&1; then
log "✓ EMQX API 已就绪"
break
fi
if [ $i -eq 60 ]; then
log "✗ EMQX API 启动超时"
exit 1
fi
sleep 5
done
# ----------------------------------------------------------------
# 2. 修改 Dashboard 密码
# ----------------------------------------------------------------
log "[2/4] 检查/更新 Dashboard 密码..."
# 获取 Token (尝试默认密码)
LOGIN_RESP=$(curl -s -X POST "${EMQX_API}/login" \
-H 'Content-Type: application/json' \
-d "{\"username\":\"${DASHBOARD_USER}\",\"password\":\"public\"}")
TOKEN=$(echo "$LOGIN_RESP" | jq -r '.token // empty')
if [ -n "$TOKEN" ]; then
log " 检测到默认密码,正在更新..."
curl -s -f -X POST "${EMQX_API}/users/${DASHBOARD_USER}/change_pwd" \
-H "Authorization: Bearer ${TOKEN}" \
-H 'Content-Type: application/json' \
-d "{\"old_pwd\":\"public\",\"new_pwd\":\"${DASHBOARD_PASS}\"}"
log " ✓ Dashboard 密码已更新"
else
log " 无法使用默认密码登录,跳过更新(可能已修改)"
fi
# ----------------------------------------------------------------
# 3. 导入 ACL 规则
# ----------------------------------------------------------------
echo "[3/3] 导入ACL规则..."
# 重新登录获取最新 Token
LOGIN_RESP=$(curl -sS -X POST "${EMQX_API}/login" \
-H 'Content-Type: application/json' \
-d "{\"username\":\"${DASHBOARD_USER}\",\"password\":\"${DASHBOARD_PASS}\"}")
TOKEN=$(echo "$LOGIN_RESP" | jq -r '.token // empty')
if [ -z "$TOKEN" ]; then
echo " ✗ 无法获取Token请检查密码设置"
exit 0
fi
if [ -f "$ACL_FILE" ]; then
echo " 正在解析 ACL 文件: $ACL_FILE"
if ! jq -e . "$ACL_FILE" >/dev/null 2>&1; then
echo " ✗ ACL 文件 JSON 格式错误,跳过处理"
exit 0
fi
jq -c '.[]' "$ACL_FILE" | while read -r user_config; do
USERNAME=$(echo "$user_config" | jq -r '.username // empty')
# ✅ PUT/POST 都需要 username + rulesusername 是 required
REQ_BODY=$(echo "$user_config" | jq -c '{username: .username, rules: .rules}')
if [ -z "$USERNAME" ]; then
echo " ✗ ACL 条目缺少 username跳过"
continue
fi
echo " 配置用户 ${USERNAME} 的ACL规则..."
# 1) 优先 PUT覆盖更新
http_code=$(curl -sS -o /tmp/emqx_acl_resp.json -w '%{http_code}' \
-X PUT "${EMQX_API}/authorization/sources/built_in_database/rules/users/${USERNAME}" \
-H "Authorization: Bearer ${TOKEN}" \
-H 'Content-Type: application/json' \
-d "$REQ_BODY")
if [ "$http_code" = "204" ]; then
echo " ✓ PUT 更新成功"
elif [ "$http_code" = "404" ]; then
# 2) 不存在则 POST 创建
http_code2=$(curl -sS -o /tmp/emqx_acl_resp.json -w '%{http_code}' \
-X POST "${EMQX_API}/authorization/sources/built_in_database/rules/users" \
-H "Authorization: Bearer ${TOKEN}" \
-H 'Content-Type: application/json' \
-d "$REQ_BODY")
if [ "$http_code2" = "204" ]; then
echo " ✓ POST 创建成功"
else
echo " ✗ POST 失败 (HTTP ${http_code2})$(cat /tmp/emqx_acl_resp.json 2>/dev/null || true)"
exit 1
fi
else
echo " ✗ PUT 失败 (HTTP ${http_code})$(cat /tmp/emqx_acl_resp.json 2>/dev/null || true)"
exit 1
fi
# 3) 导入后验证(可选但强烈建议保留)
verify_code=$(curl -sS -o /tmp/emqx_acl_verify.json -w '%{http_code}' \
-H "Authorization: Bearer ${TOKEN}" \
"${EMQX_API}/authorization/sources/built_in_database/rules/users/${USERNAME}")
if [ "$verify_code" = "200" ]; then
echo " ✓ 验证成功:$(cat /tmp/emqx_acl_verify.json | jq -c '.')"
else
echo " ✗ 验证失败 (HTTP ${verify_code})$(cat /tmp/emqx_acl_verify.json 2>/dev/null || true)"
exit 1
fi
done
echo " ✓ ACL 规则导入完成"
else
echo " 未找到 ACL 文件"
fi
---
# ============== StatefulSet ==============
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: helm-emqxs
namespace: sc-my-uav-260202
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: "2.0"
spec:
replicas: 1
serviceName: helm-emqxs-headless
podManagementPolicy: Parallel
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: "2.0"
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: uavcloud.env
operator: In
values:
- mianyang
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: cmii.app
operator: In
values:
- helm-emqxs
topologyKey: kubernetes.io/hostname
imagePullSecrets:
- name: harborsecret
serviceAccountName: helm-emqxs
securityContext:
fsGroup: 1000
runAsUser: 1000
# InitContainer - 准备bootstrap文件
initContainers:
- name: prepare-bootstrap
# 动态选择 tools 镜像
image: 192.168.1.4:8033/cmii/tools:1.0
imagePullPolicy: IfNotPresent
# =========================================================
# 权限: 必须以 root 身份运行才能 chown
# =========================================================
securityContext:
runAsUser: 0
command:
- /bin/sh
- -c
- |
echo "准备bootstrap文件..."
# 创建数据目录
mkdir -p /opt/emqx/data
# 复制bootstrap文件到数据目录
# 只在文件不存在时复制,避免覆盖已有数据
if [ ! -f /opt/emqx/data/bootstrap_users.json ]; then
cp /bootstrap-src/bootstrap_users.json /opt/emqx/data/
echo "✓ 已复制用户bootstrap文件"
else
echo " 用户bootstrap文件已存在跳过"
fi
# 设置权限 (现在有root权限可以成功)
chown -R 1000:1000 /opt/emqx/data
echo "✓ Bootstrap准备完成"
volumeMounts:
- name: emqx-data
mountPath: /opt/emqx/data
- name: bootstrap-users
mountPath: /bootstrap-src
containers:
# 主容器 - EMQX
- name: emqx
# 动态选择 emqx 镜像
image: 192.168.1.4:8033/cmii/emqx:5.8.8
imagePullPolicy: IfNotPresent
env:
# Pod信息
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: EMQX_DATA_DIR
value: "/opt/emqx/data"
ports:
- name: mqtt
containerPort: 1883
- name: mqttssl
containerPort: 8883
- name: ws
containerPort: 8083
- name: dashboard
containerPort: 18083
- name: ekka
containerPort: 4370
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "2000m"
memory: "2Gi"
livenessProbe:
httpGet:
path: /status
port: 18083
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /status
port: 18083
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
startupProbe:
httpGet:
path: /status
port: 18083
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 30
volumeMounts:
- name: emqx-data
mountPath: /opt/emqx/data
# 使用 subPath 挂载单个配置文件,避免覆盖目录
- name: bootstrap-config
mountPath: /opt/emqx/etc/emqx.conf
subPath: emqx.conf
# Sidecar - 初始化Dashboard密码和ACL
- name: init-dashboard
# 动态选择 tools 镜像
image: 192.168.1.4:8033/cmii/tools:1.0
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- |
# 等待主容器启动
echo "等待EMQX启动..."
sleep 20
# 执行初始化
/bin/sh /scripts/init-dashboard.sh
# 保持运行
echo "初始化完成,进入守护模式..."
while true; do sleep 3600; done
env:
- name: DASHBOARD_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: emqx-credentials
key: dashboard-admin-password
resources:
requests:
cpu: "100m"
memory: "64Mi"
limits:
cpu: "200m"
memory: "128Mi"
volumeMounts:
- name: init-script
mountPath: /scripts
- name: bootstrap-users
mountPath: /bootstrap
volumes:
- name: bootstrap-config
configMap:
name: emqx-bootstrap-config
- name: bootstrap-users
configMap:
name: emqx-bootstrap-users
- name: init-script
configMap:
name: emqx-init-dashboard
defaultMode: 0755
- name: emqx-data
persistentVolumeClaim:
claimName: helm-emqxs
---
# ============== Service - Headless ==============
apiVersion: v1
kind: Service
metadata:
name: helm-emqxs-headless
namespace: sc-my-uav-260202
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: "2.0"
spec:
type: ClusterIP
clusterIP: None
publishNotReadyAddresses: true
selector:
cmii.type: middleware
cmii.app: helm-emqxs
cmii.emqx.architecture: cluster
ports:
- name: mqtt
port: 1883
targetPort: 1883
- name: mqttssl
port: 8883
targetPort: 8883
- name: ws
port: 8083
targetPort: 8083
- name: dashboard
port: 18083
targetPort: 18083
- name: ekka
port: 4370
targetPort: 4370
---
# ============== Service - NodePort ==============
apiVersion: v1
kind: Service
metadata:
name: helm-emqxs
namespace: sc-my-uav-260202
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: "2.0"
spec:
type: NodePort
selector:
cmii.type: middleware
cmii.app: helm-emqxs
cmii.emqx.architecture: cluster
ports:
- name: mqtt
port: 1883
targetPort: 1883
nodePort: 31883
- name: dashboard
port: 18083
targetPort: 18083
nodePort: 38085
- name: ws
port: 8083
targetPort: 8083
nodePort: 38083
- name: mqttssl
port: 8883
targetPort: 8883