隨著云原生化流行的大趨勢,我們的基礎(chǔ)組件也需要逐漸上Kubernetes了。Apache Zookeeper作為目前最流行的分布式協(xié)調(diào)組件,在我們的微服務(wù)架構(gòu)中負(fù)責(zé)扮演注冊中心的角色。
在Kubernetes中運(yùn)行Zookeeper集群是很有意義的,可以利用其原生的彈性擴(kuò)縮容、高可用特性。
先說下使用的k8s的版本是1.25.0,對于PodDisruptionBudget的apiVersion會有影響,某些更老的k8s版本,apiVersion是policy/v1bata,1.25.0的k8s對應(yīng)的apiVersion是policy/v1。
使用StatefulSet部署Zookeeper
官方提供了使用statefulSet的方式來部署 Zookeeper 運(yùn)行 Zookeeper,它會創(chuàng)建一個headless service,一個cluster service,一個podDisruptionBudget,一個statefulSet。
apiVersion: v1
kind: PersistentVolume
metadata:
name: zk-pv
spec:
capacity:
? storage: 512Mi
accessModes:
? - ReadWriteOnce
hostPath:
? path: /data
---
apiVersion: v1
kind: Service
metadata:
name: zk-hs
labels:
? app: zk
spec:
ports:
- port: 2888
? name: server
- port: 3888
? name: leader-election
clusterIP: None
selector:
? app: zk
---
apiVersion: v1
kind: Service
metadata:
name: zk-cs
labels:
? app: zk
spec:
ports:
- port: 2181
? name: client
selector:
? app: zk
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: zk-pdb
spec:
selector:
? matchLabels:
? ? app: zk
maxUnavailable: 1
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: zk
spec:
selector:
? matchLabels:
? ? app: zk
serviceName: zk-hs
replicas: 3
updateStrategy:
? type: RollingUpdate
podManagementPolicy: OrderedReady
template:
? metadata:
? ? labels:
? ? ? app: zk
? spec:
? ? affinity:
? ? ? podAntiAffinity:
? ? ? ? requiredDuringSchedulingIgnoredDuringExecution:
? ? ? ? ? - labelSelector:
? ? ? ? ? ? ? matchExpressions:
? ? ? ? ? ? ? ? - key: "app"
? ? ? ? ? ? ? ? ? operator: In
? ? ? ? ? ? ? ? ? values:
? ? ? ? ? ? ? ? ? - zk
? ? ? ? ? ? topologyKey: "kubernetes.io/hostname"
? ? containers:
? ? - name: kubernetes-zookeeper
? ? ? imagePullPolicy: IfNotPresent
? ? ? image: "harbor.martin.cc/google_containers/kubernetes-zookeeper:1.0-3.4.10"
? ? ? resources:
? ? ? ? requests:
? ? ? ? ? memory: "0.5Gi"
? ? ? ? ? cpu: "0.5"
? ? ? ports:
? ? ? - containerPort: 2181
? ? ? ? name: client
? ? ? - containerPort: 2888
? ? ? ? name: server
? ? ? - containerPort: 3888
? ? ? ? name: leader-election
? ? ? command:
? ? ? - sh
? ? ? - -c
? ? ? - "start-zookeeper \
? ? ? ? --servers=3 \
? ? ? ? --data_dir=/var/lib/zookeeper/data \
? ? ? ? --data_log_dir=/var/lib/zookeeper/data/log \
? ? ? ? --conf_dir=/opt/zookeeper/conf \
? ? ? ? --client_port=2181 \
? ? ? ? --election_port=3888 \
? ? ? ? --server_port=2888 \
? ? ? ? --tick_time=2000 \
? ? ? ? --init_limit=10 \
? ? ? ? --sync_limit=5 \
? ? ? ? --heap=512M \
? ? ? ? --max_client_cnxns=60 \
? ? ? ? --snap_retain_count=3 \
? ? ? ? --purge_interval=12 \
? ? ? ? --max_session_timeout=40000 \
? ? ? ? --min_session_timeout=4000 \
? ? ? ? --log_level=INFO"
? ? ? readinessProbe:
? ? ? ? exec:
? ? ? ? ? command:
? ? ? ? ? - sh
? ? ? ? ? - -c
? ? ? ? ? - "zookeeper-ready 2181"
? ? ? ? initialDelaySeconds: 10
? ? ? ? timeoutSeconds: 5
? ? ? livenessProbe:
? ? ? ? exec:
? ? ? ? ? command:
? ? ? ? ? - sh
? ? ? ? ? - -c
? ? ? ? ? - "zookeeper-ready 2181"
? ? ? ? initialDelaySeconds: 10
? ? ? ? timeoutSeconds: 5
? ? ? volumeMounts:
? ? ? - name: datadir
? ? ? ? mountPath: /var/lib/zookeeper
? ? securityContext:
? ? ? runAsUser: 1000
? ? ? fsGroup: 1000
volumeClaimTemplates:
- metadata:
? ? name: datadir
? spec:
? ? accessModes: [ "ReadWriteOnce" ]
? ? resources:
? ? ? requests:
? ? ? ? storage: 512Mi
使用 kubectl apply應(yīng)用這個配置文件,等待一會之后,發(fā)現(xiàn)pod和service都已創(chuàng)建成功。
kubectl get pod 查看到 zk-0 pod一直pending.
kubectl describe pod zk-0 看到事件原因是:
0/4 nodes are available: 4 pod has unbound immediate PersistentVolumeClaims. preemption: 0/4 nodes are available: 4 Preemption is not helpful for scheduling.
再使用:
kubectl logs -n kube-system kube-controller-manager-k8s-master01.example.local
查看controller-manager的pod日志:
I0513 08:13:08.710572 ? ? ? 1 event.go:294] "Event occurred" object="default/datadir-zk-0" fieldPath="" kind="PersistentVolumeClaim" apiVersion="v1" type="Normal" reason="FailedBinding" message="no persistent volumes available for this claim and no storage class is set"
這么看,原來PV和 storage class 都沒搞。這個網(wǎng)上的參考還是需要自己補(bǔ)充一下的,PV的API定義已經(jīng)加到上面的資源清單了。
PV弄了個HostPath的。但是也不知道存在哪個節(jié)點(diǎn)上。
然后再執(zhí)行kubectl apply -f zookeeper.yml創(chuàng)建,POD zk-0未啟動成功,出來錯誤CrashLoopBackOff。通過kubectl logs zk-0查看POD日志:
#This file was autogenerated DO NOT EDIT clientPort=2181 dataDir=/var/lib/zookeeper/data dataLogDir=/var/lib/zookeeper/data/log tickTime=2000 initLimit=10 syncLimit=5 maxClientCnxns=60 minSessionTimeout=4000 maxSessionTimeout=40000 autopurge.snapRetainCount=3 autopurge.purgeInteval=12 server.1=zk-0.zk-hs.default.svc.cluster.local:2888:3888 server.2=zk-1.zk-hs.default.svc.cluster.local:2888:3888 server.3=zk-2.zk-hs.default.svc.cluster.local:2888:3888 Creating ZooKeeper log4j configuration mkdir: cannot create directory '/var/lib/zookeeper/data': Permission denied chown: cannot access '/var/lib/zookeeper/data': No such file or directory mkdir: cannot create directory '/var/lib/zookeeper/data': Permission denied chown: invalid group: 'zookeeper:USER' /usr/bin/start-zookeeper: line 176: /var/lib/zookeeper/data/myid: No such file or directory
有個疑問,這個日志是一直存著嗎,還是POD沒啟動成功,我用kubectl delete -f zookeeper刪除掉POD,再看下,還有沒有這個日志??隙]了:
kubectl logs zk-0
Error from server (NotFound): pods "zk-0" not found
原來是POD及容器對于卷的目錄主機(jī)目錄沒有寫與創(chuàng)建子目錄的權(quán)限。把對應(yīng)的目錄POD部署節(jié)點(diǎn)的目錄 /data/,權(quán)限修改成全部可以讀寫創(chuàng)建:
chmod 777 /data/
重啟后,還是有問題:
發(fā)現(xiàn)pod zk-0啟動成功了,但是到了zk-1啟動失敗,原來是每個pod要創(chuàng)建一個hostPath的PV。接下來創(chuàng)建兩個zk-pv1,zk-pv2,在node2和node3上創(chuàng)建好對應(yīng)的host文件夾/data/,并設(shè)置權(quán)限777。然后重啟,三個pod都啟動成功了。
恭喜自己,部署看起來是成功了,那么就真正測試一下部署好的zk集群吧。
要測試在 Kubernetes 上部署的 ZooKeeper 集群,可以執(zhí)行以下步驟:
-
獲取 ZooKeeper 的客戶端工具,例如 ZooKeeper 命令行客戶端
zkCli.sh
??梢栽?ZooKeeper 的官方網(wǎng)站下載安裝包,并解壓獲取相關(guān)工具。 -
進(jìn)入 Kubernetes 集群中的任意一個 Pod,可以使用
kubectl exec
命令進(jìn)入 Pod 的容器內(nèi)部。kubectl exec -it <pod-name> -- /bin/bash
-
在容器內(nèi)部,使用 ZooKeeper 客戶端工具連接到 ZooKeeper 集群。根據(jù)您的部署方式和服務(wù)發(fā)現(xiàn)配置,可以使用 Service 名稱或 Pod IP 連接到 ZooKeeper。
./zkCli.sh -server <zk-service-name>:<zk-service-port>
或者
./zkCli.sh -server <zk-pod-ip>:<zk-service-port>
這里的
<zk-service-name>
是您 ZooKeeper 服務(wù)的名稱,<zk-service-port>
是服務(wù)的端口號。如果您使用的是 StatefulSet 部署方式,可以使用zk-{index}.<statefulset-name>
的方式連接到每個 ZooKeeper Pod。 -
連接成功后,您可以執(zhí)行各種 ZooKeeper 的命令和操作,例如創(chuàng)建節(jié)點(diǎn)、設(shè)置數(shù)據(jù)、監(jiān)聽事件等??梢酝ㄟ^命令
help
或?
獲取更多可用的命令列表和用法。[zk: <zk-service-name>:<zk-service-port>] help [zk: <zk-service-name>:<zk-service-port>] ?
例如,可以使用以下命令創(chuàng)建一個節(jié)點(diǎn)并設(shè)置數(shù)據(jù):
[zk: <zk-service-name>:<zk-service-port>] create /test mydata
然后使用以下命令獲取節(jié)點(diǎn)的數(shù)據(jù):
[zk: <zk-service-name>:<zk-service-port>] get /test
通過執(zhí)行各種命令和操作,可以驗(yàn)證 ZooKeeper 集群的功能和可用性。
請注意,上述命令中的 <zk-service-name>
和 <zk-service-port>
需要替換為實(shí)際的 ZooKeeper 服務(wù)名稱和端口。具體的連接信息取決于您的部署方式和配置。
都是驗(yàn)證通過的,說明安裝成功了,Oh Yeah!
附:安裝的容器鏡像描述信息:
The ZooKeeper package is installed into the /opt/zookeeper directory, all configuration is sym linked into the /usr/etc/zookeeper/, and all executables are sym linked into /usr/bin. The ZooKeeper data directories are contained in /var/lib/zookeeper. This is identical to the RPM distribution that users should be familiar with.文章來源:http://www.zghlxwxcb.cn/news/detail-478455.html
所以 /var/lib/zookeeper這個文件夾是放數(shù)據(jù)的,所以我們就明白為什么要把這個文件夾放到PV了。文章來源地址http://www.zghlxwxcb.cn/news/detail-478455.html
到了這里,關(guān)于基于 Kubernetes 部署 Zookeeper(StatefulSet方式)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!