在k8s中部署rabbitmq鏡像集群


1 環境說明

主機名 系統版本 IP地址 cpu/內存/磁盤 用途 軟件版本
k8s_nfs CentOS7.5 172.16.1.60 2核/2GB/60GB nfs存儲 nfs-utils-1.3.0-0.68
k8s-master1 CentOS7.5 172.16.1.81 2核/2GB/60GB kubernetes master1節點 k8s v1.20.0
k8s-master2 CentOS7.5 172.16.1.82 2核/2GB/60GB kubernetes master2節點 k8s v1.20.0
k8s-node1 CentOS7.5 172.16.1.83 4核/8GB/60GB kubernetes node1節點 k8s v1.20.0
k8s-node2 CentOS7.5 172.16.1.84 4核/8GB/60GB kubernetes node2節點 k8s v1.20.0

補充: kubernetes集群的控制節點我打了污點不能被pod調度使用。

1 nfs服務部署
節點: k8s_nfs
用途: k8s pod 數據持久化存儲
說明: nfs服務的搭建過程不再贅述
驗證:
[root@k8s_nfs ~]# showmount -e 172.16.1.60
Export list for 172.16.1.60:
/ifs/kubernetes *

2 nfs-subdir-external-provisioner插件部署
節點: kubernetes集群
用途: 為中間件pod提供pvc自動供給
說明: nfs pvc自動供給插件的部署過程不再贅述。修改"deployment.yaml"文件中連接nfs服務的地址和nfs共享目錄參數;修改"class.yaml"
文件中"archiveOnDelete"(刪除時是否存檔)參數為 archiveOnDelete: "true",刪除pod時保留pod數據,默認為false時為不保留數據。
注意: 在部署前需要在k8s各個節點上部署nfs的客戶端(yum install nfs-utils -y),否則無法部署成功。

補充:
(1) gitlab項目地址: https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
(2) 下載 deploy 目錄如下文件
class.yaml、deployment.yaml、rbac.yaml

查看:
[root@k8s-master1 nfs-subdir-external-provisioner-master]# ls | xargs -i kubectl apply -f {}
[root@k8s-master1 nfs-subdir-external-provisioner-master]# kubectl get deployment,pod,svc,sc -n default

image-20220214160856064

2 rabbitmq集群部署(鏡像)

2.1 rabbitmq介紹
1 簡介
RabbitMQ是一個開源的消息代理的隊列服務器,用來通過普通協議在完全不同的應用之間共享數據。支持異步處理、流量削峰、日志處理、應用解耦。

2 RabbitMQ集群節點之間的認證方式
(1) 通過Erlang Cookie,相當於共享秘鑰的概念,長度任意,只要所有節點都一致即可。
(2) rabbitmq server在啟動的時候,erlang VM會自動創建一個隨機的cookie文件。
cookie文件的位置是/var/lib/rabbitmq/.erlang.cookie 或者 /root/.erlang.cookie,為保證cookie的完全一致,采用從一個節點
copy的方式。
(3) Erlang Cookie是保證不同節點可以相互通信的密鑰,要保證集群中的不同節點相互通信必須共享相同的Erlang Cookie。具體的目錄存放
在/var/lib/rabbitmq/.erlang.cookie。
(4) 從rabbitmqctl命令的工作原理說起,RabbitMQ底層是通過Erlang架構來實現的,所以rabbitmqctl會啟動Erlang節點,並基於Erlang
節點來使用Erlang系統連接RabbitMQ節點,在連接過程中需要正確的Erlang Cookie和節點名稱,Erlang節點通過交換Erlang Cookie以獲得
認證。

3 RabbitMQ集群模式
(1) 單機模式
(2) 普通集群模式(無高可用性)
(3) 鏡像集群模式(高可用性),最常用的集群模式

