主頁 >  其他 > 使用 KubeSphere 部署高可用 RocketMQ 集群

使用 KubeSphere 部署高可用 RocketMQ 集群

2022-11-30 07:24:48 其他

作者:老Z,云原生愛好者,目前專注于云原生運維,KubeSphere Ambassador,

Spring Cloud Alibaba 全家桶之 RocketMQ 是一款典型的分布式架構下的訊息中間件產品,使用異步通信方式和發布訂閱的訊息傳輸模型,

很多基于 Spring Cloud 開發的專案都喜歡采用 RocketMQ 作為訊息中間件,

RocketMQ 常用的部署模式如下:

  • 單 Master 模式
  • 多 Master 無 Slave 模式
  • 多 Master 多 Slave 模式-異步復制
  • 多 Master 多 Slave 模式-同步雙寫

更多的部署方案詳細資訊可以參考官方檔案,

本文重點介紹 單 Master 模式和多 Master 多 Slave-異步復制模式在 K8s 集群上的部署方案,

單 Master 模式

這種部署方式風險較大,區域署一個 NameServer 和一個 Broker,一旦 Broker 重啟或者宕機時,會導致整個服務不可用,不建議線上生產環境使用,僅可以用于開發和測驗環境,

部署方案參考官方rocketmq-docker專案中使用的容器化部署方案涉及的鏡像、啟動方式、定制化配置,

多 Master 多 Slave-異步復制模式

每個 Master 配置一個 Slave,有多對 Master-Slave,HA 采用異步復制方式,主備有短暫訊息延遲(毫秒級),這種模式的優缺點如下:

  • 優點:即使磁盤損壞,訊息丟失的非常少,且訊息實時性不會受影響,同時 Master 宕機后,消費者仍然可以從 Slave 消費,而且此程序對應用透明,不需要人工干預,性能同多 Master 模式幾乎一樣;
  • 缺點:Master 宕機,磁盤損壞情況下會丟失少量訊息,

多 Master 多 Slave-異步復制模式適用于生產環境,部署方案采用官方提供的 RocketMQ Operator,

離線鏡像制作

此程序為可選項,離線內網環境可用,如果不配置內網鏡像,后續的資源配置清單中注意容器的 image 引數請使用默認值,

本文分別介紹了單 Master 模式和多 Master 多 Slave-異步復制模式部署 RocketMQ 使用的離線鏡像的制作方式,

  • 單 Master 模式直接采用 RocketMQ 官方檔案中介紹的容器化部署方案中使用的鏡像,

  • 多 Master 多 Slave-異步復制模式的離線鏡像制作方式采用 RocketMQ Operator 官方自帶的鏡像制作工具制作打包,制作程序中很多包都需要到國外網路下載,但是受限于國外網路訪問,默認成功率較低,需要多次嘗試或采取特殊手段 ( 懂的都懂),

    也可以用傳統的方式手工的 Pull Docker Hub 上已有的鏡像,然后再 Push 到私有鏡像倉庫,

在一臺能同時訪問互聯網和內網 Harbor 倉庫的服務器上進行下面的操作,

在 Harbor 中創建專案

本人習慣內網離線鏡像的命名空間跟應用鏡像默認的命名空間保持一致,因此,在 Harbor 中創建 apacheapacherocketmq 兩個專案,可以在 Harbor 管理界面中手工創建專案,也可以用下面命令列的方式自動化創建,

curl -u "admin:Harbor12345" -X POST -H "Content-Type: application/json" https://registry.zdevops.com.cn/api/v2.0/projects -d '{ "project_name": "apache", "public": true}'
curl -u "admin:Harbor12345" -X POST -H "Content-Type: application/json" https://registry.zdevops.com.cn/api/v2.0/projects -d '{ "project_name": "apacherocketmq", "public": true}'

安裝 Go 1.16

RocketMQ Operator 自定義鏡像制作需要用到 Go 環境,需要先安裝配置,

下載 Go 1.16 系列的最新版:

cd /opt/
wget https://golang.google.cn/dl/go1.16.15.linux-amd64.tar.gz

解壓源代碼到指定目錄:

tar zxvf go1.16.15.linux-amd64.tar.gz -C /usr/local/

配置環境變數:

cat >> /etc/profile.d/go.sh << EOF
# go environment
export GOROOT=/usr/local/go
export GOPATH=/srv/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
EOF

GOPATH 為作業目錄也是代碼的存放目錄,可以根據自己的習慣配置

配置 Go:

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct

驗證:

source /etc/profile.d/go.sh
go verison

獲取 RocketMQ Operator

從 Apache 官方 GitHub 倉庫獲取 rocketmq-operator 代碼,

cd /srv
git clone -b 0.3.0 https://github.com/apache/rocketmq-operator.git

制作 RocketMQ Operator Image

修改 DockerFile:

cd /srv/rocketmq-operator
vi Dockerfile

Notice: 構建鏡像的程序需訪問國外的軟體源和鏡像倉庫,在國內訪問有時會受限制,因此可以提前修改為國內的軟體源和鏡像倉庫,

此操作為可選項,如果訪問不受限則不需要配置,

必要的修改內容

# 第 10 行(修改代理地址為國內地址,加速訪問)
# 修改前
RUN go mod download

# 修改后
RUN go env -w GOPROXY=https://goproxy.cn,direct && go mod download

# 第 25 行(修改源地址為國內源)
# 修改前
RUN apk add --no-cache bash gettext nmap-ncat openssl busybox-extras

# 修改后
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories && \
    apk add --no-cache bash gettext nmap-ncat openssl busybox-extras

可選的修改內容

# 默認安裝的 ROCKETMQ版本為 4.9.4,可以修改為指定版本
# 第 28 行,修改 4.9.4
ENV ROCKETMQ_VERSION 4.9.4

制作鏡像:

yum install gcc
cd /srv/rocketmq-operator
go mod tidy
IMAGE_URL=registry.zdevops.com.cn/apacherocketmq/rocketmq-operator:0.3.0
make docker-build IMG=${IMAGE_URL}

驗證鏡像構建成功:

docker images | grep rocketmq-operator

推送鏡像:

make docker-push IMG=${IMAGE_URL}

