k8s集群下canal-server的伪高可用实践
前言
前面我们已经介绍了canal的admin、server、adapter三个部分的容器化以及在k8s集群下的搭建过程。在创建canal-server的时候,k8s环境下,容器重启会造成ip地址的变动给我们带来了一些问题,我们通过在创建canal-server的时候使用statefuset类型,使其可以通过固定的域名去向canal-admin注册,从而保证了canal-server的连接地址的稳定不变。本文将利用容器异常自动重启这个特性,搭建一个anal-server的伪高可用版本。
问题
在使用server的默认配置时,canal.properties下的canal.instance.global.spring.xml这一项设置的是classpath:spring/file-instance.xml,在该模式下,server会将解析位点和消费位点以本地文件的形式记录下来,而在咱们之前搭建的容器环境下,容器一旦重启,这些记录着位点信息的文件也就不存在了,server容器重新启动后会认为这是一个新建的同步任务,然后以当前位点开始解析binlog,这样必然会发生数据丢失的现象。
解决方案
容器重启造成数据丢失的原因是容器重启后,容器内的内容没有做持久化的存储导致记录解析和消费位点的文件丢失,进而以当前位点解析binlog,从而造成的数据丢失。
这个时候,我们只需要将这个记录解析和消费位点的文件能够在容器重启之后不丢失就可以了,下面我们将在k8s环境下使用PV和PVC来解决这个问题。
- 需要先将磁盘挂载到192.168.100.1的/data/canal-server目录下,然后创建pv,pv.yaml如下
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv-sda
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /data/canal-server
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- 192.168.100.1
#创建PV
kubectl apply -f pv.yaml
- 因为server是用statefuset类型创建,所以无需手动创建PVC,修改server的server.yaml如下
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: canal-server-stable
namespace: testcanal
labels:
app: canal-server-stable
spec:
selector:
matchLabels:
app: canal-server-stable
serviceName: "canal-server-discovery-svc-stable"
replicas: 4
template:
metadata:
labels:
app: canal-server-stable
annotations:
prometheus.io/path: /
prometheus.io/port: "11112"
prometheus.io/scrape: "true"
spec:
containers:
- image: canal/canal-server:v1.1.4
name: canal-server-stable
imagePullPolicy: Always
ports:
- containerPort: 11110
protocol: TCP
name: http1
- containerPort: 11111
protocol: TCP
name: http2
- containerPort: 11112
protocol: TCP
name: http3
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 4000m
memory: 4Gi
volumeMounts:
- mountPath: /home/canal/bin/config.sh
subPath: config.sh
name: server-conf
#挂载pvc到容器的/home/canal/instance目录下
- name: data
mountPath: /home/canal/instance
volumes:
- name: server-conf
configMap:
name: canal-server-stable-conf
defaultMode: 0777
securityContext:
runAsUser: 0
#自动与满足条件的pv匹配
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: 'local-storage'
resources:
requests:
storage: "1G"
#创建server容器
kubectl apply -f server.yaml
- 在admin界面修改server的canal.properties中的canal.conf.dir改为以下配置
# pvc挂载到容器的目录
canal.conf.dir = ../instance
总结
使用挂载持久化存储到容器内可以保证server在发生异常重启之后还能够从记录解析和消费位点信息的文件中读取位点信息,在异常发生的时间重新解析binlog,从而保证了数据的准确性。以上便是我根据容器特性搭建的伪高可用的canal-server,该版本的问题是pv使用的本地存储,若磁盘或物理机发生故障,数据同样会丢失,可以使用高可用存储方案替代。后续继续更新canal使用中遇到的问题以及处理方案,求关注!
欢迎关注我的个人微信公众号,一个菜鸟程序猿的技术技术分享和奔溃日常
更多推荐
所有评论(0)