4 RabbitMQ節點類型
(1) RAM node
只保存狀態到內存。內存節點將所有的隊列、交換機、綁定、用戶、權限和vhost的元數據定義存儲在內存中,好處是可以使得像交換機和隊列聲明等操
作更加的快速。
(2) Disk node
將元數據存儲在磁盤中。單節點系統只允許磁盤類型的節點,防止重啟RabbitMQ的時候,丟失系統的配置信息。
(3) 內存節點雖然不寫入磁盤,但是它執行比磁盤節點要快。RabbitMQ集群中,只需要一個磁盤節點來保存狀態就足夠了;如果集群中只有內存節點,
那么不能停止它們,否則所有的狀態,消息等都會丟失。
(4) RabbitMQ要求在集群中至少有一個磁盤節點,所有其他節點可以是內存節點,當節點加入或者離開集群時,必須要將該變更通知到至少一個磁盤
節點。如果集群中唯一的一個磁盤節點崩潰的話,集群仍然可以保持運行,但是無法進行其他操作(增刪改查),直到節點恢復。解決方案:設置兩個磁
盤節點,至少有一個是可用的,可以保存元數據的更改。
(5) 為保證數據持久性,當前實驗所有node節點跑在disk模式。
2.2 yaml配置文件
 
           
1 說明
rabbitmq集群運行在rabbitmq-cluster命名空間下,采用StatefulSet與Headless Service模式部署有狀態的RabbitMQ集群。
[root@k8s-master1 ~]# mkdir -p rabbitmq-cluster
[root@k8s-master1 ~]# cd rabbitmq-cluster/
[root@k8s-master1 rabbitmq-cluster]# ls -l
total 0
# rabbitmq集群部署文件
-rw-r--r-- 1 root root 0 Feb 16 14:38 rabbitmq-cluster.yml

2 rabbitmq-cluster.yml
[root@k8s-master1 rabbitmq-cluster]# cat rabbitmq-cluster.yml
---
apiVersion: v1
kind: Service
metadata:
  name: rabbitmq-cluster-management
  namespace: rabbitmq-cluster
  labels:
    app: rabbitmq
spec:
  ports:
  - port: 15672
    name: http
    nodePort: 30072
  selector:
    app: rabbitmq
  type: NodePort
---
apiVersion: v1
kind: Service
metadata:
  name: rabbitmq-cluster
  namespace: rabbitmq-cluster
  labels:
    app: rabbitmq
spec:
  ports:
  - port: 5672
    name: amqp
  - port: 4369
    name: epmd
  - port: 25672
    name: rabbitmq-dist
  clusterIP: None
  selector:
    app: rabbitmq
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  namespace: rabbitmq-cluster
  name: rabbitmq-cluster
spec:
  serviceName: rabbitmq-cluster
  replicas: 3
  selector:
    matchLabels:
      app: rabbitmq
  template:
    metadata:
      labels:
        app: rabbitmq
    spec:
      containers:
      - name: rabbitmq
        image: rabbitmq:3.7.26-management
        lifecycle:
          postStart:
            exec:
              command:
              - /bin/sh
              - -c
              - >
                if [ -z "$(grep rabbitmq-cluster.rabbitmq-cluster.svc.cluster.local /etc/resolv.conf)" ]; then
                  cp -a /etc/resolv.conf /etc/resolv.conf.bak;
                  sed "s/^search \([^ ]\+\)/search rabbitmq-cluster.\1 \1/" /etc/resolv.conf > /etc/resolv.conf.new;
                  cat /etc/resolv.conf.new > /etc/resolv.conf;
                  rm /etc/resolv.conf.new;
                fi;
                until rabbitmqctl node_health_check; do sleep 1; done;
                if [ -z "$(rabbitmqctl cluster_status | grep rabbitmq-cluster-0)" ]; then
                  touch /gotit
                  rabbitmqctl stop_app;
                  rabbitmqctl reset;
                  rabbitmqctl join_cluster rabbit@rabbitmq-cluster-0;
                  rabbitmqctl start_app;
                else
                  touch /notget
                fi;
        env:
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: RABBITMQ_ERLANG_COOKIE
          value: "YZSDHWMFSMKEMBDHSGGZ"
        - name: RABBITMQ_NODENAME
          value: "rabbit@$(MY_POD_NAME)"
        ports:
        - name: http
          protocol: TCP
          containerPort: 15672
        - name: amqp
          protocol: TCP
          containerPort: 5672
        livenessProbe:
          tcpSocket:
            port: amqp
          initialDelaySeconds: 5
          timeoutSeconds: 5
          periodSeconds: 10
        readinessProbe:
          tcpSocket:
            port: amqp
          initialDelaySeconds: 15
          timeoutSeconds: 5
          periodSeconds: 20
        volumeMounts:
        - name: rabbitmq-data
          mountPath: /var/lib/rabbitmq
  volumeClaimTemplates:
  - metadata:
      name: rabbitmq-data
      #annotations:
      #  volume.beta.kubernetes.io/storage-class: "rabbitmq-nfs-storage"
    spec:
      storageClassName: "managed-nfs-storage"
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 10Gi