清理臨時鏡像

docker rmi registry.zdevops.com.cn/apacherocketmq/rocketmq-operator:0.3.0

制作 RocketMQ Broker Image

修改 DockerFile(可選):

cd /srv/rocketmq-operator/images/broker/alpine
vi Dockerfile

此操作為可選項,主要是為了安裝軟體加速,如果訪問不受限則不需要配置,

# 第 20 行(修改源地址為國內源)
# 修改前
RUN apk add --no-cache bash gettext nmap-ncat openssl busybox-extras

# 修改后
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories && \
    apk add --no-cache bash gettext nmap-ncat openssl busybox-extras

修改鏡像構建腳本:

# 修改鏡像倉庫地址為內網地址

sed -i 's#apacherocketmq#registry.zdevops.com.cn/apacherocketmq#g' build-broker-image.sh

構建并推送鏡像:

./build-broker-image.sh 4.9.4

驗證鏡像構建成功:

docker images | grep rocketmq-broker

清理臨時鏡像:

docker rmi registry.zdevops.com.cn/apacherocketmq/rocketmq-broker:4.9.4-alpine-operator-0.3.0

制作 RocketMQ Name Server Image

修改 DockerFile(可選):

cd /srv/rocketmq-operator/images/namesrv/alpine
vi Dockerfile

此操作為可選項,主要是為了安裝軟體加速,如果訪問不受限則不需要配置,

# 第 20 行(修改源地址為國內源)
# 修改前
RUN apk add --no-cache bash gettext nmap-ncat openssl busybox-extras

# 修改后
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories && \
    apk add --no-cache bash gettext nmap-ncat openssl busybox-extras

修改鏡像構建腳本:

# 修改鏡像倉庫地址為內網地址

sed -i 's#apacherocketmq#registry.zdevops.com.cn/apacherocketmq#g' build-namesrv-image.sh

構建并推送鏡像:

./build-namesrv-image.sh 4.9.4

驗證鏡像構建成功:

docker images | grep rocketmq-nameserver

清理臨時鏡像:

docker rmi registry.zdevops.com.cn/apacherocketmq/rocketmq-nameserver:4.9.4-alpine-operator-0.3.0

根據官方已有鏡像制作離線鏡像

上面的 RocketMQ 多 Master 多 Slave-異步復制模式部署方案中用到的離線鏡像制作方案更適合于本地修改定制的場景,如果單純的只想把官方已有鏡像不做修改的下載并推送到本地倉庫,可以參考下面的方案,

下載鏡像:

docker pull apache/rocketmq-operator:0.3.0
docker pull apacherocketmq/rocketmq-nameserver:4.5.0-alpine-operator-0.3.0
docker pull apacherocketmq/rocketmq-broker:4.5.0-alpine-operator-0.3.0

Notice: 官方倉庫最新版的鏡像是 2 年前的 4.5.0.

重新打 tag:

docker tag apache/rocketmq-operator:0.3.0-snapshot registry.zdevops.com.cn/apacherocketmq/rocketmq-operator:0.3.0
docker tag apacherocketmq/rocketmq-nameserver:4.5.0-alpine-operator-0.3.0 registry.zdevops.com.cn/apacherocketmq/rocketmq-nameserver:4.5.0-alpine-operator-0.3.0
docker tag apacherocketmq/rocketmq-broker:4.5.0-alpine-operator-0.3.0 registry.zdevops.com.cn/apacherocketmq/rocketmq-broker:4.5.0-alpine-operator-0.3.0

推送到私有鏡像倉庫:

docker push registry.zdevops.com.cn/apacherocketmq/rocketmq-operator:0.3.0
docker push registry.zdevops.com.cn/apacherocketmq/rocketmq-nameserver:4.9.4-alpine-operator-0.3.0
docker push registry.zdevops.com.cn/apacherocketmq/rocketmq-broker:4.9.4-alpine-operator-0.3.0

清理臨時鏡像:

docker rmi apache/rocketmq-operator:0.3.0
docker rmi apacherocketmq/rocketmq-nameserver:4.5.0-alpine-operator-0.3.0
docker rmi apacherocketmq/rocketmq-broker:4.5.0-alpine-operator-0.3.0
docker rmi registry.zdevops.com.cn/apacherocketmq/rocketmq-operator:0.3.0
docker rmi registry.zdevops.com.cn/apacherocketmq/rocketmq-nameserver:4.5.0-alpine-operator-0.3.0
docker rmi registry.zdevops.com.cn/apacherocketmq/rocketmq-broker:4.5.0-alpine-operator-0.3.0

制作 RocketMQ Console Image

本文直接拉取官方鏡像作為本地離線鏡像,如果需要修改內容并重構,可以參考 RocketMQ Console 使用的 官方 Dockerfile自行構建,

下載鏡像:

docker pull apacherocketmq/rocketmq-console:2.0.0

重新打 tag:

docker tag apacherocketmq/rocketmq-console:2.0.0 registry.zdevops.com.cn/apacherocketmq/rocketmq-console:2.0.0

推送到私有鏡像倉庫:

docker push registry.zdevops.com.cn/apacherocketmq/rocketmq-console:2.0.0

清理臨時鏡像:

docker rmi apacherocketmq/rocketmq-console:2.0.0
docker rmi registry.zdevops.com.cn/apacherocketmq/rocketmq-console:2.0.0

準備單 Master RocketMQ 部署方案涉及的離線鏡像

單 Master RocketMQ 部署方案涉及的鏡像跟集群模式部署方案采用的 RocketMQ Operator 中使用的鏡像不同,在制作離線鏡像時,直接從官方鏡像庫拉取然后重新打 tag,再推送本地鏡像倉庫,

二者具體不同說明如下:

  • 單 Master 方案使用的是 Docker Hub 中 apache 命名空間下的鏡像,并且鏡像名稱不區分 nameserver 和 broker,RocketMQ Operator 使用的是 apacherocketmq 命名空間下的鏡像,鏡像名稱區分 nameserver 和 broker,

  • 單 Master 方案和 RocketMQ Operator 方案中管理工具使用的鏡像也不同,單 Master 方案使用的是 apacherocketmq 命名空間下的 rocketmq-dashboard 鏡像,RocketMQ Operator 使用的是 apacherocketmq 命名空間下的 rocketmq-console 鏡像,

