一、部署方式
k8s 以statefulset方式部署zookeeper集群
二、statefulset简介
StatefulSet是Kubernetes提供的管理有状态应用的负载管理控制器API。在Pods管理的基础上,保证Pods的顺序和一致性。与Deployment一样,StatefulSet也是使用容器的Spec来创建Pod,与之不同StatefulSet创建的Pods在生命周期中会保持持久的标记(例如Pod Name)。
StatefulSet适用于具有以下特点的应用:
具有固定的网络标记(主机名)
具有持久化存储
需要按顺序部署和扩展
需要按顺序终止及删除
需要按顺序滚动更新
二、安装NFS
2.1 NFS安装与配置
2.2 创建 zookeeper pv挂载目录
mkdir /data/tools/zk/pv
2.3 将zookeeper pv挂载目录
2.3.1 方法一
直接挂载到NFS共享目录
2.3.2 方法二
将创建的zookeeper pv挂载目录再挂载到NFS共享目录。
注:若都zk pv path都挂载到共享目录,则zk pv path不能相同
举例:
zk3个节点的path 对应NFS共享目录
共享目录1:/data/tools/pv/zk01
共享目录2:/data/tools/pv/zk02
共享目录3:/data/tools/pv/zk03
zk有3个节点要挂3个pv
pv1 name:k8s-pv-zk1
pv1 path:/data/tools/pv/zk01
pv2 name: k8s-pv-zk2
pv2 path: /data/tools/pv/zk02
pv3 name: k8s-pv-zk3
pv3 path: /data/tools/pv/zk03
注:pv path的路径要与NFS共享目录保持一致。
三、创建PV与PVC
3.1 PV与PVC简介
PersistentVolume(PV)是集群中由管理员配置的一段网络存储。 它是集群中的资源,就像节点是集群资源一样。 PV是容量插件,如Volumes,但其生命周期独立于使用PV的任何单个pod。 此API对象捕获存储实现的详细信息,包括NFS,iSCSI或特定于云提供程序的存储系统。
PersistentVolumeClaim(PVC)是由用户进行存储的请求。 它类似于pod。 Pod消耗节点资源,PVC消耗PV资源。Pod可以请求特定级别的资源(CPU和内存)。声明可以请求特定的大小和访问模式(例如,可以一次读/写或多次只读)。
3.2 编写PV与PVC的yaml文件
zookeeper-pv.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
name: k8s-pv-zk1
namespace: tools
annotations:
volume.beta.kubernetes.io/storage-class: "anything"
labels:
type: local
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path:/data/tools/pv/zk01
persistentVolumeReclaimPolicy: Recycle
---
kind: PersistentVolume
apiVersion: v1
metadata:
name: k8s-pv-zk2
namespace: tools
annotations:
volume.beta.kubernetes.io/storage-class: "anything"
labels:
type: local
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path:/data/tools/pv/zk02
persistentVolumeReclaimPolicy: Recycle
---
kind: PersistentVolume
apiVersion: v1
metadata:
name: k8s-pv-zk3
namespace: tools
annotations:
volume.beta.kubernetes.io/storage-class: "anything"
labels:
type: local
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path:/data/tools/pv/zk03
persistentVolumeReclaimPolicy: Recycle
注:以上方式是同时创建PV与PVC的yaml文件
3.3 创建pv与pvc
kubectl apply -f zookeeper-pv.yaml
四、创建zookeeper集群
4.1 编写zookeepr.yaml文件
apiVersion: v1
kind: Service
metadata:
name: zk-hs
namespace: tools
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
namespace: tools
labels:
app: zk
spec:
type: NodePort
ports:
- port: 2181
nodePort: 21811
name: client
selector:
app: zk
---
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: zk-pdb
namespace: tools
spec:
selector:
matchLabels:
app: zk
maxUnavailable: 1
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: zk
namespace: tools
spec:
selector:
matchLabels:
app: zk
serviceName: zk-hs
replicas: 3 #设置节点数量
updateStrategy:
type: RollingUpdate
podManagementPolicy: Parallel
template:
metadata:
labels:
app: zk
spec:
containers:
- name: zk
imagePullPolicy: Always
image: "zookeeper 镜像pull地址"
resources:
requests:
memory: "500Mi"
cpu: "0.5"
ports:
- containerPort: 2181
name: client
- containerPort: 2888
name: server
- containerPort: 3888
name: leader-election
command:
- sh
- -c
- "/data/ecs/zookeeper-3.4.3/bin/start-zookeeper.sh \
--servers=3 \
--data_dir=/data/zookeeper/data \
--data_log_dir=/data/zookeeper/data_log_dir \
--log_dir=/data/zookeeper/log \
--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=80000 \
--min_session_timeout=8000 \
--log_level=DEBUG"
readinessProbe:
exec:
command:
- sh
- -c
- "/data/zookeeper-3.4.3/bin/zookeeper-ready.sh 2181"
initialDelaySeconds: 10
timeoutSeconds: 5
livenessProbe:
exec:
command:
- sh
- -c
- "/data/zookeeper-3.4.3/bin/zookeeper-ready.sh 2181"
initialDelaySeconds: 10
timeoutSeconds: 5
volumeMounts:
- name: datadir
mountPath: /data/zookeeper
#securityContext:
# runAsUser: 1000
# fsGroup: 1000
volumeClaimTemplates:
- metadata:
name: datadir
annotations:
volume.beta.kubernetes.io/storage-class: "anything"
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 500Mi
4.2 执行zookeeper.yaml文件
kubectl apply -f zookeeper.yaml
4.3 对外暴露访问端口
#创建zkService.yaml
touch zkService.yaml
#zkService.yaml内容
apiVersion: v1
kind: Service
metadata:
name: zk-cs
namespace: tools
labels:
app: zk
spec:
type: NodePort
ports:
- port: 2181
nodePort: 21811
name: client
selector:
app: zk
注:nodePort为对外暴露端口,端口号必须5位数字。建议与zookeeper.yaml合并。
#执行zookeeper.yaml文件
kubectl apply -f zookeeper.yaml
五、检查节点 zookeeper是否启动成功
5.1 检查zookeeper服务是否启动成功
docker ps -a|grep zk zk为name
zookeeper服务启动成功
5.2 检查集群是否启动成功
#进入容器
docker exec -it 3612d5a53590 /bin/bash
#cd到zookeeper部署目录
cd /data/zookeeper-3.4.3/bin
#检查服务状态
./zkServer.sh status
显示如下表示启动成功:
JMX enabled by default
Using config: /data/zookeeper-3.4.3/bin/../conf/zoo.cfg
Mode: leader/follower
注:3个节点会有一个leader,2个follower
显示如下表示启动失败:
JMX enabled by default
Using config: /data/zookeeper-3.4.3/bin/../conf/zoo.cfg
Error contacting service. It is probably not running.
六、遇到的坑
问题一:pvc创建成功后状态为 pending
原因:pv与pvc的storage不一样,pvc的storage只能小于或等pvc的storage
解决方法:
1、修改pvc的yam文件,将storage值修改为小于或等pv的storage值
2、删除pvc
3、重新创建pvc
问题二:启动zk提示没有权限
原因:StatefulSet指定了用户使用非root用户部署
解决方法:注释StatefulSet中以下内容
#securityContext:
# runAsUser: 1000
# fsGroup: 1000
问题三:zookeeper启动成功但集群没有启动成功
错误描述:
JMX enabled by default
Using config: /data/ecs/zookeeper-3.4.3/bin/../conf/zoo.cfg
Error contacting service. It is probably not running.
原因一:创建数据目录的myid的值与zoo.cfg的server.1=ip:2888:3888
注:创建数据目录,zoo.cfg配置文件里dataDir指定的那个目录下创建myid文件,并且指定id,改id为你zoo.cfg文件中server.1=ip:2888:3888中的1.只要在myid头部写入1即可.同理其它两台机器的id对应上。
例:
节点1 server.1=ip:2888:3888
节点2 server.2=ip:2888:3888
节点1的 myid内容为1
节点2的 myid内容为2
解决方法一:
1、进入zookeeper部署的容器,
2、删除/data/zookeeper/data下所有内容
3、kill所有节点 zookeeper进程,让zookeeper重新启动。
解决方法二:
升级zookeeper版本至3.4.4及以上