(1) rabbitmq端口號說明
4369    # erlang 發現端口
5672    # client 端通信端口
15672   # 管理界面 ui 端口
25672   # server 間內部通信端口
訪問 RabbitMQ 管理界面:  http://IP:15672/
連接 RabbitMQ 用client端通信端口:  amqp://guest:guest@localhost:5672/

(2) yml文件中的腳本說明
1) 修改域名解析
if [ -z "$(grep rabbitmq-cluster.rabbitmq-cluster.svc.cluster.local /etc/resolv.conf)" ]; then
  cp -a /etc/resolv.conf /etc/resolv.conf.bak;
  sed "s/^search \([^ ]\+\)/search rabbitmq-cluster.\1 \1/" /etc/resolv.conf > /etc/resolv.conf.new;
  cat /etc/resolv.conf.new > /etc/resolv.conf;
  rm /etc/resolv.conf.new;
fi;

說明:
因為rabbitmq節點加入集群需要使用主機名,添加rabbitmq集群所在svc的域名配置,方便rabbitmq直接使用主機名進行訪問,/etc/resolv.conf
文件修改前后變化如下圖:

圖示: image-20220218123552455

 
           
2) 將rabbitmq節點加入集群
until rabbitmqctl node_health_check; do sleep 1; done;
if [ -z "$(rabbitmqctl cluster_status | grep rabbitmq-cluster-0)" ]; then
  touch /gotit
  rabbitmqctl stop_app;
  rabbitmqctl reset;
  rabbitmqctl join_cluster rabbit@rabbitmq-cluster-0;
  rabbitmqctl start_app;
else
  touch /notget
fi;

說明:
rabbitmq服務啟動並且健康檢查通過后,將該rabbitmq節點以rabbitmq-cluster-0主機名為基准加入集群中。

2.3 部署
1 創建命名空間
[root@k8s-master1 rabbitmq-cluster]# kubectl create namespace rabbitmq-cluster

2 應用配置文件
[root@k8s-master1 rabbitmq-cluster]# kubectl apply -f rabbitmq-cluster.yml
service/rabbitmq-cluster-management created
service/rabbitmq-cluster created
statefulset.apps/rabbitmq-cluster created
3 查看 rabbitmq 集群 pod
[root@k8s-master1 rabbitmq-cluster]# kubectl get pod -n rabbitmq-cluster

圖示: image-20220217175224900

4 查看 rabbitmq 集群 pvc、pv
[root@k8s-master1 rabbitmq-cluster]# kubectl get pvc -n rabbitmq-cluster
[root@k8s-master1 rabbitmq-cluster]# kubectl get pv

圖示: image-20220217175350113

5 查看 rabbitmq 集群 svc
[root@k8s-master1 rabbitmq-cluster]# kubectl get svc,ep -n rabbitmq-cluster

圖示: image-20220217175504676

6 查看 rabbitmq 集群 nfs 共享存儲
[root@k8s_nfs ~]# ls -l /ifs/kubernetes/
[root@k8s_nfs ~]# ls -l /ifs/kubernetes/*/

# RabbitMQ的三個容器節點的.erlang.cookie內容是一致的
[root@k8s_nfs ~]# cat /ifs/kubernetes/*/.erlang.cookie

圖示: image-20220217175726540

7 驗證RabbitMQ集群
登錄 rabbitmq-0|1|2 容器查看集群狀態
[root@k8s-master1 rabbitmq-cluster]# kubectl exec -it pod/rabbitmq-cluster-0 -n rabbitmq-cluster -- bash
root@rabbitmq-cluster-0:/# rabbitmqctl cluster_status

