3.9.7 StatefulSet部署rabbitmq

使用 StatefulSet 部署有状态服务时,可以使用 volumeClaimTemplates 自动为每个 Pod 生成PVC,并挂载至容器中,大大降低了手动创建管理存储的难度和复杂度。

假设需要搭建一个三节点的 RabbitMQ 集群到 K8s 中,并且需要实现数据的持久化,此时可以通过 StatefulSet 创建三个副本,并且通过 volumeClaimTemplates 绑定存储。

1、下载部署文件

[root@k8s-master01 ~]# git clone https://gitee.com/dukuan/k8s.git

2、更改配置文件

[root@k8s-master01 ~]# cd k8s/k8s-rabbitmq-cluster/
# 修改配置文件
[root@k8s-master01 k8s-rabbitmq-cluster]# cat rabbitmq-cluster-ss.yaml 
kind: StatefulSet
apiVersion: apps/v1
metadata:
  labels:
    app: rmq-cluster
  name: rmq-cluster
  namespace: public-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: rmq-cluster
  serviceName: rmq-cluster
  template:
    metadata:
      labels:
        app: rmq-cluster
    spec:
      containers:
      - args:
        - -c
        - cp -v /etc/rabbitmq/rabbitmq.conf ${RABBITMQ_CONFIG_FILE}; exec docker-entrypoint.sh
          rabbitmq-server
        command:
        - sh
        env:
        - name: RABBITMQ_DEFAULT_USER
          valueFrom:
            secretKeyRef:
              key: username
              name: rmq-cluster-secret
        - name: RABBITMQ_DEFAULT_PASS
          valueFrom:
            secretKeyRef:
              key: password
              name: rmq-cluster-secret
        - name: RABBITMQ_ERLANG_COOKIE
          valueFrom:
            secretKeyRef:
              key: cookie
              name: rmq-cluster-secret
        - name: K8S_SERVICE_NAME
          value: rmq-cluster
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: RABBITMQ_USE_LONGNAME
          value: "true"
        - name: RABBITMQ_NODENAME
          value: rabbit@$(POD_NAME).rmq-cluster.$(POD_NAMESPACE).svc.cluster.local
        - name: RABBITMQ_CONFIG_FILE
          value: /var/lib/rabbitmq/rabbitmq.conf
        image: registry.cn-hangzhou.aliyuncs.com/abroad_images/rabbitmq:3.13.6-management-alpine 
        imagePullPolicy: IfNotPresent
        livenessProbe:
          exec:
            command:
            - rabbitmqctl
            - status
          initialDelaySeconds: 30
          timeoutSeconds: 10
        name: rabbitmq
        ports:
        - containerPort: 15672
          name: http
          protocol: TCP
        - containerPort: 5672
          name: amqp
          protocol: TCP
        readinessProbe:
          exec:
            command:
            - rabbitmqctl
            - status
          initialDelaySeconds: 10
          timeoutSeconds: 10
        volumeMounts:
        - mountPath: /etc/rabbitmq
          name: config-volume
          readOnly: false
        - mountPath: /var/lib/rabbitmq
          name: rabbitmq-storage
          readOnly: false
      serviceAccountName: rmq-cluster
      terminationGracePeriodSeconds: 30
      volumes:
      - configMap:
          items:
          - key: rabbitmq.conf
            path: rabbitmq.conf
          - key: enabled_plugins
            path: enabled_plugins
          name: rmq-cluster-config
        name: config-volume
  volumeClaimTemplates:
  - metadata:
      name: rabbitmq-storage
    spec:
      accessModes:
      - ReadWriteMany
      storageClassName: "nfs-csi"
      resources:
        requests:
          storage: 4Gi

3、创建RabbitMQ 集群

[root@k8s-master01 k8s-rabbitmq-cluster]# kubectl create ns public-service
[root@k8s-master01 k8s-rabbitmq-cluster]# kaf .

4、验证相关资源是否成功创建

# 查看创建的pod
[root@k8s-master01 ~]# kgp -n public-service
NAME            READY   STATUS    RESTARTS   AGE
rmq-cluster-0   1/1     Running   0          104s
rmq-cluster-1   1/1     Running   0          75s
rmq-cluster-2   1/1     Running   0          48s

# 查看创建的pvc
[root@k8s-master01 ~]# kg pvc -n public-service 
NAME                             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
rabbitmq-storage-rmq-cluster-0   Bound    pvc-9ee54de2-2dc8-452a-bbfa-4015883251f1   4Gi        RWX            nfs-csi        <unset>                 3m45s
rabbitmq-storage-rmq-cluster-1   Bound    pvc-0e1b106d-ef60-45b5-a62f-b84db434ff8f   4Gi        RWX            nfs-csi        <unset>                 3m16s
rabbitmq-storage-rmq-cluster-2   Bound    pvc-1bd15630-b253-4d1e-934b-3fb3a2024798   4Gi        RWX            nfs-csi        <unset>                 2m49s

# 查看创建的svc
[root@k8s-master01 ~]# kg svc -n public-service 
NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                          AGE
rmq-cluster            ClusterIP   None             <none>        5672/TCP                         4m32s
rmq-cluster-balancer   NodePort    10.104.133.109   <none>        15672:32115/TCP,5672:32282/TCP   4m32s

5、在浏览器中输入任意node_ip:32115访问集群环境,这里使用的是10.0.0.20:32115,账号为RABBITMQ_USER,密码为RABBITMQ_PASS

# 查看账户为RABBITMQ_USER 密码为RABBITMQ_PASS
[root@k8s-master01 ~]# cd k8s/k8s-rabbitmq-cluster/
[root@k8s-master01 k8s-rabbitmq-cluster]# cat rabbitmq-secret.yaml 
kind: Secret
apiVersion: v1
metadata:
  name: rmq-cluster-secret
  namespace: public-service
stringData:
  cookie: ERLANG_COOKIE
  password: RABBITMQ_PASS
  url: amqp://RABBITMQ_USER:RABBITMQ_PASS@rmq-cluster-balancer
  username: RABBITMQ_USER
type: Opaque

image-20250321120923859

6、环境复原

[root@k8s-master01 ~]# cd k8s/k8s-rabbitmq-cluster/
[root@k8s-master01 k8s-rabbitmq-cluster]# k delete -f .
[root@k8s-master01 k8s-rabbitmq-cluster]# k delete  pvc rabbitmq-storage-rmq-cluster-0