具體的離線鏡像制作流程如下:

下載鏡像

docker pull apache/rocketmq:4.9.4
docker pull apacherocketmq/rocketmq-dashboard:1.0.0

重新打 tag

docker tag apache/rocketmq:4.9.4 registry.zdevops.com.cn/apache/rocketmq:4.9.4
docker tag apacherocketmq/rocketmq-dashboard:1.0.0 registry.zdevops.com.cn/apacherocketmq/rocketmq-dashboard:1.0.0

推送到私有鏡像倉庫

docker push registry.zdevops.com.cn/apache/rocketmq:4.9.4
docker push registry.zdevops.com.cn/apacherocketmq/rocketmq-dashboard:1.0.0

清理臨時鏡像

docker rmi apache/rocketmq:4.9.4
docker rmi apacherocketmq/rocketmq-dashboard:1.0.0
docker rmi registry.zdevops.com.cn/apache/rocketmq:4.9.4
docker rmi registry.zdevops.com.cn/apacherocketmq/rocketmq-dashboard:1.0.0

單 Master 模式部署

思路梳理

根據 RocketMQ 服務使用的組件,需要部署以下資源

  • Broker StatefulSet
  • NameServer StatefulSet
  • NameServer Cluster Service:內部服務
  • Dashboard Deployment
  • Dashboard External Service:Dashboard 外部管理用
  • ConfigMap:Broker 自定義組態檔

資源配置清單

參考 GitHub 中 Apache rocketmq-docker專案中介紹的容器化啟動示例配置,撰寫適用于 K8S 的資源配置清單,

Notice: 每個人技術能力、技術習慣、服務環境有所不同,這里介紹的只是我采用的一種簡單方式,并不一定是最優的方案,大家可以根據實際情況撰寫適合自己的配置,

rocketmq-cm.yaml

kind: ConfigMap
apiVersion: v1
metadata:
  name: rocketmq-broker-config
  namespace: zdevops
data:
  BROKER_MEM: ' -Xms2g -Xmx2g -Xmn1g '
  broker-common.conf: |-
    brokerClusterName = DefaultCluster
    brokerName = broker-0
    brokerId = 0
    deleteWhen = 04
    fileReservedTime = 48
    brokerRole = ASYNC_MASTER
    flushDiskType = ASYNC_FLUSH

rocketmq-name-service-sts.yaml

kind: StatefulSet
apiVersion: apps/v1
metadata:
  name: rocketmq-name-service
  namespace: zdevops
spec:
  replicas: 1
  selector:
    matchLabels:
      app: rocketmq-name-service
      name_service_cr: rocketmq-name-service
  template:
    metadata:
      labels:
        app: rocketmq-name-service
        name_service_cr: rocketmq-name-service
    spec:
      volumes:
        - name: host-time
          hostPath:
            path: /etc/localtime
            type: ''
      containers:
        - name: rocketmq-name-service
          image: 'registry.zdevops.com.cn/apache/rocketmq:4.9.4'
          command:
            - /bin/sh
          args:
            - mqnamesrv
          ports:
            - name: tcp-9876
              containerPort: 9876
              protocol: TCP
          resources:
            limits:
              cpu: 500m
              memory: 1Gi
            requests:
              cpu: 250m
              memory: 512Mi
          volumeMounts:
            - name: rocketmq-namesrv-storage
              mountPath: /home/rocketmq/logs
              subPath: logs
            - name: host-time
              readOnly: true
              mountPath: /etc/localtime
          imagePullPolicy: Always
  volumeClaimTemplates:
    - kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: rocketmq-namesrv-storage
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi
        storageClassName: glusterfs
        volumeMode: Filesystem
  serviceName: ''

---
kind: Service
apiVersion: v1
metadata:
  name: rocketmq-name-server-service
  namespace: zdevops
spec:
  ports:
    - name: tcp-9876
      protocol: TCP
      port: 9876
      targetPort: 9876
  selector:
    name_service_cr: rocketmq-name-service
  type: ClusterIP

rocketmq-broker-sts.yaml

kind: StatefulSet
apiVersion: apps/v1
metadata:
  name: rocketmq-broker-0-master
  namespace: zdevops
spec:
  replicas: 1
  selector:
    matchLabels:
      app: rocketmq-broker
      broker_cr: rocketmq-broker
  template:
    metadata:
      labels:
        app: rocketmq-broker
        broker_cr: rocketmq-broker
    spec:
      volumes:
        - name: rocketmq-broker-config
          configMap:
            name: rocketmq-broker-config
            items:
              - key: broker-common.conf
                path: broker-common.conf
            defaultMode: 420
        - name: host-time
          hostPath:
            path: /etc/localtime
            type: ''
      containers:
        - name: rocketmq-broker
          image: 'apache/rocketmq:4.9.4'
          command:
            - /bin/sh
          args:
            - mqbroker
            - "-c"
            - /home/rocketmq/conf/broker-common.conf
          ports:
            - name: tcp-vip-10909
              containerPort: 10909
              protocol: TCP
            - name: tcp-main-10911
              containerPort: 10911
              protocol: TCP
            - name: tcp-ha-10912
              containerPort: 10912
              protocol: TCP
          env:
            - name: NAMESRV_ADDR
              value: 'rocketmq-name-server-service.zdevops:9876'
            - name: BROKER_MEM
              valueFrom:
                configMapKeyRef:
                  name: rocketmq-broker-config
                  key: BROKER_MEM
          resources:
            limits:
              cpu: 500m
              memory: 12Gi
            requests:
              cpu: 250m
              memory: 2Gi
          volumeMounts:
            - name: host-time
              readOnly: true
              mountPath: /etc/localtime
            - name: rocketmq-broker-storage
              mountPath: /home/rocketmq/logs
              subPath: logs/broker-0-master
            - name: rocketmq-broker-storage
              mountPath: /home/rocketmq/store
              subPath: store/broker-0-master
            - name: rocketmq-broker-config
              mountPath: /home/rocketmq/conf/broker-common.conf
              subPath: broker-common.conf
          imagePullPolicy: Always
  volumeClaimTemplates:
    - kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: rocketmq-broker-storage
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 8Gi
        storageClassName: glusterfs
        volumeMode: Filesystem
  serviceName: ''