說明: 可以看到rabbitmq集群三節點運行正常。

圖示: image-20220217180048078

8 訪問 rabbitmq 集群的 web 界面,查看集群的狀態
訪問 http://<nodeip>:30072,用戶名和密碼都是 guest。

圖示: image-20220217180548962

2.4 測試
1 說明
模擬RabbitMQ節點故障,重啟其中的一個node節點,比如rabbitmq-cluster-0,然后觀察集群狀態。

2 刪除rabbitmq-cluster-0節點
[root@k8s-master1 rabbitmq-cluster]# kubectl delete pod rabbitmq-cluster-0 -n rabbitmq-cluster
pod "rabbitmq-cluster-0" deleted

說明:
此時在web界面查看集群的狀態,先后經歷了三個狀態,紅色表示節點故障,黃色表示節點恢復中(暫不可用),綠色表示節點運行正常。

3 查看pod,發現rabbitmq-cluster-0節點30s左右重啟成功
[root@k8s-master1 rabbitmq-cluster]# kubectl get pod -n rabbitmq-cluster
NAME                 READY   STATUS   RESTARTS   AGE
rabbitmq-cluster-0   1/1     Running   0         30s
rabbitmq-cluster-1   1/1     Running   0         30m
rabbitmq-cluster-2   1/1     Running   0         30m

4 查看RabbitMQ集群狀態
發現rabbitmq集群各節點狀態正常。
# kubectl exec -it rabbitmq-cluster-1 -n rabbitmq-cluster -- rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq-cluster-1 ...
[{nodes,[{disc,['rabbit@rabbitmq-cluster-0','rabbit@rabbitmq-cluster-1',
               'rabbit@rabbitmq-cluster-2']}]},
{running_nodes,['rabbit@rabbitmq-cluster-0','rabbit@rabbitmq-cluster-2',
                 'rabbit@rabbitmq-cluster-1']},
{cluster_name,<<"rabbit@rabbitmq-cluster-0.rabbitmq-cluster.rabbitmq-cluster.svc.cluster.local">>},
{partitions,[]},
{alarms,[{'rabbit@rabbitmq-cluster-0',[]},
         {'rabbit@rabbitmq-cluster-2',[]},
         {'rabbit@rabbitmq-cluster-1',[]}]}]
[root@k8s-master1 rabbitmq-cluster]#

5 客戶端訪問RabbitMQ集群地址
(1) 訪問域名如下,端口為5672
# kubectl run -i --tty --image busybox:1.28.4 dns-test --restart=Never --rm /bin/sh
/ # nslookup rabbitmq-cluster.rabbitmq-cluster.svc.cluster.local
Server:   172.28.0.2
Address 1: 172.28.0.2 kube-dns.kube-system.svc.cluster.local

Name:     rabbitmq-cluster.rabbitmq-cluster.svc.cluster.local
Address 1: 172.27.36.88   rabbitmq-cluster-2.rabbitmq-cluster.rabbitmq-cluster.svc.cluster.local
Address 2: 172.27.169.155 rabbitmq-cluster-1.rabbitmq-cluster.rabbitmq-cluster.svc.cluster.local
Address 3: 172.27.36.87   rabbitmq-cluster-0.rabbitmq-cluster.rabbitmq-cluster.svc.cluster.local
/ #

(2) 連接方式
客戶端可以連接RabbitMQ集群中的任意一個節點,如果一個節點故障,客戶端自行重新連接到其他的可用節點,也就是說,RabbitMQ集群有"重連"機
制,但是這種集群連接方式對客戶端不透明,不太建議這種連接方式。推薦方式,給客戶端提供一個統一的透明的集群連接地址,在集群前面部署LVS或
Haproxy,通過四層負載均衡代理RabbitMQ的三個node節點的5672端口。

6 集群故障修復
[root@k8s-master1 rabbitmq-cluster]# kubectl delete -f rabbitmq-cluster.yml
[root@k8s_nfs ~]# rm -rf /ifs/kubernetes/*/*
[root@k8s-master1 rabbitmq-cluster]# kubectl apply -f rabbitmq-cluster.yml


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM