| 主機名 | 系統版本 | 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
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
文件修改前后變化如下圖:
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
4 查看 rabbitmq 集群 pvc、pv
[root@k8s-master1 rabbitmq-cluster]# kubectl get pvc -n rabbitmq-cluster
[root@k8s-master1 rabbitmq-cluster]# kubectl get pv
5 查看 rabbitmq 集群 svc
[root@k8s-master1 rabbitmq-cluster]# kubectl get svc,ep -n rabbitmq-cluster
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
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集群三節點運行正常。
8 訪問 rabbitmq 集群的 web 界面,查看集群的狀態
訪問 http://<nodeip>:30072,用戶名和密碼都是 guest。
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