rocketmq-dashboard.yaml

kind: Deployment
apiVersion: apps/v1
metadata:
  name: rocketmq-dashboard
  namespace: zdevops
spec:
  replicas: 1
  selector:
    matchLabels:
      app: rocketmq-dashboard
  template:
    metadata:
      labels:
        app: rocketmq-dashboard
    spec:
      containers:
        - name: rocketmq-dashboard
          image: 'registry.zdevops.com.cn/apacherocketmq/rocketmq-dashboard:1.0.0'
          ports:
            - name: http-8080
              containerPort: 8080
              protocol: TCP
          env:
            - name: JAVA_OPTS
              value: >-
                -Drocketmq.namesrv.addr=rocketmq-name-server-service.zdevops:9876
                -Dcom.rocketmq.sendMessageWithVIPChannel=false
          resources:
            limits:
              cpu: 500m
              memory: 2Gi
            requests:
              cpu: 50m
              memory: 512Mi
          imagePullPolicy: Always

---
kind: Service
apiVersion: v1
metadata:
  name: rocketmq-dashboard-service
  namespace: zdevops
spec:
  ports:
    - name: http-8080
      protocol: TCP
      port: 8080
      targetPort: 8080
      nodePort: 31080
  selector:
    app: rocketmq-dashboard
  type: NodePort

GitOps

本操作為可選項,本人習慣在個人開發服務器上編輯或修改資源配置清單,然后提交到 Git 服務器 (Gitlab、Gitee、GitHub 等),然后在 k8s 節點上從 Git 服務器拉取資源配置清單并執行,從而實作資源配置清單的版本化管理,簡單的實作運維 GitOps,

本系列檔案的所有 k8s 資源配置清單檔案,為了演示和操作方便,都放在了統一的 k8s-yaml 倉庫中,實際作業中都是一個應用一個 Git 倉庫,更便于應用配置的版本控制,

大家在實際使用中可以忽略本步驟,直接在 k8s 節點上撰寫資源配置清單并執行,也可以參考我的使用方式,實作簡單的 GitOps,

在個人運維開發服務器上操作

# 在已有代碼倉庫創建 rocketmq/single 目錄
mkdir -p rocketmq/single

# 編輯資源配置清單
vi rocketmq/single/rocketmq-cm.yaml
vi rocketmq/single/rocketmq-name-service-sts.yaml
vi rocketmq/single/rocketmq-broker-sts.yaml
vi rocketmq/single/rocketmq-dashboard.yaml

# 提交 Git
git add rocketmq
git commit -am '添加 rocketmq 單節點資源配置清單'
git push

部署資源

在 k8s 集群 Master 節點上或是獨立的運維管理服務器上操作

更新鏡像倉庫代碼

cd /srv/k8s-yaml
git pull

部署資源 (分步式,二選一)

測驗環境使用分步單獨部署的方式,以便測驗資源配置清單的準確性,

cd /srv/k8s-yaml
kubectl apply -f rocketmq/single/rocketmq-cm.yaml
kubectl apply -f rocketmq/single/rocketmq-name-service-sts.yaml
kubectl apply -f rocketmq/single/rocketmq-broker-sts.yaml
kubectl apply -f rocketmq/single/rocketmq-dashboard.yaml

部署資源 (一鍵式,二選一)

實際使用中,可以直接 apply 整個目錄,實作一鍵式自動部署,在正式研發和生產環境中使用目錄的方式實作快速部署,

kubectl apply -f rocketmq/single/

驗證

ConfigMap:

$ kubectl get cm -n zdevops

NAME                     DATA   AGE
kube-root-ca.crt         1      17d
rocketmq-broker-config   2      22s

StatefulSet:

$ kubectl get sts -o wide -n zdevops

NAME                       READY   AGE   CONTAINERS              IMAGES
rocketmq-broker-0-master   1/1     11s   rocketmq-broker         registry.zdevops.com.cn/apache/rocketmq:4.9.4
rocketmq-name-service      1/1     12s   rocketmq-name-service   registry.zdevops.com.cn/apache/rocketmq:4.9.4

Deployment:

$ kubectl get deploy -o wide -n zdevops

NAME                 READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS           IMAGES                                                            SELECTOR
rocketmq-dashboard   1/1     1            1           31s   rocketmq-dashboard   registry.zdevops.com.cn/apacherocketmq/rocketmq-dashboard:1.0.0   app=rocketmq-dashboard

Pods:

$ kubectl get pods -o wide -n zdevops

NAME                                 READY   STATUS    RESTARTS   AGE   IP               NODE              NOMINATED NODE   READINESS GATES
rocketmq-broker-0-master-0           1/1     Running   0          77s   10.233.116.103   ks-k8s-master-2   <none>           <none>
rocketmq-dashboard-b5dbb9d88-cwhqc   1/1     Running   0          3s    10.233.87.115    ks-k8s-master-1   <none>           <none>
rocketmq-name-service-0              1/1     Running   0          78s   10.233.116.102   ks-k8s-master-2   <none>           <none>

Service:

$ kubectl get svc -o wide -n zdevops

NAME                           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE     SELECTOR
rocketmq-dashboard-service     NodePort    10.233.5.237    <none>        8080:31080/TCP   74s     app=rocketmq-dashboard
rocketmq-name-server-service   ClusterIP   10.233.3.61     <none>        9876/TCP         2m29s   name_service_cr=rocketmq-name-service

通過瀏覽器打開 K8S 集群中任意節點的 IP:31080,可以看到 RocketMQ 控制臺的管理界面,

清理資源

卸載 RocketMQ 或是安裝失敗需要清理后重新安裝,可以在 K8S 集群上使用下面的流程清理資源,

清理 StatefulSet:

kubectl delete sts rocketmq-broker-0-master -n zdevops
kubectl delete sts rocketmq-name-service -n zdevops

清理 Deployment:

kubectl delete deployments rocketmq-dashboard -n zdevops

清理 ConfigMap:

kubectl delete cm rocketmq-broker-config -n zdevops

