更新EMQX为5.8.8可运行版本
This commit is contained in:
@@ -2,6 +2,26 @@ package c_middle
|
||||
|
||||
const CmiiEmqxTemplate = `
|
||||
---
|
||||
# ============== Secret - 密码管理 ==============
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: emqx-credentials
|
||||
namespace: {{ .Namespace }}
|
||||
labels:
|
||||
cmii.type: middleware
|
||||
cmii.app: helm-emqxs
|
||||
app.kubernetes.io/managed-by: octopus-control
|
||||
app.kubernetes.io/version: {{ .TagVersion }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
# Dashboard管理员密码
|
||||
dashboard-admin-password: "{{ .EmqxPassword }}"
|
||||
# MQTT用户密码
|
||||
mqtt-admin-password: "{{ .EmqxPassword }}"
|
||||
|
||||
---
|
||||
# ============== ServiceAccount ==============
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
@@ -9,155 +29,336 @@ metadata:
|
||||
namespace: {{ .Namespace }}
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
# ============== Role - RBAC ==============
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: helm-emqxs-env
|
||||
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 }}
|
||||
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 }}"
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources:
|
||||
- endpoints
|
||||
- pods
|
||||
verbs:
|
||||
- get
|
||||
- watch
|
||||
- list
|
||||
|
||||
---
|
||||
# ============== RoleBinding ==============
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
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
|
||||
|
||||
---
|
||||
# ============== ConfigMap - Bootstrap配置文件 ==============
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: helm-emqxs-init-script
|
||||
name: emqx-bootstrap-config
|
||||
namespace: {{ .Namespace }}
|
||||
labels:
|
||||
cmii.type: middleware
|
||||
cmii.app: helm-emqxs
|
||||
data:
|
||||
init-mqtt-user.sh: |
|
||||
#!/bin/sh
|
||||
# 主配置文件 - 覆盖默认配置
|
||||
emqx.conf: |
|
||||
# 节点配置
|
||||
node {
|
||||
name = "emqx@${POD_NAME}.helm-emqxs-headless.{{ .Namespace }}.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 = "{{ .Namespace }}"
|
||||
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: {{ .Namespace }}
|
||||
data:
|
||||
bootstrap_users.json: |
|
||||
[
|
||||
{ "user_id": "admin", "password": "{{ .EmqxPassword }}", "is_superuser": true },
|
||||
{ "user_id": "cmlc", "password": "{{ .EmqxPassword }}", "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: {{ .Namespace }}
|
||||
data:
|
||||
init-dashboard.sh: |
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
DASHBOARD_USER="admin"
|
||||
DASHBOARD_PASS="{{ .EmqxPassword }}"
|
||||
MQTT_USER="admin"
|
||||
MQTT_PASS="{{ .EmqxPassword }}"
|
||||
# 等待 EMQX 本地 API 就绪
|
||||
DASHBOARD_PASS="${DASHBOARD_ADMIN_PASSWORD}"
|
||||
EMQX_API="http://localhost:18083/api/v5"
|
||||
echo "等待 EMQX API 就绪..."
|
||||
for i in $(seq 1 120); do
|
||||
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
|
||||
echo "EMQX API 已就绪"
|
||||
log "✓ EMQX API 已就绪"
|
||||
break
|
||||
fi
|
||||
echo "等待中... ($i/120)"
|
||||
if [ $i -eq 60 ]; then
|
||||
log "✗ EMQX API 启动超时"
|
||||
exit 1
|
||||
fi
|
||||
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" \
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# 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\":\"${DASHBOARD_PASS}\"}" \
|
||||
| grep -o '"token":"[^"]*' | cut -d'"' -f4)
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "ERROR: 无法获取 Token"
|
||||
exit 1
|
||||
-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
|
||||
echo "Token 获取成功"
|
||||
# 创建内置数据库认证器(使用 listeners 作用域)
|
||||
echo "检查并创建内置数据库认证器..."
|
||||
# 为 tcp:default listener 添加认证器
|
||||
echo "为 listener tcp:default 配置认证器..."
|
||||
curl -s -X POST "${EMQX_API}/authentication/tcp:default" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# 3. 导入 ACL 规则
|
||||
# ----------------------------------------------------------------
|
||||
echo "[3/3] 导入ACL规则..."
|
||||
|
||||
# 重新登录获取最新 Token
|
||||
LOGIN_RESP=$(curl -sS -X POST "${EMQX_API}/login" \
|
||||
-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}"
|
||||
-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 + rules(username 是 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:
|
||||
@@ -173,6 +374,7 @@ metadata:
|
||||
spec:
|
||||
replicas: 1
|
||||
serviceName: helm-emqxs-headless
|
||||
podManagementPolicy: Parallel
|
||||
updateStrategy:
|
||||
type: RollingUpdate
|
||||
selector:
|
||||
@@ -180,6 +382,7 @@ spec:
|
||||
cmii.type: middleware
|
||||
cmii.app: helm-emqxs
|
||||
cmii.emqx.architecture: cluster
|
||||
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
@@ -203,106 +406,246 @@ spec:
|
||||
{{- else }}
|
||||
- {{ .Namespace }}
|
||||
{{- end }}
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: cmii.app
|
||||
operator: In
|
||||
values:
|
||||
- helm-emqxs
|
||||
topologyKey: kubernetes.io/hostname
|
||||
|
||||
imagePullSecrets:
|
||||
- name: harborsecret
|
||||
- name: harborsecret
|
||||
|
||||
serviceAccountName: helm-emqxs
|
||||
|
||||
securityContext:
|
||||
fsGroup: 1000
|
||||
runAsUser: 1000
|
||||
|
||||
# InitContainer - 准备bootstrap文件
|
||||
initContainers:
|
||||
- name: prepare-bootstrap
|
||||
# 动态选择 tools 镜像
|
||||
{{- if .HarborPort }}
|
||||
image: {{ .HarborIPOrCustomImagePrefix }}:{{ .HarborPort }}/cmii/tools:1.0
|
||||
{{- else }}
|
||||
image: {{ .HarborIPOrCustomImagePrefix }}cmii/tools:1.0
|
||||
{{- end }}
|
||||
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:
|
||||
- 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
|
||||
# 主容器 - EMQX
|
||||
- name: emqx
|
||||
# 动态选择 emqx 镜像
|
||||
{{- if .HarborPort }}
|
||||
image: {{ .HarborIPOrCustomImagePrefix }}:{{ .HarborPort }}/cmii/emqx:5.8.8
|
||||
{{- else }}
|
||||
image: {{ .HarborIPOrCustomImagePrefix }}emqx:5.8.8
|
||||
{{- end }}
|
||||
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 镜像
|
||||
{{- if .HarborPort }}
|
||||
image: {{ .HarborIPOrCustomImagePrefix }}:{{ .HarborPort }}/cmii/tools:1.0
|
||||
{{- else }}
|
||||
image: {{ .HarborIPOrCustomImagePrefix }}cmii/tools:1.0
|
||||
{{- end }}
|
||||
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: emqx-data
|
||||
persistentVolumeClaim:
|
||||
- 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
|
||||
- name: init-script
|
||||
configMap:
|
||||
name: helm-emqxs-init-script
|
||||
defaultMode: 0755
|
||||
|
||||
---
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
# ============== Service - Headless ==============
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: helm-emqxs
|
||||
name: helm-emqxs-headless
|
||||
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
|
||||
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
|
||||
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:
|
||||
@@ -322,66 +665,19 @@ spec:
|
||||
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
|
||||
- name: mqtt
|
||||
port: 1883
|
||||
targetPort: 1883
|
||||
nodePort: {{ .EmqxNodePort }}
|
||||
- name: dashboard
|
||||
port: 18083
|
||||
targetPort: 18083
|
||||
nodePort: {{ .EmqxDashboardNodePort }}
|
||||
- name: ws
|
||||
port: 8083
|
||||
targetPort: 8083
|
||||
nodePort: {{ .EmqxWebSocketNodePort }}
|
||||
- name: mqttssl
|
||||
port: 8883
|
||||
targetPort: 8883
|
||||
`
|
||||
|
||||
@@ -186,11 +186,11 @@ var MiddlewareAmd64 = []string{
|
||||
"harbor.cdcyy.com.cn/cmii/nfs-subdir-external-provisioner:v4.0.2",
|
||||
"docker.m.daocloud.io/jerrychina2020/rke-tools:v0.175-linux",
|
||||
"docker.m.daocloud.io/jerrychina2020/rke-tools:v0.175",
|
||||
"harbor.cdcyy.com.cn/cmii/busybox:1.37",
|
||||
"harbor.cdcyy.com.cn/cmii/doris.be-ubuntu:2.1.6",
|
||||
"harbor.cdcyy.com.cn/cmii/doris.fe-ubuntu:2.1.6",
|
||||
"harbor.cdcyy.com.cn/cmii/doris.k8s-operator:1.3.1",
|
||||
"harbor.cdcyy.com.cn/cmii/alpine:3.23.0",
|
||||
"harbor.cdcyy.com.cn/cmii/tools:1.0",
|
||||
"harbor.cdcyy.com.cn/cmii/curl:8.18.0",
|
||||
"harbor.cdcyy.com.cn/cmii/nginx:1.27.0",
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user