自学内容网 自学内容网

使用 Helm 部署 RabbitMQ 高可用集群(HA)

在这篇教程中,我们将介绍如何通过 Helm 在 Kubernetes 集群中部署 RabbitMQ 高可用集群(HA)。我们将从下载和配置 Helm Chart 包开始,接着会介绍一些常见错误的解决方案,以帮助你顺利完成部署。

步骤 1:搜索并下载 RabbitMQ HA Helm Chart

首先,添加一些常见的 Helm 仓库,如 Bitnami、Aliyun 和 Azure 等

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add stable http://mirror.azure.cn/kubernetes/charts
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
helm repo add incubator https://charts.helm.sh/incubator
helm repo update

然后,我们需要在 Helm 仓库中搜索 RabbitMQ HA Chart。使用以下命令可以列出所有相关的 RabbitMQ Chart。

helm search repo rabbitmq

输出示例:

NAME                                    CHART VERSION   APP VERSION     DESCRIPTION
aliyun/rabbitmq                         0.6.21          3.7.3           Open source message broker software that implem...
aliyun/rabbitmq-ha                      1.0.0           3.7.3           Highly available RabbitMQ cluster, the open sou...
bitnami/rabbitmq                        15.2.3          4.0.5           RabbitMQ is an open source general-purpose mess...
bitnami/rabbitmq-cluster-operator       4.4.2           2.12.0          The RabbitMQ Cluster Kubernetes Operator automa...
stable/rabbitmq                         0.6.21          3.7.3           Open source message broker software that implem...
stable/rabbitmq-ha                      1.0.0           3.7.3           Highly available RabbitMQ cluster, the open sou...

选择 stable/rabbitmq-ha,然后使用 helm pull 下载该 Chart 包。

helm pull stable/rabbitmq-ha

解压下载的 Chart 包:

tar -xvf rabbitmq-ha-1.0.0.tgz
cd rabbitmq-ha/

步骤 2:修改 values.yaml 配置文件

在 Chart 解压后,我们可以找到 values.yaml 文件,修改其中的配置以满足我们的需求。

以下是关键配置项的修改示例:

rabbitmqUsername: rabbitmq
rabbitmqPassword: rabbitmq
image:
  repository: docker-0.unsee.tech/rabbitmq
  tag: 3.7-alpine
  pullPolicy: IfNotPresent
service:
  type: NodePort
persistentVolume:
  enabled: false  # 如果需要开启持久化存储,将此项改为 true
  accessModes:
    - ReadWriteMany
  size: 8Gi

在这里,我们更改了 RabbitMQ 的用户名和密码,还设置了 RabbitMQ 镜像的自定义地址。同时,我们配置了 NodePort 类型的服务,并禁用了持久化存储(你可以根据需求修改为启用)。

步骤 3:安装 RabbitMQ HA

完成配置后,使用 Helm 安装 RabbitMQ HA 集群。

helm install rabbitmq-ha ./rabbitmq-ha

安装完成后,可以通过以下命令查看服务和 Pod 状态。

查看服务状态:

kubectl get svc

输出示例:

NAME                      TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                                         AGE
kubernetes                ClusterIP   10.96.0.1    <none>        443/TCP                                         3d21h
rabbitmq-ha-rabbitmq-ha   NodePort    10.96.3.50   <none>        15672:32241/TCP,5672:31214/TCP,4369:32046/TCP   2m53s

查看 Pod 状态:

kubectl get pod

输出示例:

NAME                                              READY   STATUS             RESTARTS   AGE
nfs-subdir-external-provisioner-dc68ff47f-g8k6n   0/1     ImagePullBackOff   0          47m
rabbitmq-ha-rabbitmq-ha-0                         1/1     Running            0          3m7s
rabbitmq-ha-rabbitmq-ha-1                         1/1     Running            0          84s
rabbitmq-ha-rabbitmq-ha-2                         1/1     Running            0          60s

步骤 4:浏览器访问 RabbitMQ 管理界面