清理服務:

kubectl delete svc rocketmq-name-server-service -n zdevops 
kubectl delete svc rocketmq-dashboard-service -n zdevops 

清理存盤卷:

kubectl delete pvc rocketmq-namesrv-storage-rocketmq-name-service-0 -n zdevops
kubectl delete pvc rocketmq-broker-storage-rocketmq-broker-0-master-0 -n zdevops

當然,也可以利用資源配置清單清理資源,更簡單快捷 (存盤卷無法自動清理,需要手工清理),

$ kubectl delete -f rocketmq/single/

statefulset.apps "rocketmq-broker-0-master" deleted
configmap "rocketmq-broker-config" deleted
deployment.apps "rocketmq-dashboard" deleted
service "rocketmq-dashboard-service" deleted
statefulset.apps "rocketmq-name-service" deleted
service "rocketmq-name-server-service" deleted

多 Master 多 Slave-異步復制模式部署

思路梳理

多 Master 多 Slave-異步復制模式的 RocketMQ 部署,使用官方提供的 RocketMQ Operator,部署起來比較快速便捷,擴容也比較方便,

默認配置會部署 1 個 Master 和 1 個對應的 Slave,部署完成后可以根據需求擴容 Master 和 Slave,

獲取 RocketMQ Operator

# git 獲取代碼時指定版本
cd /srv 
git clone -b 0.3.0 https://github.com/apache/rocketmq-operator.git

準備資源配置清單

本文演示的資源配置清單都是直接修改 rocketmq-operator 默認的配置,生產環境應根據默認配置修改一套適合自己環境的標準組態檔,并存放于 git 倉庫中,

為 deploy 資源配置清單檔案增加或修改命名空間:

cd /srv/rocketmq-operator
sed -i 'N;8 a \  namespace: zdevops' deploy/crds/rocketmq.apache.org_brokers.yaml
sed -i 'N;8 a \  namespace: zdevops' deploy/crds/rocketmq.apache.org_consoles.yaml
sed -i 'N;8 a \  namespace: zdevops' deploy/crds/rocketmq.apache.org_nameservices.yaml
sed -i 'N;8 a \  namespace: zdevops' deploy/crds/rocketmq.apache.org_topictransfers.yaml
sed -i 'N;18 a \  namespace: zdevops' deploy/operator.yaml
sed -i 'N;18 a \  namespace: zdevops' deploy/role_binding.yaml
sed -i 's/namespace: default/namespace: zdevops/g' deploy/role_binding.yaml
sed -i 'N;18 a \  namespace: zdevops' deploy/service_account.yaml
sed -i 'N;20 a \  namespace: zdevops' deploy/role.yaml

切記此步驟只能執行一次,如果失敗了則需要刪掉后重新執行,

