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使用中遇到的问题以及处理方案,求关注!

欢迎关注我的个人微信公众号,一个菜鸟程序猿的技术技术分享和奔溃日常

一个菜鸟程序猿的技术技术分享和奔溃日常

GitHub 加速计划 / ca / canal
28.22 K
7.57 K
下载
alibaba/canal: Canal 是由阿里巴巴开源的分布式数据库同步系统,主要用于实现MySQL数据库的日志解析和实时增量数据订阅与消费,广泛应用于数据库变更消息的捕获、数据迁移、缓存更新等场景。
最近提交(Master分支:3 个月前 )
1e5b8a20 - 2 个月前
ff82fd65 2 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