RabbitMQ 管理界面可以通过 NodePort 服务进行访问,使用以下 IP 地址和端口:

http://192.168.80.130:32241/

登录账号密码为:

用户名:rabbitmq
密码:rabbitmq

在这里插入图片描述

常见错误及解决办法

错误 1:API 版本不兼容

如果在安装过程中遇到以下错误:

Error: INSTALLATION FAILED: unable to build kubernetes objects from release manifest: [resource mapping not found for name: "rabbitmq-ha-rabbitmq-ha" namespace: "" from "": no matches for kind "Role" in version "rbac.authorization.k8s.io/v1beta1"]

分析: 这是因为 Kubernetes 1.16 版本后,许多 API 版本被更新或废弃,rbac.authorization.k8s.io/v1beta1apps/v1beta1 已被废弃。

解决方法: 将 Helm Chart 中的 API 版本更新为适用于 Kubernetes 1.22 及以上版本的 API 版本,具体如下:

  • rbac.authorization.k8s.io/v1(替代 v1beta1
  • apps/v1(替代 v1beta1

你需要在 templates/ 目录下的资源定义文件中手动更新这些 API 版本。

错误 2:StatefulSet 的 selector 和 labels 不匹配

如果遇到以下错误:

Error: INSTALLATION FAILED: StatefulSet.apps "rabbitmq-ha-rabbitmq-ha" is invalid: [spec.selector: Required value, spec.template.metadata.labels: Invalid value: map[string]string{"app":"rabbitmq-ha", "release":"rabbitmq-ha"}: `selector` does not match template `labels`]

分析: 错误表明,StatefulSetspec.selector 部分与 spec.template.metadata.labels 部分的内容不一致。

解决方法: 打开 statefulset.yaml 文件,确保 spec.selector.matchLabelsspec.template.metadata.labels 部分的标签一致。

例如,修改以下部分:

selector:
  matchLabels:
    app: {{ template "rabbitmq-ha.name" . }}
    release: {{ .Release.Name }}

同时确保 template.metadata.labels 部分的标签一致:

labels:
  app: {{ template "rabbitmq-ha.name" . }}
  release: {{ .Release.Name }}

完整的statefulset.yaml 示例:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: {{ template "rabbitmq-ha.fullname" . }}
  labels:
    app: {{ template "rabbitmq-ha.name" . }}
    chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
spec:
  serviceName: {{ template "rabbitmq-ha.fullname" . }}
  replicas: {{ .Values.replicaCount }}
  updateStrategy:
    type: {{ .Values.updateStrategy }}
  selector:
    matchLabels:
      app: {{ template "rabbitmq-ha.name" . }}
      release: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app: {{ template "rabbitmq-ha.name" . }}
        release: {{ .Release.Name }}
      annotations:
        {{- if not .Values.customConfigMap }}
        checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
        {{- end }}
    spec:
      terminationGracePeriodSeconds: 10
      serviceAccountName: {{ template "rabbitmq-ha.serviceAccountName" . }}
      containers:
        - name: {{ .Chart.Name }}
          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: epmd
              protocol: TCP
              containerPort: 4369
            - name: amqp
              protocol: TCP
              containerPort: 5672
            - name: http
              protocol: TCP
              containerPort: 15672
            {{- if .Values.rabbitmqSTOMPPlugin.enabled }}
            - name: stomp-tcp
              protocol: TCP
              containerPort: 61613
            - name: stomp-ssl
              protocol: TCP
              containerPort: 61614
            {{- end }}
            {{- if .Values.rabbitmqWebSTOMPPlugin.enabled }}
            - name: stomp-ws
              protocol: TCP
              containerPort: 15674
            {{- end }}
            {{- if .Values.rabbitmqMQTTPlugin.enabled }}
            - name: mqtt-tcp
              protocol: TCP
              containerPort: 1883
            - name: mqtt-ssl
              protocol: TCP
              containerPort: 8883
            {{- end }}
            {{- if .Values.rabbitmqWebMQTTPlugin.enabled }}
            - name: mqtt-ws
              protocol: TCP
              containerPort: 15675
            {{- end }}
          livenessProbe:
            exec:
              command:
                - rabbitmqctl
                - status
            initialDelaySeconds: 30
            timeoutSeconds: 5
          readinessProbe:
            exec:
              command:
                - rabbitmqctl
                - status
            initialDelaySeconds: 10
            timeoutSeconds: 5
          env:
            - name: MY_POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: RABBITMQ_USE_LONGNAME
              value: "true"
            - name: RABBITMQ_NODENAME
              value: "rabbit@$(MY_POD_IP)"
            - name: K8S_SERVICE_NAME
              value: {{ template "rabbitmq-ha.fullname" . }}
            - name: RABBITMQ_ERLANG_COOKIE
              valueFrom:
                secretKeyRef:
                  name: {{ template "rabbitmq-ha.fullname" . }}
                  key: rabbitmq-erlang-cookie
            {{- if .Values.rabbitmqHipeCompile }}
            - name: RABBITMQ_HIPE_COMPILE
              value: {{ .Values.rabbitmqHipeCompile | quote }}
            {{- end }}
            - name: RABBITMQ_DEFAULT_USER
              value: {{ .Values.rabbitmqUsername | quote }}
            - name: RABBITMQ_DEFAULT_PASS
              valueFrom:
                secretKeyRef:
                  name: {{ template "rabbitmq-ha.fullname" . }}
                  key: rabbitmq-password
            - name: RABBITMQ_DEFAULT_VHOST
              value: {{ .Values.rabbitmqVhost | quote }}
          resources:
{{ toYaml .Values.resources | indent 12 }}
          volumeMounts:
            - name: data
              mountPath: /var/lib/rabbitmq
            - name: config
              mountPath: /etc/rabbitmq
      {{- if .Values.nodeSelector }}
      nodeSelector:
{{ toYaml .Values.nodeSelector | indent 8 }}
      {{- end }}
      {{- if .Values.tolerations }}
      tolerations:
{{ toYaml .Values.tolerations | indent 8 }}
      {{- end }}
      {{- if eq .Values.podAntiAffinity "hard" }}
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - topologyKey: "kubernetes.io/hostname"
              labelSelector:
                matchLabels:
                  app: {{ template "rabbitmq-ha.name" . }}
                  release: {{ .Release.Name }}
      {{- else if eq .Values.podAntiAffinity "soft" }}
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 1
              podAffinityTerm:
                topologyKey: kubernetes.io/hostname
                labelSelector:
                  matchLabels:
                    app: {{ template "rabbitmq-ha.name" . }}
                    release: {{ .Release.Name }}
      {{- end }}
      volumes:
        - name: config
          configMap:
            name: {{ template "rabbitmq-ha.fullname" . }}
{{- if .Values.persistentVolume.enabled }}
  volumeClaimTemplates:
    - metadata:
        name: data
        annotations:
        {{- range $key, $value := .Values.persistentVolume.annotations }}
          {{ $key }}: {{ $value }}
        {{- end }}
      spec:
        accessModes:
        {{- range .Values.persistentVolume.accessModes }}
          - {{ . | quote }}
        {{- end }}
        resources:
          requests:
            storage: {{ .Values.persistentVolume.size | quote }}
      {{- if .Values.persistentVolume.storageClass }}
      {{- if (eq "-" .Values.persistentVolume.storageClass) }}
        storageClassName: ""
      {{- else }}
        storageClassName: "{{ .Values.persistentVolume.storageClass }}"
      {{- end }}
      {{- end }}
{{- else }}
        - name: data
          emptyDir: {}
{{- end }}

结论

通过以上步骤,你成功地在 Kubernetes 集群上使用 Helm 部署了 RabbitMQ 高可用集群。你可以使用浏览器访问管理界面,并根据需要调整配置,处理常见的安装错误。在部署过程中,确保 Helm Chart 与 Kubernetes API 版本兼容,才能顺利完成安装。


原文地址:https://blog.csdn.net/m0_46423830/article/details/145241009

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!