執行完成后一定要查看一下結果是否符合預期 grep -r zdevops deploy/*

修改 example 資源配置清單檔案中的命名空間:

sed -i 's/namespace: default/namespace: zdevops/g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml
sed -i 'N;18 a \  namespace: zdevops' example/rocketmq_v1alpha1_cluster_service.yaml

修改鏡像地址為內網地址:

sed -i 's#apache/rocketmq-operator:0.3.0#registry.zdevops.com.cn/apacherocketmq/rocketmq-operator:0.3.0#g' deploy/operator.yaml
sed -i 's#apacherocketmq#registry.zdevops.com.cn/apacherocketmq#g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml 

修改 RocketMQ 版本 (可選):

sed -i 's/4.5.0/4.9.4/g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml 

Notice: 默認的資源配置清單示例中部署 RocketMQ 集群的版本為 4.5.0, 實際使用時請根據需求調整,

修改 NameService 網路模式 (可選):

sed -i 's/hostNetwork: true/hostNetwork: false/g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml 
sed -i 's/dnsPolicy: ClusterFirstWithHostNet/dnsPolicy: ClusterFirst/g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml

Notice: 官方示例默認配置使用 hostNetwork 模式 , 適用于同時給 K8S 集群內、外應用提供服務 , 實際使用時請根據需求調整 .

個人傾向于禁用 hostNetwork 模式 , 不跟外部應用混用 . 如果需要混用 , 則傾向于在外部獨立部署 RocketMQ,

修改 storageClassName 為 glusterfs:

sed -i 's/storageClassName: rocketmq-storage/storageClassName: glusterfs/g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml
sed -i 's/storageMode: EmptyDir/storageMode: StorageClass/g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml

Notice: 演示環境 GlusterFS 存盤對應的 storageClassName 為 glusterfs,請根據實際情況修改,

修改 nameServers 為域名的形式:

sed -i 's/nameServers: ""/nameServers: "name-server-service.zdevops:9876"/g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml

Notice: name-server-service.zdevops 是 NameServer service 名稱 + 專案名稱的組合

默認配置采用 pod [ip:port] 的形式 , 一旦 Pod IP 發生變化 ,Console 就沒法管理集群了 , 且 Console 不會自動變更配置,如果設定為空的話可能還會出現隨便配置的情況,因此一定要提前修改,

修改 RocketMQ Console 外部訪問的 NodePort:

sed -i 's/nodePort: 30000/nodePort: 31080/g' example/rocketmq_v1alpha1_cluster_service.yaml

Notice: 官方示例默認配置埠號為 30000, 實際使用時請根據需求調整,

修改 RocketMQ NameServer 和 Console 的 service 配置:

sed -i '32,46s/^#//g' example/rocketmq_v1alpha1_cluster_service.yaml
sed -i 's/nodePort: 30001/nodePort: 31081/g' example/rocketmq_v1alpha1_cluster_service.yaml
sed -i 's/namespace: default/namespace: zdevops/g' example/rocketmq_v1alpha1_cluster_service.yaml

NameServer 默認使用了 NodePort 的形式,單純在 K8S 集群內部使用的話,可以修改為集群模式,

GitOps

生產環境實際使用時建議將上面編輯整理后的資源配置清單,單獨整理,洗掉 rocketmq-operator 專案中多余的檔案,行成一套適合于自己業務需要的資源配置清單,并使用 Git 進行版本控制,

單 Master 模式部署方案中已經詳細介紹過操作流程,此處不再多做介紹,

4.5. 部署 RocketMQ Operator (自動)

官方介紹的自動部署方法,適用于能連接互聯網的環境,部署程序中需要下載 controller-gen 和 kustomize 二進制檔案,同時會下載一堆 go 依賴,

不適合于內網離線環境,這里只是簡單介紹,本文重點采用后面的手動部署的方案,

部署 RocketMQ Operator:

make deploy

部署 RocketMQ Operator (手動)

部署 RocketMQ Operator:

kubectl create -f deploy/crds/rocketmq.apache.org_brokers.yaml
kubectl create -f deploy/crds/rocketmq.apache.org_nameservices.yaml
kubectl create -f deploy/crds/rocketmq.apache.org_consoles.yaml
kubectl create -f deploy/crds/rocketmq.apache.org_topictransfers.yaml
kubectl create -f deploy/service_account.yaml
kubectl create -f deploy/role.yaml
kubectl create -f deploy/role_binding.yaml
kubectl create -f deploy/operator.yaml

驗證 CRDS:

$ kubectl get crd | grep rocketmq.apache.org

brokers.rocketmq.apache.org                           2022-11-09T02:54:52Z
consoles.rocketmq.apache.org                          2022-11-09T02:54:54Z
nameservices.rocketmq.apache.org                      2022-11-09T02:54:53Z
topictransfers.rocketmq.apache.org                    2022-11-09T02:54:54Z

驗證 RocketMQ Operator:

$ kubectl get deploy -n zdevops -o wide

NAME                READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES                                                           SELECTOR
rocketmq-operator   1/1     1            1           6m46s   manager      registry.zdevops.com.cn/apacherocketmq/rocketmq-operator:0.3.0   name=rocketmq-operator

$ kubectl get pods -n zdevops -o wide

NAME                                 READY   STATUS    RESTARTS   AGE     IP              NODE              NOMINATED NODE   READINESS GATES
rocketmq-operator-7cc6b48796-htpk8   1/1     Running   0          2m28s   10.233.116.70   ks-k8s-master-2   <none>           <none>

部署 RocketMQ 集群

創建服務:

$ kubectl apply -f example/rocketmq_v1alpha1_cluster_service.yaml

service/console-service created
service/name-server-service created

創建集群:

$ kubectl apply -f example/rocketmq_v1alpha1_rocketmq_cluster.yaml

configmap/broker-config created
broker.rocketmq.apache.org/broker created
nameservice.rocketmq.apache.org/name-service created
console.rocketmq.apache.org/console created

驗證

StatefulSet:

$ kubectl get sts -o wide -n zdevops

NAME                 READY   AGE   CONTAINERS     IMAGES
broker-0-master      1/1     27s   broker         registry.zdevops.com.cn/apacherocketmq/rocketmq-broker:4.9.4-alpine-operator-0.3.0
broker-0-replica-1   1/1     27s   broker         registry.zdevops.com.cn/apacherocketmq/rocketmq-broker:4.9.4-alpine-operator-0.3.0
name-service         1/1     27s   name-service   registry.zdevops.com.cn/apacherocketmq/rocketmq-nameserver:4.9.4-alpine-operator-0.3.0

Deployment:

$ kubectl get deploy -o wide -n zdevops

NAME                READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES                                                           SELECTOR
console             1/1     1            1           52s     console      registry.zdevops.com.cn/apacherocketmq/rocketmq-console:2.0.0    app=rocketmq-console
rocketmq-operator   1/1     1            1           4h43m   manager      registry.zdevops.com.cn/apacherocketmq/rocketmq-operator:0.3.0   name=rocketmq-operator

Pod:

$ kubectl get pods -o wide -n zdevops

NAME                                 READY   STATUS    RESTARTS      AGE     IP              NODE              NOMINATED NODE   READINESS GATES
broker-0-master-0                    1/1     Running   0             47s     10.233.87.24    ks-k8s-master-1   <none>           <none>
broker-0-replica-1-0                 1/1     Running   0             17s     10.233.117.28   ks-k8s-master-0   <none>           <none>
console-8d685798f-5pwct              1/1     Running   0             116s    10.233.116.84   ks-k8s-master-2   <none>           <none>
name-service-0                       1/1     Running   0             96s     10.233.116.85   ks-k8s-master-2   <none>           <none>
rocketmq-operator-7cc6b48796-htpk8   1/1     Running   2 (98s ago)   4h39m   10.233.116.70   ks-k8s-master-2   <none>           <none>

Services:

$ kubectl get svc -o wide -n zdevops

NAME                                                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE   SELECTOR
console-service                                          NodePort    10.233.38.15    <none>        8080:31080/TCP   21m   app=rocketmq-console
name-server-service                                      NodePort    10.233.56.238   <none>        9876:31081/TCP   21m   name_service_cr=name-service   

通過瀏覽器打開 K8S 集群中任意節點的 IP:31080,可以看到 RocketMQ 控制臺的管理界面,

清理資源

清理 RocketMQ Cluster

部署集群失敗或是需要重新部署時,采用下面的順序清理洗掉,

kubectl delete -f example/rocketmq_v1alpha1_rocketmq_cluster.yaml
kubectl delete -f example/rocketmq_v1alpha1_cluster_service.yaml

清理 RocketMQ Operator

kubectl delete -f deploy/crds/rocketmq.apache.org_brokers.yaml
kubectl delete -f deploy/crds/rocketmq.apache.org_nameservices.yaml
kubectl delete -f deploy/crds/rocketmq.apache.org_consoles.yaml
kubectl delete -f deploy/crds/rocketmq.apache.org_topictransfers.yaml
kubectl delete -f deploy/service_account.yaml
kubectl delete -f deploy/role.yaml
kubectl delete -f deploy/role_binding.yaml
kubectl delete -f deploy/operator.yaml

清理存盤卷

需要手工查找 Broker 和 NameServer 相關的存盤卷并洗掉,

# 查找存盤卷
$ kubectl get pvc -n zdevops

NAME                                  STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
broker-storage-broker-0-master-0      Bound    pvc-6a78b573-d72a-47ca-9012-5bc888dfcb0f   8Gi        RWO            glusterfs      3m54s
broker-storage-broker-0-replica-1-0   Bound    pvc-4f096942-505d-4e34-ac7f-b871b9f33df3   8Gi        RWO            glusterfs      3m54s
namesrv-storage-name-service-0        Bound    pvc-2c45a77e-3ca1-4eab-bb57-8374aa9068d3   1Gi        RWO            glusterfs      3m54s

# 洗掉存盤卷
kubectl delete pvc namesrv-storage-name-service-0 -n zdevops
kubectl delete pvc broker-storage-broker-0-master-0 -n zdevops
kubectl delete pvc broker-storage-broker-0-replica-1-0 -n zdevops

擴容 NameServer

如果當前的 name service 集群規模不能滿足您的需求,您可以簡單地使用 RocketMQ-Operator 來擴大或縮小 name service 集群的規模,

擴容 name service 需要撰寫并執行獨立的資源配置清單,參考官方示例Name Server Cluster Scale,并結合自己實際環境的 rocketmq-operator 配置修改,

Notice: 不要在已部署的資源中直接修改副本數,直接修改不會生效,會被 Operator 干掉,

編輯擴容 NameServer 資源配置清單 , rocketmq_v1alpha1_nameservice_cr.yaml

apiVersion: rocketmq.apache.org/v1alpha1
kind: NameService
metadata:
  name: name-service
  namespace: zdevops
spec:
  size: 2
  nameServiceImage: registry.zdevops.com.cn/apacherocketmq/rocketmq-nameserver:4.9.4-alpine-operator-0.3.0
  imagePullPolicy: Always
  hostNetwork: false
  dnsPolicy: ClusterFirst
  resources:
    requests:
      memory: "512Mi"
      cpu: "250m"
    limits:
      memory: "1024Mi"
      cpu: "500m"
  storageMode: StorageClass
  hostPath: /data/rocketmq/nameserver
  volumeClaimTemplates:
    - metadata:
        name: namesrv-storage
      spec:
        accessModes:
          - ReadWriteOnce
        storageClassName: glusterfs
        resources:
          requests:
            storage: 1Gi

執行擴容操作:

kubectl apply -f rocketmq/cluster/rocketmq_v1alpha1_nameservice_cr.yaml

驗證 StatefulSet:

$ kubectl get sts name-service -o wide -n zdevops

NAME           READY   AGE   CONTAINERS     IMAGES
name-service   2/2     16m   name-service   registry.zdevops.com.cn/apacherocketmq/rocketmq-nameserver:4.9.4-alpine-operator-0.3.0

驗證 Pods:

$ kubectl get pods -o wide -n zdevops

NAME                                 READY   STATUS    RESTARTS   AGE    IP               NODE              NOMINATED NODE   READINESS GATES
broker-0-master-0                    1/1     Running   0          18m    10.233.87.117    ks-k8s-master-1   <none>           <none>
broker-0-replica-1-0                 1/1     Running   0          43s    10.233.117.99    ks-k8s-master-0   <none>           <none>
console-8d685798f-hnmvg              1/1     Running   0          18m    10.233.116.113   ks-k8s-master-2   <none>           <none>
name-service-0                       1/1     Running   0          18m    10.233.116.114   ks-k8s-master-2   <none>           <none>
name-service-1                       1/1     Running   0          110s   10.233.87.120    ks-k8s-master-1   <none>           <none>
rocketmq-operator-6db8ccc685-5hkk8   1/1     Running   0          18m    10.233.116.112   ks-k8s-master-2   <none>           <none>

特別說明

NameServer 擴容一定要慎重,在實際驗證測驗中發現 NameServer 擴容會導致重建已有的除了 Broker-0 的 Master 之外的其他 Broker 的 Master 和 所有的 Slave,按官方檔案上的說明,應該是 Operator 通知所有的 Broker 更新 name service list parameters,以便它們可以注冊到新的 NameServer Service,

同時,在 allowRestart: true 策略下,Broker 將逐漸更新,因此更新程序也不會被生產者和消費者客戶端感知,也就是說理論上不會影響業務(未實際測驗),

但是,所有 Broker 的 Master 和 Slave 重建后,查看集群狀態時,集群節點的資訊不穩定,有的時候能看到 3 個節點,有的時候則能看到 4 個節點,

因此,生產環境最好在初次部署的時候就配置 NameServer 的副本數為 2 或是 3,盡量不要在后期擴容,除非你能搞定擴容造成的一切后果,

擴容 Broker

通常情況下,隨著業務的發展,現有的 Broker 集群規模可能不再滿足您的業務需求,你可以簡單地使用 RocketMQ-Operator 來升級、擴容 Broker 集群,

擴容 Broker 需要撰寫并執行獨立的資源配置清單,參考官方示例Broker Cluster Scale,并結合自己實際環境的 rocketmq-operator 配置修改,

編輯擴容 Broker 資源配置清單 , rocketmq_v1alpha1_broker_cr.yaml

apiVersion: rocketmq.apache.org/v1alpha1
kind: Broker
metadata:
  name: broker
  namespace: zdevops
spec:
  size: 2
  nameServers: "name-server-service.zdevops::9876"
  replicaPerGroup: 1
  brokerImage: registry.zdevops.com.cn/apacherocketmq/rocketmq-broker:4.9.4-alpine-operator-0.3.0
  imagePullPolicy: Always
  resources:
    requests:
      memory: "2048Mi"
      cpu: "250m"
    limits:
      memory: "12288Mi"
      cpu: "500m"
  allowRestart: true
  storageMode: StorageClass
  hostPath: /data/rocketmq/broker
  # scalePodName is [Broker name]-[broker group number]-master-0
  scalePodName: broker-0-master-0
  env:
    - name: BROKER_MEM
      valueFrom:
        configMapKeyRef:
          name: broker-config
          key: BROKER_MEM
  volumes:
    - name: broker-config
      configMap:
        name: broker-config
        items:
          - key: broker-common.conf
            path: broker-common.conf
  volumeClaimTemplates:
    - metadata:
        name: broker-storage
      spec:
        accessModes:
          - ReadWriteOnce
        storageClassName: glusterfs
        resources:
          requests:
            storage: 8Gi

Notice: 注意重點欄位 scalePodName: broker-0-master-0,

選擇源 Broker pod,將從其中將主題和訂閱資訊資料等舊元資料傳輸到新創建的 Broker,

執行擴容 Broker:

kubectl apply -f rocketmq/cluster/rocketmq_v1alpha1_broker_cr.yaml

Notice: 執行成功后將部署一個新的 Broker Pod 組,同時 Operator 將在啟動新 Broker 之前將源 Broker Pod 中的元資料復制到新創建的 Broker Pod 中,因此新 Broker 將重新加載已有的主題和訂閱資訊,

驗證 StatefulSet:

$ kubectl get sts  -o wide -n zdevops
NAME                 READY   AGE   CONTAINERS     IMAGES
broker-0-master      1/1     43m   broker         registry.zdevops.com.cn/apacherocketmq/rocketmq-broker:4.9.4-alpine-operator-0.3.0
broker-0-replica-1   1/1     43m   broker         registry.zdevops.com.cn/apacherocketmq/rocketmq-broker:4.9.4-alpine-operator-0.3.0
broker-1-master      1/1     27s   broker         registry.zdevops.com.cn/apacherocketmq/rocketmq-broker:4.9.4-alpine-operator-0.3.0
broker-1-replica-1   1/1     27s   broker         registry.zdevops.com.cn/apacherocketmq/rocketmq-broker:4.9.4-alpine-operator-0.3.0
name-service         2/2     43m   name-service   registry.zdevops.com.cn/apacherocketmq/rocketmq-nameserver:4.9.4-alpine-operator-0.3.0

驗證 Pods:

$ kubectl get pods -o wide -n zdevops

NAME                                 READY   STATUS    RESTARTS   AGE   IP               NODE              NOMINATED NODE   READINESS GATES
broker-0-master-0                    1/1     Running   0          44m   10.233.87.117    ks-k8s-master-1   <none>           <none>
broker-0-replica-1-0                 1/1     Running   0          26m   10.233.117.99    ks-k8s-master-0   <none>           <none>
broker-1-master-0                    1/1     Running   0          72s   10.233.116.117   ks-k8s-master-2   <none>           <none>
broker-1-replica-1-0                 1/1     Running   0          72s   10.233.117.100   ks-k8s-master-0   <none>           <none>
console-8d685798f-hnmvg              1/1     Running   0          44m   10.233.116.113   ks-k8s-master-2   <none>           <none>
name-service-0                       1/1     Running   0          44m   10.233.116.114   ks-k8s-master-2   <none>           <none>
name-service-1                       1/1     Running   0          27m   10.233.87.120    ks-k8s-master-1   <none>           <none>
rocketmq-operator-6db8ccc685-5hkk8   1/1     Running   0          44m   10.233.116.112   ks-k8s-master-2   <none>           <none>

在 KubeSphere 控制臺驗證:

在 RocketMQ 控制臺驗證:

常見問題

沒裝 gcc 編譯工具

報錯資訊:

[root@zdevops-master rocketmq-operator]# make docker-build IMG=${IMAGE_URL}
/data/k8s-yaml/rocketmq-operator/bin/controller-gen rbac:roleName=rocketmq-operator crd:generateEmbeddedObjectMeta=true webhook paths="./..." output:dir=deploy output:crd:artifacts:config=deploy/crds
head -n 14 deploy/role_binding.yaml > deploy/role.yaml.bak
cat deploy/role.yaml >> deploy/role.yaml.bak
rm deploy/role.yaml && mv deploy/role.yaml.bak deploy/role.yaml
/data/k8s-yaml/rocketmq-operator/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..."
/usr/local/go/src/net/cgo_linux.go:12:8: no such package located
Error: not all generators ran successfully
run `controller-gen object:headerFile=hack/boilerplate.go.txt paths=./... -w` to see all available markers, or `controller-gen object:headerFile=hack/boilerplate.go.txt paths=./... -h` for usage
make: *** [generate] Error 1

解決方案:

$ yum install gcc

go mod 錯誤

報錯資訊:

# 執行 make docker-build IMG=${IMAGE_URL} 報錯

go: creating new go.mod: module tmp
Downloading sigs.k8s.io/controller-tools/cmd/[email protected]
go get: added sigs.k8s.io/controller-tools v0.7.0
/data/build/rocketmq-operator/bin/controller-gen rbac:roleName=rocketmq-operator crd:generateEmbeddedObjectMeta=true webhook paths="./..." output:dir=deploy output:crd:artifacts:config=deploy/crds
Error: err: exit status 1: stderr: go: github.com/google/[email protected]: missing go.sum entry; to add it:
        go mod download github.com/google/uuid

Usage:
  controller-gen [flags]
  
......

output rules (optionally as output:<generator>:...)

+output:artifacts[:code=<string>],config=<string>  package  outputs artifacts to different locations, depending on whether they're package-associated or not.   
+output:dir=<string>                               package  outputs each artifact to the given directory, regardless of if it's package-associated or not.      
+output:none                                       package  skips outputting anything.                                                                          
+output:stdout                                     package  outputs everything to standard-out, with no separation.                                             

run `controller-gen rbac:roleName=rocketmq-operator crd:generateEmbeddedObjectMeta=true webhook paths=./... output:dir=deploy output:crd:artifacts:config=deploy/crds -w` to see all available markers, or `controller-gen rbac:roleName=rocketmq-operator crd:generateEmbeddedObjectMeta=true webhook paths=./... output:dir=deploy output:crd:artifacts:config=deploy/crds -h` for usage
make: *** [manifests] Error 1

解決方案:

go mod tidy

結束語

本文只是初步介紹了 RocketMQ 在 K8s 平臺上的單 Master 節點和多 Master 多 Slave-異步復制模式部署的方法,屬于入門級,

在生產環境中還需要根據實際環境優化配置,例如調整集群的 Broker 數量、Master 和 Slave 的分配、性能調優、配置優化等,

本文由博客一文多發平臺 OpenWrite 發布!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/538727.html

標籤:其他

上一篇:KubeSphere 多行日志采集方案深度探索 

下一篇:MySQL日志管理、備份與恢復

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more