静海县建设局网站,去国外怎么导航地图,中国上市公司100强排行榜,lamp wordpress 404前言
知识点
定级#xff1a;入门级如何利用 AI 助手辅助运维工作单节点 Zookeeper 安装部署集群模式 Zookeeper 安装部署开源应用选型思想
实战服务器配置(架构 1:1 复刻小规模生产环境#xff0c;配置略有不同)
主机名IPCPU内存系统盘数据盘用途ks-master-0192.168.9.9…前言
知识点
定级入门级如何利用 AI 助手辅助运维工作单节点 Zookeeper 安装部署集群模式 Zookeeper 安装部署开源应用选型思想
实战服务器配置(架构 1:1 复刻小规模生产环境配置略有不同)
主机名IPCPU内存系统盘数据盘用途ks-master-0192.168.9.914850100KubeSphere/k8s-masterks-master-1192.168.9.924850100KubeSphere/k8s-masterks-master-2192.168.9.934850100KubeSphere/k8s-masterks-worker-0192.168.9.9541650100k8s-worker/CIks-worker-1192.168.9.9641650100k8s-workerks-worker-2192.168.9.9741650100k8s-workerstorage-0192.168.9.812450100ElasticSearch/GlusterFS/Ceph/Longhorn/NFS/storage-1192.168.9.822450100ElasticSearch/GlusterFS/Ceph/Longhornstorage-2192.168.9.832450100ElasticSearch/GlusterFS/Ceph/Longhornregistry192.168.9.802450200Sonatype Nexus 3合计1032885001100
实战环境涉及软件版本信息
操作系统openEuler 22.03 LTS SP2 x86_64KubeSphere3.3.2Kubernetesv1.24.12Containerd1.6.4GlusterFS10.0-8KubeKey: v3.0.8Zookeeper3.8.2
简介
今天我们的实战内容采用场景模拟的形式模拟真实运维工作中必然会遇到的一个场景。
作为一个初入职场刚接触云原生运维的运维小白Boss 今天给我安排了一个高难度的任务对你没看错就是高难度的。
高难度 2 M 1 D 听过、没见过、没干过、时间短。
Boss 提出的任务要求整理如下都是我根据 Boss 的原话自己理解、猜测、搜索整理的实际上 Boos 根本没说几个字
在 K8s 集群上部署一个单节点模式的 Zookeeper在 K8s 集群上部署集群模式的 Zookeeper使用场景研发、测试后期很有可能直接转生产任务交付期明天领导认为很简单核心要求能用就行自己理解的
既然不能拒绝时间紧任务重那就干吧冲冲冲
2. 任务实现思路分析
工欲善其事必先利其器。既然是 2 M 1 D 级别的任务先搬出 AI 时代运维三板斧中的前两板看看是否能解决问题。 由于只用了两板斧就搞定了所以就没用到第三板。 第一板斧——AI 助手
提示词 我要在 K8s 上部署 zookeerper。分别给我一个单节点和集群模式的部署方案注意需要使用存储类 glusterfs、需要有 SVC、需要有 zoo.cfg 的 ConfigMap 重点说明 本人学艺不精AI 助手玩的还不熟提示词写的不好所以最终效果也不是太好。 输入上面的提示词以后AI 助手-3.5 吧啦吧啦返回了一堆文字给我我只取了精华作为展示。
单节点部署配置文件zookeeper-single.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: zookeeper-data
spec:accessModes:- ReadWriteOncestorageClassName: glusterfsresources:requests:storage: 10Gi---
apiVersion: v1
kind: Service
metadata:name: zookeeper
spec:selector:app: zookeeperports:- protocol: TCPport: 2181targetPort: 2181---
apiVersion: v1
kind: ConfigMap
metadata:name: zookeeper-config
data:zoo.cfg: |tickTime2000dataDir/dataclientPort2181---
apiVersion: apps/v1
kind: Deployment
metadata:name: zookeeper
spec:replicas: 1selector:matchLabels:app: zookeepertemplate:metadata:labels:app: zookeeperspec:containers:- name: zookeeperimage: zookeeper:3.7.0resources:requests:cpu: 100mmemory: 1Giports:- containerPort: 2181volumeMounts:- name: zookeeper-datamountPath: /dataenv:- name: ZOOKEEPER_CONFIG_FILEvalue: /opt/zookeeper-3.7.0/conf/zoo.cfg- name: ZOO_SERVERSvalue: server.1zookeeper-0.zookeeper.default.svc.cluster.local:2888:3888;2181volumes:- name: zookeeper-datapersistentVolumeClaim:claimName: zookeeper-data- name: zookeeper-configconfigMap:name: zookeeper-config
集群模式部署配置文件zookeeper-cluster.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: zookeeper-data
spec:accessModes:- ReadWriteOncestorageClassName: glusterfsresources:requests:storage: 10Gi---
apiVersion: v1
kind: Service
metadata:name: zookeeper
spec:selector:app: zookeeperports:- protocol: TCPport: 2181targetPort: 2181---
apiVersion: v1
kind: ConfigMap
metadata:name: zookeeper-config
data:zoo.cfg: |tickTime2000dataDir/dataclientPort2181initLimit5syncLimit2server.1zookeeper-0.zookeeper.default.svc.cluster.local:2888:3888server.2zookeeper-1.zookeeper.default.svc.cluster.local:2888:3888server.3zookeeper-2.zookeeper.default.svc.cluster.local:2888:3888---
apiVersion: apps/v1
kind: StatefulSet
metadata:name: zookeeper
spec:serviceName: zookeeperreplicas: 3selector:matchLabels:app: zookeepertemplate:metadata:labels:app: zookeeperspec:containers:- name: zookeeperimage: zookeeper:3.7.0resources:requests:cpu: 100mmemory: 1Giports:- containerPort: 2181volumeMounts:- name: zookeeper-datamountPath: /dataenv:- name: ZOOKEEPER_CONFIG_FILEvalue: /opt/zookeeper-3.7.0/conf/zoo.cfgvolumes:- name: zookeeper-datapersistentVolumeClaim:claimName: zookeeper-data- name: zookeeper-configconfigMap:name: zookeeper-config
分析完内容我发现我好像懂了点但是又没有完全懂返回的结果中单节点和集群模式的配置文件看着差不太多分析一下结果顺便捋一下思路
kind 类型不同 单节点是 Deployment 集群模式是 StatefulSet这个目前看起来没毛病思路是对的Deployment 副本数为 1StatefulSet 副本数为 3集群模式没有使用 volumeClaimTemplates集群模式 zoo.cfg 配置文件中多了几个 server 的配置项但是好像没有实现 myid 的处理 必须有一定的 K8s 和 Zookeeper 相关知识积累才能分析出 AI 助手 给出的结果是否符合需求否则根本看不懂。 第二板斧——搜索引擎
搜索引擎在AI 助手出来以前在运维辅助中排名第一现在暂居第二了估计也没机会重回巅峰了谨代表个人排名意见。
看完了 AI 助手 的输出结果觉得整体结构内容没问题但是感觉细节上还是差那么点意思尤其是集群模式的部署。我们会在本文第三小节验证。
同时我还发现了一点 image: zookeeper:3.7.0既然引用的 Image 是 DockerHub 官方的那么 DockerHub 上一定有对应的 Image 及容器化部署的使用方法。
这也就带来一个新的灵感和一种新的学习方法同时也是最简单直接的 Docker 部署转化为 Kubernetes 部署的方法直接去看 Docker 的部署命令、启动命令、相关参数然后直接搬到 K8s 上就可以。
直接转到 DokcerHub 官网我们直接用关键词 zookeeper 搜索一下。
搜索结果截图 简单的思考分析一下搜索结果
排名最高的两个 zookeeper 镜像下载量都超过 100M, 分别是 Docker 官方和 Bitnami 出品的。 上周下载量最多的是 Bitnami 出品的 zookeeper下载量高达 1,140,215比 DockerHub 出品的 zookeeper 下载量 681,115多了一倍还多。 小提示Bitnami 十几年前我就开始用它们出品的一键部署安装包当时就是很牛的一键部署中间件解决方案服务商现在应该是更全面、更牛了。 为什么要做上面的分析
当我们做开源技术选型的时候主要的决定因素之一就是使用者数量使用者太少说明产品还不成熟代表着出了问题你都没地方寻求帮助。我的技术选型几个原则首选官方(Apache 官方没有只能选 DockerHub 官方)、用户量大(100M)、维护更新频繁(7 days ago)。除了 DockerHub 出品的 zookeeper 镜像之外Bitnami 出品的镜像也是一个很好的选择群众的眼睛是雪亮的如果不好用也不可能这么多人推荐、下载。AI 助手 给出的示例用的是 DockerHub 官方的镜像。
上面说了那么多好像没有说到第二板斧的重点搜索引擎AI 助手 给出的结果中单节点模式看着没什么问题但是集群模式总感觉少点啥重点的 myid 的处理方式我就没看到。因此我又用关键词 StatefulSet 部署 Zookeeper 在搜索引擎中搜索了一番。
搜索结果中有两个方向的思路比较有参考价值
基于 K8s 官方文档给出的 Zookeeper 部署方案。
K8s 官网的一个教程案例 Running ZooKeeper, A Distributed System Coordinator这个例子看着比较复杂而且引入了几个新的技术。
基于 Bitnami 制作的镜像提供的 Zookeeper 集群部署方案
梳理清楚已经获取的信息为了快速完成领导交付的任务今天的验证测试方案顺序如下
AI 助手 提供的单节点部署配置AI 助手 提供的集群模式部署配置Bitnami 提供的集群模式部署方案K8s 官网 Zookeeper 部署案例
因为单节点部署比较简单。所以测试问题重点就在于 AI 助手和 Bitnami 提供的集群模式部署配置是否可行如果方案可行就没官网案例什么事了如果不行再去实验 K8s 官网 Zookeeper 部署案例但是说实话我暂时还很不想碰因为这个案例里有个技术点我压根儿就没听过真要搞的话又会引入新的问题。
Zookeeper 单节点部署
我觉得 AI 助手 返回的单节点的部署方案和配置文件看着还可以没啥问题。但是也不要直接复制、粘贴拿来即用。一定要多参考 DockerHub 官网的 Zookeeper 相关示例二者相结合写出来的才是更靠谱的资源清单。
思路梳理
在 K8s 集群上部一套单节点的 Zookeeper 需要的资源清单如下
PersistentVolumeClaim ConfigMapzoo.cfg Deployment Cluster Service External Service可选
知道了需要完成的任务目标接下来结合 AI 助手给出的配置和官方配置参数生成一套资源配置清单。
注意 实践证明AI 助手 给出的也只是一个大概细节还是有很多不足的地方下面示例中的所有资源配置清单都是参考官方配置参数和实际使用需求整理的。
简单说一下修改了哪些内容。
Zookeeper 版本选择使用了落后官方最新的稳定版 3.9.0 一个版本的 3.8.2 替换 AI 助手给出的配置方案中的 3.7.0增加了 dataLog 的配置完善了资源限制的配置完善了 zoo.cfg 的配置
资源配置清单
如无特殊说明所有涉及 K8s 的操作都在 Master-0 节点上执行 , 配置文件根目录为 /srv/opsman/k8s-yaml。
创建资源清单文件夹
cd /srv/opsman/k8s-yaml
mkdir -p zookeeper/single
cd zookeeper/single
vi zookeeper-pvc.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: zookeeper-data
spec:accessModes:- ReadWriteOncestorageClassName: glusterfsresources:requests:storage: 1Gi---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: zookeeper-datalog
spec:accessModes:- ReadWriteOncestorageClassName: glusterfsresources:requests:storage: 2Gi 说明 后端存储类使用的 GlusterFS。 vi zookeeper-cm.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:name: zookeeper-config
data:zoo-cfg: |tickTime2000dataDir/datadataLogDir/datalogclientPort2181initLimit10syncLimit5
vi zookeeper-deploy.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:name: zookeeper
spec:replicas: 1selector:matchLabels:app: zookeepertemplate:metadata:labels:app: zookeeperspec:containers:- name: zookeeperimage: zookeeper:3.8.2resources:requests:cpu: 50mmemory: 500Milimits:cpu: 2memory: 4000Miports:- name: zookeeper-2181containerPort: 2181protocol: TCPvolumeMounts:- name: configmountPath: /conf- name: datamountPath: /data- name: datalogmountPath: /datalogvolumes:- name: datapersistentVolumeClaim:claimName: zookeeper-data- name: datalogpersistentVolumeClaim:claimName: zookeeper-datalog- name: configconfigMap:name: zookeeper-configitems:- key: zoo-cfgpath: zoo.cfg---
apiVersion: v1
kind: Service
metadata:name: zookeeper
spec:ports:- name: zookeeper-2181protocol: TCPport: 2181targetPort: 2181selector:app: zookeepertype: ClusterIP Deployment 和 Cluster Service 放在了一个配置文件。 vi zookeeper-external-svc.yaml
---
apiVersion: v1
kind: Service
metadata:name: zookeeper-external-svclabels:app: zookeeper-external-svc
spec:ports:- name: tcp-zookeeper-externalprotocol: TCPport: 2181targetPort: 2181nodePort: 32181selector:app: zookeepertype: NodePort 注意可选配置项如果不需要被 K8s 集群之外的服务访问则不需要配置。 部署资源
部署 PersistentVolumeClaim
kubectl apply -f zookeeper-pvc.yaml
部署 ConfigMap
kubectl apply -f zookeeper-cm.yaml
部署 Deployment
kubectl apply -f zookeeper-deploy.yaml
部署 External Service
kubectl apply -f zookeeper-svc.yaml
K8s 部署资源验证
验证 PersistentVolumeClaim
[rootks-master-0 single]# kubectl get pvc -o wide
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE
zookeeper-data Bound pvc-371c9406-1757-451a-9c89-bed47ac71dd4 1Gi RWO glusterfs 12s Filesystem
zookeeper-datalog Bound pvc-457a134c-0db2-4efc-902c-555daba2057e 2Gi RWO glusterfs 11s Filesystem
验证 Deployment
[rootks-master-0 single]# kubectl get deploy -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
zookeeper 1/1 1 1 5m1s zookeeper zookeeper:3.8.2 appzookeeper
验证 Pod
[rootks-master-0 single]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
zookeeper-bcfc6cc5c-bh56m 1/1 Running 0 54s 10.233.120.8 ks-worker-1 none none
验证 Service
[rootks-master-0 single]# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
zookeeper ClusterIP 10.233.58.30 none 2181/TCP 59s appzookeeper
zookeeper-external-svc NodePort 10.233.40.37 none 2181:32181/TCP 59s appzookeeper
Zookeeper 服务可用性验证
在 K8s 集群内部验证。
在 K8s 上创建一个 Zookeeper Client Pod 验证
kubectl run zookeeper-client --imagezookeeper:3.8.2
验证 Zookeeper Server 连通性
# 进入 Zookeeper Client 容器内部
kubectl exec -it zookeeper-client -- bash# 连接 Zookeeper Server
bin/zkCli.sh -server 10.233.58.30:2181# 成功结果如下
[rootks-master-0 single]# kubectl exec -it zookeeper-client -- bash
rootzookeeper-client:/apache-zookeeper-3.8.2-bin# bin/zkCli.sh -server 10.233.58.30:2181
Connecting to 10.233.58.30:2181
2023-08-07 07:44:16,110 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:zookeeper.version3.8.2-139d619b58292d7734b4fc83a0f44be4e7b0c986, built on 2023-07-05 19:24 UTC
2023-08-07 07:44:16,117 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:host.namezookeeper-client
2023-08-07 07:44:16,117 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:java.version11.0.20
2023-08-07 07:44:16,117 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:java.vendorEclipse Adoptium
2023-08-07 07:44:16,117 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:java.home/opt/java/openjdk
2023-08-07 07:44:16,117 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:java.class.path/apache-zookeeper-3.8.2-bin/bin/......(此处有省略)
2023-08-07 07:44:16,118 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:java.library.path/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib
2023-08-07 07:44:16,118 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:java.io.tmpdir/tmp
2023-08-07 07:44:16,118 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:java.compilerNA
2023-08-07 07:44:16,118 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:os.nameLinux
2023-08-07 07:44:16,118 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:os.archamd64
2023-08-07 07:44:16,118 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:os.version5.10.0-153.12.0.92.oe2203sp2.x86_64
2023-08-07 07:44:16,118 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:user.nameroot
2023-08-07 07:44:16,119 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:user.home/root
2023-08-07 07:44:16,119 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:user.dir/apache-zookeeper-3.8.2-bin
2023-08-07 07:44:16,119 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:os.memory.free42MB
2023-08-07 07:44:16,119 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:os.memory.max256MB
2023-08-07 07:44:16,120 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:os.memory.total48MB
2023-08-07 07:44:16,123 [myid:] - INFO [main:o.a.z.ZooKeeper637] - Initiating client connection, connectString10.233.58.30:2181 sessionTimeout30000 watcherorg.apache.zookeeper.ZooKeeperMain$MyWatcher18bf3d14
2023-08-07 07:44:16,128 [myid:] - INFO [main:o.a.z.c.X509Util78] - Setting -D jdk.tls.rejectClientInitiatedRenegotiationtrue to disable client-initiated TLS renegotiation
2023-08-07 07:44:16,134 [myid:] - INFO [main:o.a.z.ClientCnxnSocket239] - jute.maxbuffer value is 1048575 Bytes
2023-08-07 07:44:16,143 [myid:] - INFO [main:o.a.z.ClientCnxn1741] - zookeeper.request.timeout value is 0. feature enabledfalse
Welcome to ZooKeeper!
2023-08-07 07:44:16,171 [myid:10.233.58.30:2181] - INFO [main-SendThread(10.233.58.30:2181):o.a.z.ClientCnxn$SendThread1177] - Opening socket connection to server zookeeper.default.svc.cluster.local/10.233.58.30:2181.
2023-08-07 07:44:16,173 [myid:10.233.58.30:2181] - INFO [main-SendThread(10.233.58.30:2181):o.a.z.ClientCnxn$SendThread1179] - SASL config status: Will not attempt to authenticate using SASL (unknown error)
2023-08-07 07:44:16,185 [myid:10.233.58.30:2181] - INFO [main-SendThread(10.233.58.30:2181):o.a.z.ClientCnxn$SendThread1011] - Socket connection established, initiating session, client: /10.233.118.8:55022, server: zookeeper.default.svc.cluster.local/10.233.58.30:2181
JLine support is enabled
2023-08-07 07:44:16,251 [myid:10.233.58.30:2181] - INFO [main-SendThread(10.233.58.30:2181):o.a.z.ClientCnxn$SendThread1452] - Session establishment complete on server zookeeper.default.svc.cluster.local/10.233.58.30:2181, session id 0x1000178f5af0000, negotiated timeout 30000WATCHER::WatchedEvent state:SyncConnected type:None path:null
[zk: 10.233.58.30:2181(CONNECTED) 0]
创建测试数据验证服务可用性
# 创建测试数据
[zk: 10.233.58.30:2181(CONNECTED) 0] create /test test-data1
Created /test# 读取测试数据
[zk: 10.233.58.30:2181(CONNECTED) 1] get /test
test-data1
在 K8s 集群外部验证。
本文直接使用 K8s Master-0 节点安装 Zookeeper 客户端进行测试验证。
安装 openjdk仅限于测试验证。
yum install java-11-openjdk
安装 Zookeeper 客户端到 Zookeeper 官网找相应版本的软件包。本文选择 3.8.2 作为测试版本。
# 下载并解压 Zookeeper在国内源下载
wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.8.2/apache-zookeeper-3.8.2-bin.tar.gztar xvf apache-zookeeper-3.8.2-bin.tar.gz
验证 Zookeeper Server 连通性
cd apache-zookeeper-3.8.2-bin/bin/
./zkCli.sh -server 192.168.9.91:32181# 成功结果如下结果有省略
[rootks-master-0 bin]# ./zkCli.sh -server 192.168.9.91:32181
/usr/bin/java
Connecting to 192.168.9.91:32181
2023-08-07 15:46:53,156 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:zookeeper.version3.8.2-139d619b58292d7734b4fc83a0f44be4e7b0c986, built on 2023-07-05 19:24 UTC
......WATCHER::WatchedEvent state:SyncConnected type:None path:null
[zk: 192.168.9.91:32181(CONNECTED) 0]
创建测试数据验证服务可用性
# 创建测试数据
[zk: 192.168.9.91:32181(CONNECTED) 0] create /test2 test2-data1
Created /test2# 读取测试数据
[zk: 192.168.9.91:32181(CONNECTED) 1] get /test2
test2-data1
至此Boss 交代的任务完成了一半已经实现了单节点 Zookeeper 的部署并在 K8s 集群内部和外部分别做了连通性、可用性测试。
但是时间已超期已经来到了第二天所以说啊对于一个未知的任务实现起来根本没有 Boss 想象的那么简单。
不过由于完成了单节点的任务先上交汇报给 Boss并说明一下实现思路、过程部署过程中遇到的问题及解决方案切记不要直接跟 Boss 说这个很难你预估的时间有问题那么说纯属找抽。
按上面的套路汇报完得到了 Boss 的理解和认可Boss 其实还是很好说话的只要你能以理说服他让我先把单节点的 Zookeeper 环境交给测试使用再去继续研究集群模式的部署方案。
这波操作不仅没有受到批评还给自己争取了时间完美
集群模式 Zookeeper 部署
单节点部署 Zookeeper 的任务完成以后接下来开始研究集群模式的 Zookeeper 部署AI 助手给出的默认示例根本就不靠谱我也懒得再调教他了。
为什么这么说
因为我利用 AI 助手给的方案利用 DockerHub 提供的 Zookeeper 去尝试在 K8s 集群上部署 Zookeeper 集群耗时 2 天主要是犯病了钻了牛角尖就想搞定它无奈能力又不够
接下来简单说一下我被折磨疯了的两天都做了哪些尝试、遇到了哪些问题、有哪些心得体会逼得我都差点祭出第三板斧了。
集群模式的关键解决 myid 和 servers 的配置servers 的配置这个没有问题很好解决可以在配置文件中直接写入或是用 ENV 的方式注入myid 是重点DockHub 镜像仓库中提供的 Zookeeper 镜像节点 myid 不能动态配置在实验中尝试了 initContainers 、SidecarContainer、ConfigMap 挂载启动脚本等方式都没有起到效果不是说 DockHub 镜像彻底不能用只是需要进行启动脚本改造甚至需要重新打 Image太麻烦了已经耗时 2 天了不得不暂时放弃上面几种尝试以及最后的成品资源配置清单的编写都是在 KubeSphere 的图形化管理控制台下测试验证的比命令行界面方便了太多心得 通往成功的路有千万条一条不通时可以尝试换条路不要死磕到底。我们的目的是为了解决问题能解决问题的办法就是好办法钻牛角尖的精神也要分情况
最终只能另寻出路好在之前的调研中已经找到了另外两种可能的解决方案。
使用 Bitnami 制作的镜像部署 Zookeeper 集群最终选择。Kubernetes 官方文档示例中介绍的方案该方案使用镜像 registry.k8s.io/kubernetes-zookeeper:1.0-3.4.10使用 PodDisruptionBudget 确保服务可用性。
说一下最终的选型理由
Pod Disruption Budget有点复杂不太适合我目前段位。
Pod Disruption Budget (Pod 干扰 预算) 简称 PDBKubernetes version 1.21 才可以使用 PodDisruptionBudget。PDB 的作用是将限制在同一时间因自愿干扰导致的多副本应用中发生宕机的 Pod 数量。
具体的知识点本文不细说了反正我目前也不打算用了唉主要是说不明白难免误人子弟有兴趣的可以参考官方文档的 PDB 介绍和 PDB 配置案例。
Bitnami 制作的镜像部署 Zookeeper 集群该方案网上的参考案例有很多而且该方案采用 Zookeeper 原生部署方案没有额外的 K8S 机制减少了复杂度。这个也是选择的重点。
接下来我就开始尝试使用 Bitnami 制作的 Zookeeper 镜像完成 Zookeeper 集群的部署。
思路梳理
在 K8s 集群上部一套 Zookeeper 集群需要的资源清单如下
StatefulSet Headless Service ConfigMapzoo.cfg没有使用所有的配置都使用 ENV 的形式 ConfigMapsetup.sh启动脚本计划使用实际没有使用最终采取了 ENV 和 Command 方式 External Service可选
注意由于本文配置方案没有考虑安全配置仅适用于开发、测试环境。不要把本文的示例直接拿到生产环境使用必须参考官方配置文档增加相应的 ENV 配置方可用于生产。
资源配置清单
如无特殊说明所有涉及 K8s 的操作都在 Master-0 节点上执行 , 配置文件根目录为 /srv/opsman/k8s-yaml。
创建资源清单文件夹
cd /srv/opsman/k8s-yaml
mkdir -p zookeeper/cluster
cd zookeeper/cluster
vi zookeeper-svc.yaml
---
# Headless Service用于 Zookeeper 集群之间相互通讯
apiVersion: v1
kind: Service
metadata:name: zk-hslabels:app: zookeeper
spec:ports:- name: tcp-clientprotocol: TCPport: 2181targetPort: 2181- name: tcp-followerport: 2888targetPort: 2888- name: tcp-electionport: 3888targetPort: 3888selector:app: zookeeperclusterIP: Nonetype: ClusterIP---
# Client Service用于 K8S 集群内的应用访问 Zookeeper
apiVersion: v1
kind: Service
metadata:name: zk-cslabels:app: zookeeper
spec:ports:- name: tcp-clientprotocol: TCPport: 2181targetPort: 2181selector:app: zookeepertype: ClusterIP
vi zookeeper-sts.yaml
---
apiVersion: apps/v1
kind: StatefulSet
metadata:name: zookeeperlabels:app: zookeeper
spec:replicas: 3selector:matchLabels:app: zookeeperserviceName: zk-hstemplate:metadata:name: zookeeperlabels:app: zookeeperspec:affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- zookeepertopologyKey: kubernetes.io/hostnamecontainers:- name: zookeeperimage: bitnami/zookeeper:3.8.2command:- bash- -ec- |HOSTNAME$(hostname -s)if [[ $HOSTNAME ~ (.*)-([0-9])$ ]]; thenORD${BASH_REMATCH[2]}export ZOO_SERVER_ID$((ORD 1 ))elseecho Failed to get index from hostname $HOSTexit 1fiexec /entrypoint.sh /run.shresources:limits:cpu: 1memory: 2Girequests:cpu: 50mmemory: 500Mienv:- name: ZOO_ENABLE_AUTHvalue: no- name: ALLOW_ANONYMOUS_LOGINvalue: yes- name: ZOO_SERVERSvalue: zookeeper-0.zk-hs.default.svc.cluster.local:2888:3888zookeeper-1.zk-hs.default.svc.cluster.local:2888:3888zookeeper-2.zk-hs.ddefault.svc.cluster.local:2888:3888ports:- name: clientcontainerPort: 2181- name: followercontainerPort: 2888- name: electioncontainerPort: 3888livenessProbe:tcpSocket:port: clientfailureThreshold: 6initialDelaySeconds: 30periodSeconds: 10successThreshold: 1timeoutSeconds: 5readinessProbe:tcpSocket:port: clientfailureThreshold: 6initialDelaySeconds: 5periodSeconds: 10successThreshold: 1timeoutSeconds: 5volumeMounts:- name: datamountPath: /bitnami/zookeepervolumeClaimTemplates:- metadata:name: dataspec:accessModes: [ ReadWriteOnce ]storageClassName: glusterfsresources:requests:storage: 2Gi 说明 ENV 的配置我只用了最基本的重点就是 ZOO_SERVERS更多参数的用法请参考 Bitnami 官方文档Command 里直接写了启动命令也可以做成 ConfigMap 挂载为脚本default.svc.cluster.local注意 FQDN 只能这么写不要写成自定义的哪怕我的集群域名是 opsman.top这个是遗留问题来不及细看了回头再说 vi zookeeper-external-svc.yaml
---
# External Client Service用于 K8S 集群外部访问 Zookeeper
apiVersion: v1
kind: Service
metadata:name: zookeeper-external-svclabels:app: zookeeper-external-svc
spec:ports:- name: tcp-zookeeper-externalprotocol: TCPport: 2181targetPort: 2181nodePort: 32181selector:app: zookeepertype: NodePort 注意可选配置项如果不需要被 K8s 集群之外的服务访问则不需要配置。 部署资源
部署 Cluster 和 Headless Service
kubectl apply -f zookeeper-svc.yaml
部署 StatefulSet
kubectl apply -f zookeeper-sts.yaml
部署外部 Services
kubectl apply -f zookeeper-external-svc.yaml
K8s 部署资源验证
验证 PersistentVolumeClaim
[rootks-master-0 cluster]# kubectl get pvc -o wide
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE
data-zookeeper-0 Bound pvc-342c3869-17ca-40c7-9db0-755d5af0f85f 2Gi RWO glusterfs 2m7s Filesystem
data-zookeeper-1 Bound pvc-6744813f-0f5b-4138-8ffc-387f63044af3 2Gi RWO glusterfs 47s Filesystem
data-zookeeper-2 Bound pvc-731edc8d-189a-4601-aa64-a8d6754d93ec 2Gi RWO glusterfs 28s Filesystem
验证 StatefulSet
[rootks-master-0 cluster]# kubectl get sts -o wide
NAME READY AGE CONTAINERS IMAGES
zookeeper 3/3 2m3s zookeeper bitnami/zookeeper:3.8.2
验证 Pod
[rootks-master-0 cluster]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
zookeeper-0 1/1 Running 0 2m42s 10.233.118.45 ks-worker-2 none none
zookeeper-1 1/1 Running 0 83s 10.233.120.17 ks-worker-1 none none
zookeeper-2 1/1 Running 0 64s 10.233.115.99 ks-worker-0 none none
验证 Service
[rootks-master-0 cluster]# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
zk-cs ClusterIP 10.233.43.229 none 2181/TCP 3m58s appzookeeper
zk-hs ClusterIP None none 2181/TCP,2888/TCP,3888/TCP 3m58s appzookeeper
zookeeper-external-svc NodePort 10.233.45.5 none 2181:32181/TCP 10s appzookeeper
Zookeeper 集群状态验证
验证 StatefulSet 创建的 Pod 配置的主机名
[rootks-master-0 cluster]# for i in 0 1 2; do kubectl exec zookeeper-$i -- hostname; done
zookeeper-0
zookeeper-1
zookeeper-2
验证 StatefulSet 创建的 Pod 配置的完全限定域名Fully Qualified Domain NameFQDN
[rootks-master-0 cluster]# for i in 0 1 2; do kubectl exec zookeeper-$i -- hostname -f; done
zookeeper-0.zk-hs.default.svc.cluster.local
zookeeper-1.zk-hs.default.svc.cluster.local
zookeeper-2.zk-hs.default.svc.cluster.local
验证每个 Zookeeper 服务的 myid 文件内容
[rootks-master-0 cluster]# for i in 0 1 2; do echo myid zookeeper-$i;kubectl exec zookeeper-$i -- cat /bitnami/zookeeper/data/myid; done
myid zookeeper-0
1
myid zookeeper-1
2
myid zookeeper-2
3
验证 Zookeeper 生成的配置文件
[rootks-master-0 cluster]# kubectl exec -it zookeeper-0 -- cat /opt/bitnami/zookeeper/conf/zoo.cfg | grep -vE ^#|^$
tickTime2000
initLimit10
syncLimit5
dataDir/bitnami/zookeeper/data
clientPort2181
maxClientCnxns60
autopurge.snapRetainCount3
autopurge.purgeInterval0preAllocSize65536
snapCount100000
maxCnxns0
reconfigEnabledfalse
quorumListenOnAllIPsfalse
4lw.commands.whitelistsrvr, mntr
maxSessionTimeout40000
admin.serverPort8080
admin.enableServertrue
server.1zookeeper-0.zk-hs.default.svc.cluster.local:2888:3888;2181
server.2zookeeper-1.zk-hs.default.svc.cluster.local:2888:3888;2181
server.3zookeeper-2.zk-hs.default.svc.cluster.local:2888:3888;2181
验证集群状态
[rootks-master-0 cluster]# for i in 0 1 2; do echo -e # myid zookeeper-$i \n;kubectl exec zookeeper-$i -- /opt/bitnami/zookeeper/bin/zkServer.sh status;echo -e \n; done
# myid zookeeper-0/opt/bitnami/java/bin/java
ZooKeeper JMX enabled by default
Using config: /opt/bitnami/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: leader# myid zookeeper-1/opt/bitnami/java/bin/java
ZooKeeper JMX enabled by default
Using config: /opt/bitnami/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower# myid zookeeper-2/opt/bitnami/java/bin/java
ZooKeeper JMX enabled by default
Using config: /opt/bitnami/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: followerZookeeper 服务可用性验证
在 K8s 集群内部验证。
在 K8s 上创建一个 Zookeeper Client Pod 验证单节点验证时创建过不需要再创建了
kubectl run zookeeper-client --imagezookeeper:3.8.2
验证 Zookeeper Server 连通性
# 进入 Zookeeper Client 容器内部
kubectl exec -it zookeeper-client -- bash# 连接 Zookeeper Server 10.233.43.229 是 Cluster Service 的 IP
bin/zkCli.sh -server 10.233.43.229:2181# 成功结果如下(内容有省略)
[rootks-master-0 cluster]# kubectl exec -it zookeeper-client -- bash
rootzookeeper-client:/apache-zookeeper-3.8.2-bin# bin/zkCli.sh -server 10.233.43.229:2181
Connecting to 10.233.43.229:2181
2023-08-08 10:08:40,864 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:zookeeper.version3.8.2-139d619b58292d7734b4fc83a0f44be4e7b0c986, built on 2023-07-05 19:24 UTC
.....
2023-08-08 10:08:40,872 [myid:] - INFO [main:o.a.z.ZooKeeper637] - Initiating client connection, connectString10.233.43.229:2181 sessionTimeout30000 watcherorg.apache.zookeeper.ZooKeeperMain$MyWatcher18bf3d14
2023-08-08 10:08:40,886 [myid:] - INFO [main:o.a.z.c.X509Util78] - Setting -D jdk.tls.rejectClientInitiatedRenegotiationtrue to disable client-initiated TLS renegotiation
2023-08-08 10:08:40,892 [myid:] - INFO [main:o.a.z.ClientCnxnSocket239] - jute.maxbuffer value is 1048575 Bytes
2023-08-08 10:08:40,903 [myid:] - INFO [main:o.a.z.ClientCnxn1741] - zookeeper.request.timeout value is 0. feature enabledfalse
Welcome to ZooKeeper!
2023-08-08 10:08:40,920 [myid:10.233.43.229:2181] - INFO [main-SendThread(10.233.43.229:2181):o.a.z.ClientCnxn$SendThread1177] - Opening socket connection to server zk-cs.default.svc.cluster.local/10.233.43.229:2181.
2023-08-08 10:08:40,923 [myid:10.233.43.229:2181] - INFO [main-SendThread(10.233.43.229:2181):o.a.z.ClientCnxn$SendThread1179] - SASL config status: Will not attempt to authenticate using SASL (unknown error)
JLine support is enabled
2023-08-08 10:08:40,948 [myid:10.233.43.229:2181] - INFO [main-SendThread(10.233.43.229:2181):o.a.z.ClientCnxn$SendThread1011] - Socket connection established, initiating session, client: /10.233.118.8:38050, server: zk-cs.default.svc.cluster.local/10.233.43.229:2181
2023-08-08 10:08:41,064 [myid:10.233.43.229:2181] - INFO [main-SendThread(10.233.43.229:2181):o.a.z.ClientCnxn$SendThread1452] - Session establishment complete on server zk-cs.default.svc.cluster.local/10.233.43.229:2181, session id 0x10007253d840000, negotiated timeout 30000WATCHER::WatchedEvent state:SyncConnected type:None path:null
[zk: 10.233.43.229:2181(CONNECTED) 0]
创建测试数据验证服务可用性
# 创建测试数据
[zk: 10.233.43.229:2181(CONNECTED) 0] create /test test-data1
Created /test# 读取测试数据
[zk: 10.233.43.229:2181(CONNECTED) 1] get /test
test-data1
在 K8s 集群外部验证。
验证 Zookeeper Server 连通性
# 进入 Zookeeper 安装包的 bin 目录
cd apache-zookeeper-3.8.2-bin/bin/# 连接 Zookeeper Server 192.168.9.91 是 K8S Master-0 节点的 IP32181 是 External Service 定义的 NodePort 端口号
./zkCli.sh -server 192.168.9.91:32181# 成功结果如下结果有省略
[rootks-master-0 bin]# ./zkCli.sh -server 192.168.9.91:32181
/usr/bin/java
Connecting to 192.168.9.91:32181
2023-08-08 18:13:52,650 [myid:] - INFO [main:o.a.z.Environment98] - Client environment:zookeeper.version3.8.2-139d619b58292d7734b4fc83a0f44be4e7b0c986, built on 2023-07-05 19:24 UTC
......
2023-08-08 18:13:52,660 [myid:] - INFO [main:o.a.z.ZooKeeper637] - Initiating client connection, connectString192.168.9.91:32181 sessionTimeout30000 watcherorg.apache.zookeeper.ZooKeeperMain$MyWatcher5c072e3f
2023-08-08 18:13:52,666 [myid:] - INFO [main:o.a.z.c.X509Util78] - Setting -D jdk.tls.rejectClientInitiatedRenegotiationtrue to disable client-initiated TLS renegotiation
2023-08-08 18:13:52,671 [myid:] - INFO [main:o.a.z.ClientCnxnSocket239] - jute.maxbuffer value is 1048575 Bytes
2023-08-08 18:13:52,686 [myid:] - INFO [main:o.a.z.ClientCnxn1741] - zookeeper.request.timeout value is 0. feature enabledfalse
Welcome to ZooKeeper!
2023-08-08 18:13:52,708 [myid:192.168.9.91:32181] - INFO [main-SendThread(192.168.9.91:32181):o.a.z.ClientCnxn$SendThread1177] - Opening socket connection to server ks-master-0/192.168.9.91:32181.
2023-08-08 18:13:52,709 [myid:192.168.9.91:32181] - INFO [main-SendThread(192.168.9.91:32181):o.a.z.ClientCnxn$SendThread1179] - SASL config status: Will not attempt to authenticate using SASL (unknown error)
JLine support is enabled
2023-08-08 18:13:52,721 [myid:192.168.9.91:32181] - INFO [main-SendThread(192.168.9.91:32181):o.a.z.ClientCnxn$SendThread1011] - Socket connection established, initiating session, client: /192.168.9.91:45004, server: ks-master-0/192.168.9.91:32181
2023-08-08 18:13:52,776 [myid:192.168.9.91:32181] - INFO [main-SendThread(192.168.9.91:32181):o.a.z.ClientCnxn$SendThread1452] - Session establishment complete on server ks-master-0/192.168.9.91:32181, session id 0x10007253d840001, negotiated timeout 30000WATCHER::WatchedEvent state:SyncConnected type:None path:null
[zk: 192.168.9.91:32181(CONNECTED) 0]创建测试数据验证服务可用性
# 创建测试数据
[zk: 192.168.9.91:32181(CONNECTED) 0] create /test2 test2-data1
Created /test2# 读取测试数据读取了 2次 测试数据
[zk: 192.168.9.91:32181(CONNECTED) 1] get /test
test-data1
[zk: 192.168.9.91:32181(CONNECTED) 2] get /test2
test2-data1
至此实现了 Zookeeper 集群模式部署并在 K8S 集群内部和外部分别做了连通性、可用性测试。
在 KubeSphere 管理控制台验证
截几张图看一看 Zookeeper 相关资源在 KubeSphere 管理控制台中展示效果。
StatefulSet Pods Service 总结
本文详细介绍了 Zookeeper 单节点和集群模式在基于 KubeSphere 部署的 K8s 集群上的安装部署、测试验证的过程。具体涉及的内容总结如下。
如何利用 AI 助手 和 搜索引擎辅助完成运维工作。如何利用 DockerHub 官方提供的 Zookeeper 镜像在 K8s 集群上部署单节点 Zookeeper 服务并验证测试。如何利用 Bitnami 提供的 Zookeeper 镜像在 K8s 集群上部署 Zookeeper 集群服务并验证测试。介绍了一种使用 PodDisruptionBudget 部署 Zookeeper 集群的示例但是并未实际验证。
本文的配置方案可直接用于开发测试环境对于生产环境也有一定的借鉴意义。 本文由博客一文多发平台 OpenWrite 发布