RocketMQ 5.x 安装教程 (基于 Kubernetes)

    有参考 https://juejin.cn/post/7277395050508746809
    有参考 https://rocketmq.apache.org/docs/deploymentOperations/01deploy#start-proxy

    本文的目的是基于kubernetes搭建一套 rocketmq 5.1.4 (2 nameserver 2 broker 2 proxy )环境.
    有以下功能点

    1. 命名空间隔离. 所有资源均创建于 rocketmq namespace 下
    2. 基于 nfs 做数据存储/日志存储. (基于 default StorageClass PV 生成的 pvc)
    3. 用到的镜像均已做 aliyun 镜像源缓存

    关于 RocketMQ 5

    官方介绍 RocketMQ 5 https://rocketmq.apache.org/version

    RocketMQ 4 和 5 的对比

    RocketMQ 5 最大特定就是引入了 Proxy 组件
    Proxy 组件是无状态的 Broker. 对Broker职责进行拆分,对于客户端协议适配、权限管理、消费管理等计算逻辑进行抽离,独立无状态的代理角色提供服务

    Broker则继续专注于存储能力的持续优化。

    这套模式可以更好地实现在云环境(Kubernetes)的资源弹性调度

    image.png

    准备工作

    创建命名空间 rocketmq

    后续所有 rocketmq 相关资源均处于该命名空间下, 方便管理和清理

    kubectl create namespace rocketmq
    

    创建存储 PVC

    用来存储日志和数据

    如何创建 NFS PV 可参考 https://cloud.docs.jansora.app/cloud-native/install-k8s/kubernetes-pv-config

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: nfs-pvc
      namespace: rocketmq
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 100Gi
    

    创建自定义配置

    为了方便后续对参数的调整, 对配置进行维护是必要的

    共有以下配置

    • broker.conf: 创建 broker 和 proxy 使用
    • proxy-config.json: 创建 proxy 会用到的 json 配置
    • runbroker.sh: 创建 broker会用到的启动脚本 (对官方的配置进行略微调整, 增加了可调整内存的配置)
    • runserver.sh: 创建 nameserver 和 proxy 会用到的启动脚本 (对官方的配置进行略微调整, 增加了可调整内存的配置)
    # 创建 configmap
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: rocketmq-config
      namespace: rocketmq
    data:
      broker.conf: |
        brokerClusterName = DefaultCluster
        brokerName = broker-a
        brokerId = 0
        deleteWhen = 04
        fileReservedTime = 48
        brokerRole = ASYNC_MASTER
        flushDiskType = ASYNC_FLUSH
        autoCreateTopicEnable=true
        autoCreateSubscriptionGroup=true
        
      proxy-config.json: |
        {
          "rocketMQClusterName": "DefaultCluster"
        }
        
      runbroker.sh: |
        error_exit ()
        {
        echo "ERROR: $1 !!"
        exit 1
        }
          
          find_java_home()
          {
            case "`uname`" in
            Darwin)
            JAVA_HOME=$(/usr/libexec/java_home)
            ;;
            *)
            JAVA_HOME=$(dirname $(dirname $(readlink -f $(which javac))))
            ;;
            esac
          }
          
          find_java_home
          
          [ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=$HOME/jdk/java
          [ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/java
          [ ! -e "$JAVA_HOME/bin/java" ] && error_exit "Please set the JAVA_HOME variable in your environment, We need java(x64)!"
          
          export JAVA_HOME
          export JAVA="$JAVA_HOME/bin/java"
          export BASE_DIR=$(dirname $0)/..
          export CLASSPATH=.:${BASE_DIR}/conf:${CLASSPATH}
          
          #===========================================================================================
          # JVM Configuration
          #===========================================================================================
          calculate_heap_sizes()
          {
          case "`uname`" in
          Linux)
          system_memory_in_mb=`free -m| sed -n '2p' | awk '{print $2}'`
          system_cpu_cores=`egrep -c 'processor([[:space:]]+):.*' /proc/cpuinfo`
          ;;
          FreeBSD)
          system_memory_in_bytes=`sysctl hw.physmem | awk '{print $2}'`
          system_memory_in_mb=`expr $system_memory_in_bytes / 1024 / 1024`
          system_cpu_cores=`sysctl hw.ncpu | awk '{print $2}'`
          ;;
          SunOS)
          system_memory_in_mb=`prtconf | awk '/Memory size:/ {print $3}'`
          system_cpu_cores=`psrinfo | wc -l`
          ;;
          Darwin)
          system_memory_in_bytes=`sysctl hw.memsize | awk '{print $2}'`
          system_memory_in_mb=`expr $system_memory_in_bytes / 1024 / 1024`
          system_cpu_cores=`sysctl hw.ncpu | awk '{print $2}'`
          ;;
          *)
          # assume reasonable defaults for e.g. a modern desktop or
          # cheap server
          system_memory_in_mb="2048"
          system_cpu_cores="2"
          ;;
          esac
          
          # some systems like the raspberry pi don't report cores, use at least 1
          if [ "$system_cpu_cores" -lt "1" ]
          then
          system_cpu_cores="1"
          fi
          
          # set max heap size based on the following
          # max(min(1/2 ram, 1024MB), min(1/4 ram, 8GB))
          # calculate 1/2 ram and cap to 1024MB
          # calculate 1/4 ram and cap to 8192MB
          # pick the max
          half_system_memory_in_mb=`expr $system_memory_in_mb / 2`
          quarter_system_memory_in_mb=`expr $half_system_memory_in_mb / 2`
          if [ "$half_system_memory_in_mb" -gt "1024" ]
          then
          half_system_memory_in_mb="1024"
          fi
          if [ "$quarter_system_memory_in_mb" -gt "8192" ]
          then
          quarter_system_memory_in_mb="8192"
          fi
          if [ "$half_system_memory_in_mb" -gt "$quarter_system_memory_in_mb" ]
          then
          max_heap_size_in_mb="$half_system_memory_in_mb"
          else
          max_heap_size_in_mb="$quarter_system_memory_in_mb"
          fi
          MAX_HEAP_SIZE="${max_heap_size_in_mb}M"
          
          # Young gen: min(max_sensible_per_modern_cpu_core * num_cores, 1/4 * heap size)
          max_sensible_yg_per_core_in_mb="100"
          max_sensible_yg_in_mb=`expr $max_sensible_yg_per_core_in_mb "*" $system_cpu_cores`
          
          desired_yg_in_mb=`expr $max_heap_size_in_mb / 4`
          
          if [ "$desired_yg_in_mb" -gt "$max_sensible_yg_in_mb" ]
          then
          HEAP_NEWSIZE="${max_sensible_yg_in_mb}M"
          else
          HEAP_NEWSIZE="${desired_yg_in_mb}M"
          fi
          }
          
          calculate_heap_sizes
          
          # Dynamically calculate parameters, for reference.
          Xms=$MAX_HEAP_SIZE
          Xmx=$MAX_HEAP_SIZE
          Xmn=$HEAP_NEWSIZE
          MaxDirectMemorySize=$MAX_HEAP_SIZE
          # Set for `JAVA_OPT`.
          JAVA_OPT="${JAVA_OPT} -server ${JAVA_VM_OPTS}"
          JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8"
          JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/dev/shm/mq_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy"
          JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m"
          JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow"
          JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch"
          #  JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=${MaxDirectMemorySize}"
          JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking"
          JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${JAVA_HOME}/jre/lib/ext:${BASE_DIR}/lib"
          #JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n"
          JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT}"
          JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}"
          
          numactl --interleave=all pwd > /dev/null 2>&1
          if [ $? -eq 0 ]
          then
          if [ -z "$RMQ_NUMA_NODE" ] ; then
          numactl --interleave=all $JAVA ${JAVA_OPT} $@
          else
          numactl --cpunodebind=$RMQ_NUMA_NODE --membind=$RMQ_NUMA_NODE $JAVA ${JAVA_OPT} $@
          fi
          else
          $JAVA ${JAVA_OPT} $@
          fi
    
      runserver.sh: |
        #!/bin/bash
    
        # Licensed to the Apache Software Foundation (ASF) under one or more
        # contributor license agreements.  See the NOTICE file distributed with
        # this work for additional information regarding copyright ownership.
        # The ASF licenses this file to You under the Apache License, Version 2.0
        # (the "License"); you may not use this file except in compliance with
        # the License.  You may obtain a copy of the License at
        #
        #     http://www.apache.org/licenses/LICENSE-2.0
        #
        # Unless required by applicable law or agreed to in writing, software
        # distributed under the License is distributed on an "AS IS" BASIS,
        # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        # See the License for the specific language governing permissions and
        # limitations under the License.
    
        #===========================================================================================
        # Java Environment Setting
        #===========================================================================================
        error_exit ()
        {
            echo "ERROR: $1 !!"
            exit 1
        }
    
        find_java_home()
        {
            case "`uname`" in
                Darwin)
                    JAVA_HOME=$(/usr/libexec/java_home)
                ;;
                *)
                    JAVA_HOME=$(dirname $(dirname $(readlink -f $(which javac))))
                ;;
            esac
        }
    
        find_java_home
    
        [ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=$HOME/jdk/java
        [ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/java
        [ ! -e "$JAVA_HOME/bin/java" ] && error_exit "Please set the JAVA_HOME variable in your environment, We need java(x64)!"
    
        export JAVA_HOME
        export JAVA="$JAVA_HOME/bin/java"
        export BASE_DIR=$(dirname $0)/..
        export CLASSPATH=.:${BASE_DIR}/conf:${CLASSPATH}
    
        #===========================================================================================
        # JVM Configuration
        #===========================================================================================
        calculate_heap_sizes()
        {
            case "`uname`" in
                Linux)
                    system_memory_in_mb=`free -m| sed -n '2p' | awk '{print $2}'`
                    system_cpu_cores=`egrep -c 'processor([[:space:]]+):.*' /proc/cpuinfo`
                ;;
                FreeBSD)
                    system_memory_in_bytes=`sysctl hw.physmem | awk '{print $2}'`
                    system_memory_in_mb=`expr $system_memory_in_bytes / 1024 / 1024`
                    system_cpu_cores=`sysctl hw.ncpu | awk '{print $2}'`
                ;;
                SunOS)
                    system_memory_in_mb=`prtconf | awk '/Memory size:/ {print $3}'`
                    system_cpu_cores=`psrinfo | wc -l`
                ;;
                Darwin)
                    system_memory_in_bytes=`sysctl hw.memsize | awk '{print $2}'`
                    system_memory_in_mb=`expr $system_memory_in_bytes / 1024 / 1024`
                    system_cpu_cores=`sysctl hw.ncpu | awk '{print $2}'`
                ;;
                *)
                    # assume reasonable defaults for e.g. a modern desktop or
                    # cheap server
                    system_memory_in_mb="2048"
                    system_cpu_cores="2"
                ;;
            esac
    
            # some systems like the raspberry pi don't report cores, use at least 1
            if [ "$system_cpu_cores" -lt "1" ]
            then
                system_cpu_cores="1"
            fi
    
            # set max heap size based on the following
            # max(min(1/2 ram, 1024MB), min(1/4 ram, 8GB))
            # calculate 1/2 ram and cap to 1024MB
            # calculate 1/4 ram and cap to 8192MB
            # pick the max
            half_system_memory_in_mb=`expr $system_memory_in_mb / 2`
            quarter_system_memory_in_mb=`expr $half_system_memory_in_mb / 2`
            if [ "$half_system_memory_in_mb" -gt "1024" ]
            then
                half_system_memory_in_mb="1024"
            fi
            if [ "$quarter_system_memory_in_mb" -gt "8192" ]
            then
                quarter_system_memory_in_mb="8192"
            fi
            if [ "$half_system_memory_in_mb" -gt "$quarter_system_memory_in_mb" ]
            then
                max_heap_size_in_mb="$half_system_memory_in_mb"
            else
                max_heap_size_in_mb="$quarter_system_memory_in_mb"
            fi
            MAX_HEAP_SIZE="${max_heap_size_in_mb}M"
    
            # Young gen: min(max_sensible_per_modern_cpu_core * num_cores, 1/4 * heap size)
            max_sensible_yg_per_core_in_mb="100"
            max_sensible_yg_in_mb=`expr $max_sensible_yg_per_core_in_mb "*" $system_cpu_cores`
    
            desired_yg_in_mb=`expr $max_heap_size_in_mb / 4`
    
            if [ "$desired_yg_in_mb" -gt "$max_sensible_yg_in_mb" ]
            then
                HEAP_NEWSIZE="${max_sensible_yg_in_mb}M"
            else
                HEAP_NEWSIZE="${desired_yg_in_mb}M"
            fi
        }
    
        calculate_heap_sizes
    
        # Dynamically calculate parameters, for reference.
        Xms=$MAX_HEAP_SIZE
        Xmx=$MAX_HEAP_SIZE
        Xmn=$HEAP_NEWSIZE
        # Set for `JAVA_OPT`.
        JAVA_OPT="${JAVA_OPT} -server ${JAVA_VM_OPTS}"
        JAVA_OPT="${JAVA_OPT} -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8  -XX:-UseParNewGC"
        JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/dev/shm/rmq_srv_gc.log -XX:+PrintGCDetails"
        JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow"
        JAVA_OPT="${JAVA_OPT}  -XX:-UseLargePages"
        JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${JAVA_HOME}/jre/lib/ext:${BASE_DIR}/lib"
        #JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n"
        JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT}"
        JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}"
    
        $JAVA ${JAVA_OPT} $@
        
        
    
    
    

    部署核心组件

    • nameserver : 2 个 Pod 节点(StatefulSets) + 1 个 Service (负载均衡)
    • broker : 2个 Pod 节点(StatefulSets) + 1 个 Service (负载均衡)
    • proxy : 2个 Pod 节点(StatefulSets) + 1 个 Service (负载均衡)

    根据实际情况, 可分别对 nameserver broker proxy 的 Pod 进行动态的扩容

    部署 nameserver

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: rocketmq-nameserver-1
      namespace: rocketmq
    spec:
      selector:
        matchLabels:
          app: rocketmq-nameserver
      replicas: 1
      template:
        metadata:
          labels:
            app: rocketmq-nameserver
        spec:
          containers:
            - name: rocketmq-nameserver
              image: registry.cn-hongkong.aliyuncs.com/jansora/rocketmq:5.1.4
              imagePullPolicy: IfNotPresent
              env:
                - name: JAVA_VM_OPTS
                  value: "-Xms512M -Xmx512M -Xmn256M "
              resources:
                requests:
                  memory: "200Mi"
                  cpu: "500m"
                limits:
                  memory: "512Mi"
                  cpu: "1000m"
              ports:
                - containerPort: 9876
              command: ["sh", "mqnamesrv"]
              volumeMounts:
                - name: nfs-pvc
                  subPath: 'rocketmq/rocketmq-nameserver-1'
                  mountPath: "/home/rocketmq/logs"
                - name: config-volume
                  mountPath: /home/rocketmq/rocketmq-5.1.4/bin/runserver.sh # 具体路径请参考官方文档
                  subPath: runserver.sh
          volumes:
            - name: config-volume
              configMap:
                name: rocketmq-config
            - name: nfs-pvc
              persistentVolumeClaim:
                claimName: nfs-pvc
      serviceName: rocketmq-nameserver-service
    
    
    ---
    
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: rocketmq-nameserver-2
      namespace: rocketmq
    spec:
      selector:
        matchLabels:
          app: rocketmq-nameserver
      replicas: 1
      template:
        metadata:
          labels:
            app: rocketmq-nameserver
        spec:
          containers:
            - name: rocketmq-nameserver
              image: registry.cn-hongkong.aliyuncs.com/jansora/rocketmq:5.1.4
              imagePullPolicy: IfNotPresent
              env:
                - name: JAVA_VM_OPTS
                  value: "-Xms512M -Xmx512M -Xmn256M "
              ports:
                - containerPort: 9876
              volumeMounts:
                - name: nfs-pvc
                  subPath: 'rocketmq/rocketmq-nameserver-2'
                  mountPath: "/home/rocketmq/logs"
                - name: config-volume
                  mountPath: /home/rocketmq/rocketmq-5.1.4/bin/runserver.sh # 具体路径请参考官方文档
                  subPath: runserver.sh
              command: ["sh", "mqnamesrv"]
          volumes:
            - name: config-volume
              configMap:
                name: rocketmq-config
            - name: nfs-pvc
              persistentVolumeClaim:
                claimName: nfs-pvc
      serviceName: rocketmq-nameserver-service
    
    ---
    
    # 创建 Service 由 kubernetes 来对多个 nameserver 做负载均衡
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: rocketmq-nameserver
      name: rocketmq-nameserver-service
      namespace: rocketmq
    spec:
      ports:
        - port: 9876
          protocol: TCP
      selector:
        app: rocketmq-nameserver
    
    

    部署 broker

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: rocketmq-broker-1
      namespace: rocketmq
    spec:
      selector:
        matchLabels:
          app: rocketmq-broker
      replicas: 1
      template:
        metadata:
          labels:
            app: rocketmq-broker
        spec:
          containers:
            - name: rocketmq-broker
              image: registry.cn-hongkong.aliyuncs.com/jansora/rocketmq:5.1.4
              imagePullPolicy: IfNotPresent
              env:
                - name: JAVA_VM_OPTS
                  value: "-Xms512M -Xmx512M -Xmn512M "
    #          resources:
    #            requests:
    #              memory: "512Mi"
    #              cpu: "500m"
    #            limits:
    #              memory: "512Mi"
    #              cpu: "1000m"
              ports:
                - containerPort: 10911
                - containerPort: 10909
              volumeMounts:
                - name: config-volume
                  mountPath: /home/rocketmq/rocketmq-5.1.4/conf/broker.conf # 具体路径请参考官方文档
                  subPath: broker.conf
                - name: config-volume
                  mountPath: /home/rocketmq/rocketmq-5.1.4/bin/runbroker.sh # 具体路径请参考官方文档
                  subPath: runbroker.sh
                - name: nfs-pvc
                  subPath: 'rocketmq/rocketmq-broker-1/log'
                  mountPath: '/home/rocketmq/logs'
                - name: nfs-pvc
                  subPath: 'rocketmq/rocketmq-broker-1/store'
                  mountPath: "/home/rocketmq/store"
              command: ["sh", "mqbroker", "-n", "rocketmq-nameserver-service.rocketmq.svc.cluster.local:9876", "-c", "/home/rocketmq/rocketmq-5.1.4/conf/broker.conf"]
          volumes:
            - name: config-volume
              configMap:
                name: rocketmq-config
            - name: nfs-pvc
              persistentVolumeClaim:
                claimName: nfs-pvc
      serviceName: rocketmq-broker-service
    
    
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: rocketmq-broker-2
      namespace: rocketmq
    spec:
      selector:
        matchLabels:
          app: rocketmq-broker
      replicas: 1
      template:
        metadata:
          labels:
            app: rocketmq-broker
        spec:
          containers:
            - name: rocketmq-broker
              image: registry.cn-hongkong.aliyuncs.com/jansora/rocketmq:5.1.4
              imagePullPolicy: IfNotPresent
              env:
                - name: JAVA_VM_OPTS
                  value: "-Xms512M -Xmx512M -Xmn512M "
              ports:
                - containerPort: 10911
                - containerPort: 10909
              volumeMounts:
                - name: config-volume
                  mountPath: /home/rocketmq/rocketmq-5.1.4/conf/broker.conf # 具体路径请参考官方文档
                  subPath: broker.conf
                - name: config-volume
                  mountPath: /home/rocketmq/rocketmq-5.1.4/bin/runbroker.sh # 具体路径请参考官方文档
                  subPath: runbroker.sh
    
                - name: nfs-pvc
                  subPath: 'rocketmq/rocketmq-broker-2/logs'
                  mountPath: "/home/rocketmq/logs"
                - name: nfs-pvc
                  subPath: 'rocketmq/rocketmq-broker-2/store'
                  mountPath: "/home/rocketmq/store"
              command: ["sh", "mqbroker", "-n", "rocketmq-nameserver-service.rocketmq.svc.cluster.local:9876", "-c", "/home/rocketmq/rocketmq-5.1.4/conf/broker.conf"]
          volumes:
            - name: config-volume
              configMap:
                name: rocketmq-config
            - name: nfs-pvc
              persistentVolumeClaim:
                claimName: nfs-pvc
      serviceName: rocketmq-broker-service
    
    
    ---
    
    # 创建 Service 由 kubernetes 来对多个 broker 做负载均衡
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: rocketmq-broker
      name: rocketmq-broker-service
      namespace: rocketmq
    spec:
      ports:
        - port: 9876
          protocol: TCP
      selector:
        app: rocketmq-broker
    
    
    
    

    部署 proxy

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: rocketmq-proxy-1
      namespace: rocketmq
    spec:
      selector:
        matchLabels:
          app: rocketmq-proxy
      replicas: 1
      template:
        metadata:
          labels:
            app: rocketmq-proxy
        spec:
          containers:
            - name: rocketmq-proxy
              image: registry.cn-hongkong.aliyuncs.com/jansora/rocketmq:5.1.4
              imagePullPolicy: IfNotPresent
              env:
                - name: JAVA_VM_OPTS
                  value: "-Xms512M -Xmx512M -Xmn256M "
              ports:
                - containerPort: 10911
                - containerPort: 10909
              volumeMounts:
                - name: config-volume
                  mountPath: /home/rocketmq/rocketmq-5.1.4/conf/rmq-proxy.json # 具体路径请参考官方文档
                  subPath: proxy-config.json
                - name: config-volume
                  mountPath: /home/rocketmq/rocketmq-5.1.4/bin/runserver.sh # 具体路径请参考官方文档
                  subPath: runserver.sh
                - name: nfs-pvc
                  subPath: 'rocketmq/rocketmq-proxy-1'
                  mountPath: '/home/rocketmq/logs'
              command: ["sh", "mqproxy", "-n", "rocketmq-nameserver-service.rocketmq.svc.cluster.local:9876", "-pc", "/home/rocketmq/rocketmq-5.1.4/conf/rmq-proxy.json"]
          volumes:
            - name: config-volume
              configMap:
                name: rocketmq-config
            - name: nfs-pvc
              persistentVolumeClaim:
                claimName: nfs-pvc
      serviceName: rocketmq-proxy-service
    
    
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: rocketmq-proxy-2
      namespace: rocketmq
    spec:
      selector:
        matchLabels:
          app: rocketmq-proxy
      replicas: 1
      template:
        metadata:
          labels:
            app: rocketmq-proxy
        spec:
          containers:
            - name: rocketmq-proxy
              image: registry.cn-hongkong.aliyuncs.com/jansora/rocketmq:5.1.4
              imagePullPolicy: IfNotPresent
              env:
                - name: JAVA_VM_OPTS
                  value: "-Xms512M -Xmx512M -Xmn256M "
              ports:
                - containerPort: 10911
                - containerPort: 10909
              volumeMounts:
                - name: config-volume
                  mountPath: /home/rocketmq/rocketmq-5.1.4/conf/rmq-proxy.json # 具体路径请参考官方文档
                  subPath: proxy-config.json
                - name: config-volume
                  mountPath: /home/rocketmq/rocketmq-5.1.4/bin/runserver.sh # 具体路径请参考官方文档
                  subPath: runserver.sh
                - name: nfs-pvc
                  subPath: 'rocketmq/rocketmq-proxy-2'
                  mountPath: '/home/rocketmq/logs'
              command: ["sh", "mqproxy", "-n", "rocketmq-nameserver-service.rocketmq.svc.cluster.local:9876", "-pc", "/home/rocketmq/rocketmq-5.1.4/conf/rmq-proxy.json"]
          volumes:
            - name: config-volume
              configMap:
                name: rocketmq-config
            - name: nfs-pvc
              persistentVolumeClaim:
                claimName: nfs-pvc
      serviceName: rocketmq-proxy-service
    
    
    
    ---
    
    # 创建 Service 由 kubernetes 来对多个 broker 做负载均衡
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: rocketmq-proxy
      name: rocketmq-proxy-service
      namespace: rocketmq
    spec:
      ports:
        - port: 9876
          protocol: TCP
      selector:
        app: rocketmq-proxy
    
    
    

    部署 Console

    1 个 pod 和 1 个 service (供外部访问)

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: rocketmq-dashboard
      namespace: rocketmq
    spec:
      selector:
        matchLabels:
          app:  rocketmq-dashboard
      strategy:
        type: RollingUpdate
        rollingUpdate:
          maxSurge: 20
          maxUnavailable: 20
      replicas: 1
      template:
        metadata:
          labels:
            app: rocketmq-dashboard
        spec:
          containers:
            - name: rocketmq-dashboard
              image: registry.cn-hongkong.aliyuncs.com/jansora/rocketmq-dashboard:1.0.0
              imagePullPolicy: IfNotPresent
              ports:
                - containerPort: 8080
              env:
                - name: JAVA_OPTS
                  value: ' -Drocketmq.namesrv.addr=rocketmq-nameserver-service.rocketmq.svc.cluster.local:9876 -Dserver.port=8080  -Xms512m -Xmx512m -Xmn256m '
    
    ---
    
    apiVersion: v1
    kind: Service
    metadata:
      name: rocketmq-dashboard-service
      namespace: rocketmq
      labels:
        app: rocketmq-dashboard-service
    spec:
      type: ClusterIP
      selector:
        app: rocketmq-dashboard
      ports:
        - protocol: TCP
          port: 8080
          targetPort: 8080
          name: http
    
    

    部署 console 的 ingress

    可选项: 部署 basic 认证 以及 tls 证书

    创建 basic 认证

    用户名:密码 (jansora

    )

    export PASSWORD=$(openssl passwd -apr1 pwd) && kubectl create secret generic default-basic-auth --from-literal=auth="jansora:$PASSWORD"
    

    部署 tls 证书

    kubectl create secret tls wildcard.jansora.com \
      --key /etc/openresty/certs/lets-encrypt-jansora.com/jansora.com.key \
      --cert /etc/openresty/certs/lets-encrypt-jansora.com/jansora.com.crt \
      --namespace rocketmq \
      --dry-run=client -o yaml | kubectl apply -f -
    '
    

    部署 ingress

    
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: rocketmq-ingress
      namespace: rocketmq
      annotations:
        nginx.ingress.kubernetes.io/force-ssl-redirect: "true" # 80 -> 443 http 强制跳转 https
        nginx.ingress.kubernetes.io/auth-type: basic  # 添加 basic 认证
        nginx.ingress.kubernetes.io/auth-secret: default-basic-auth
        nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"
        nginx.ingress.kubernetes.io/hsts: "false"
    spec:
      ingressClassName: nginx
      tls:
        - secretName: wildcard.jansora.com
      rules:
        - host: rocketmq.kubernetes.jansora.com
          http:
            paths:
              - backend:
                  service:
                    name: rocketmq-dashboard-service
                    port:
                      number: 8080
                pathType: Prefix
                path: /
                
    

    验证

    https://rocketmq.kubernetes.jansora.com

    评论栏