应公司开发要求业务分离需要用到 ETCD 数据库,因为资源问题,也就不申请机器在虚机部署了,准备直接上容器,开发/测试/预生产都上了单节点的 ETCD

对于 ETCD 的容器化部署,官方目前只有 docker 容器的部署方式 https://etcd.io/docs/v3.6/install/ https://github.com/etcd-io/etcd/releases ,有一个 bitnami 的开源项目,它做了很多不支持 k8s 容器化的项目,其中就有 ETCD,我猛地一头就扎了进去,立马上手就部署,ETCD 起来了把连接方式给到开发就完了,我没有做任何自定义,直到那天 etcd 挂了(-_-||),我想着这上生产可不行啊,赶紧补一下 ETCD 的知识吧,先把自定义的内容先搞一搞,今天我来了

HELM 部署 ETCD

https://www.cnblogs.com/davygeek/p/8951999.html

helm 添加仓库

helm repo add bitnami https://charts.bitnami.com/bitnami

可根据 github 参数解析配置 https://github.com/bitnami/charts/tree/master/bitnami/etcd

部署集群

端口暴露修改(可选),如果没有集群外访问的需求可跳过

指定存储,我本地用了 nfs,公司 PRE 环境用了阿里云oss,默认申请8G,云存储20G起步,需要修改

$ helm install etcd bitnami/etcd --version 8.2.3 \
--set replicaCount=3 \
--set global.storageClass="nfs-client" \
--set service.type=NodePort \
--set service.nodePorts.client=32379 \
--set service.nodePorts.peer=32380 \
--set auth.rbac.rootPassword=abcdef     # 密码不能为纯数字

# 释义
--set replicaCount=3                   # 副本数量
--set global.storageClass="nfs-client" # 指定可用的storageClass的名字
--set service.type=NodePort            # 通过NodePort暴露端口
--set service.nodePorts.client=32379   # 暴露客户端通信端口
--set service.nodePorts.peer=32380     # 暴露集群通信端口
--set auth.rbac.rootPassword=abcdef    # etcd用户密码,默认用户为root,密码不能为纯数字

执行成功后输出

NAME: etcd
LAST DEPLOYED: Fri Jun 10 15:06:21 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: etcd
CHART VERSION: 8.2.3
APP VERSION: 3.5.4

** Please be patient while the chart is being deployed **

etcd can be accessed via port 2379 on the following DNS name from within your cluster:

    etcd.default.svc.cluster.local

To create a pod that you can use as a etcd client run the following command:

    kubectl run etcd-client --restart='Never' --image docker.io/bitnami/etcd:3.5.4-debian-10-r25 --env ROOT_PASSWORD=$(kubectl get secret --namespace default etcd -o jsonpath="{.data.etcd-root-password}" | base64 -d) --env ETCDCTL_ENDPOINTS="etcd.default.svc.cluster.local:2379" --namespace default --command -- sleep infinity

Then, you can set/get a key using the commands below:

    kubectl exec --namespace default -it etcd-client -- bash
    etcdctl --user root:$ROOT_PASSWORD put /message Hello
    etcdctl --user root:$ROOT_PASSWORD get /message

To connect to your etcd server from outside the cluster execute the following commands:

    export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
    export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services etcd)
    echo "etcd URL: http://$NODE_IP:$NODE_PORT/"

 * As rbac is enabled you should add the flag `--user root:$ETCD_ROOT_PASSWORD` to the etcdctl commands. Use the command below to export the password:

    export ETCD_ROOT_PASSWORD=$(kubectl get secret --namespace default etcd -o jsonpath="{.data.etcd-root-password}" | base64 -d)

输出信息主要看一下几个

# ETCD客户端启动,这里我是使用了 nodeport 来暴露的,所以 ETCDCTL_ENDPOINTS="etcd.default.svc.cluster.local:2379,改为
# ETCDCTL_ENDPOINTS="192.168.1.12:32379"    随便一台节点的加 nodeport 端口
$ kubectl run etcd-client --restart='Never' --image docker.io/bitnami/etcd:3.5.4-debian-10-r25 --env ROOT_PASSWORD=$(kubectl get secret --namespace default etcd -o jsonpath="{.data.etcd-root-password}" | base64 -d) --env ETCDCTL_ENDPOINTS="192.168.1.12:32379" --namespace default --command -- sleep infinity

# 进入容器ETCD客户端
$ kubectl exec --namespace default -it etcd-client -- bash

# 尝试操作ETCD数据库
etcdctl --user root:$ROOT_PASSWORD put /message Hello
etcdctl --user root:$ROOT_PASSWORD get /message

感兴趣的可以拉取 ETCD chart 包来研究研究

指定版本是因为我在部署开发测试的时候拉取的最新的是这个版本,过了几天就成 8.2.5 了,也不知道改动了啥

helm pull bitnami/etcd --version 8.2.3

解压 Chart 包

tar zxf etcd-8.2.2-tgz

使用 CronJob 备份

CronJob 备份后存储在

本地 nfs 存储,已经创建 nfs 的 storageClass,创建 nfs 请参考:Kubernetes–StorageClass(二)

$ kubectl get sc -o name
storageclass.storage.k8s.io/nfs-client

编写 PVC 文件,用来存储 etcd 备份

$ vim etcd-backup-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: etcd-backup-pvc
  namespace: default
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: "nfs-client"    # 指定storageClass
  resources:
    requests:
      storage: 2Gi

创建 PVC

$ kubectl create -f etcd-backup-pvc.yaml

编写 CronJob 来定时备份,注意命名空间

$ vim etcd-backup-cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: etcd-backup-cronjob
  namespace: default
spec:
 schedule: "* * * * *"    # 为了测试改为每分钟执行备份
 jobTemplate:
  spec:
    template:
      metadata:
       labels:
        app: etcd-backup-cronjob
      spec:
        containers:
        - name: etcd
          image: docker.io/bitnami/etcd:3.5.4-debian-10-r25
          command:
          - sh
          - -c
          - "etcdctl --endpoints $ENDPOINT --user $USER:$PASSWORD snapshot save /snapshot/$(date +%Y%m%d_%H%M%S)_snapshot.db"
          env:
          - name: USER     # etcd 用户
            value: root
          - name: PASSWORD  # etcd 用户密码
            value: qYKH9wUBch
          - name: ENDPOINT
            value: "192.168.1.12:32379"  # ETCD的客户端地址
          volumeMounts:
            - mountPath: "/snapshot"
              name: snapshot
              subPath: data/etcd-snapshot
        restartPolicy: OnFailure
        volumes:
          - name: snapshot
            persistentVolumeClaim:
              claimName: etcd-backup-pvc    # 指定创建好的PVC
        hostNetwork: true

创建 cronjob

$ kubectl create -f etcd-backup-cronjob.yaml

$ kubectl get cj,po | grep etcd-backup
cronjob.batch/etcd-backup-cronjob   * * * * *   False     0        42s             55s
pod/etcd-backup-cronjob-27580769-gjxz9                           0/1     Completed   0          42s

查看 NFS 路径的备份文件

$ ls /nfsdata/default-etcd-backup-pvc-pvc-1196fd3b-2cf7-4991-9131-03d4c28246bf/data/etcd-snapshot
20220610_014012_snapshot.db

模拟数据增删

$ etcdctl --user root:$ROOT_PASSWORD put /myblogurl https://www.feiyiblog.com
OK
$ etcdctl --user root:$ROOT_PASSWORD put /myname FeiYi                       
OK
$ etcdctl --user root:$ROOT_PASSWORD get /myblogurl   
/myblogurl
https://www.feiyiblog.com
$ etcdctl --user root:$ROOT_PASSWORD get /myname   
/myname
FeiYi

启动新集群并根据备份数据添加数据

挑一个最新的备份数据文件

# ll /nfsdata/default-etcd-backup-pvc-pvc-1196fd3b-2cf7-4991-9131-03d4c28246bf/data/etcd-snapshot/
total 192
-rw------- 1 1001 root 20512 Jun 10 15:32 20220610_014012_snapshot.db
-rw------- 1 1001 root 20512 Jun 10 15:34 20220610_014212_snapshot.db
-rw------- 1 1001 root 20512 Jun 10 15:35 20220610_014312_snapshot.db
-rw------- 1 1001 root 20512 Jun 10 15:36 20220610_014412_snapshot.db
-rw------- 1 1001 root 20512 Jun 10 15:37 20220610_014512_snapshot.db
-rw------- 1 1001 root 20512 Jun 10 15:38 20220610_014612_snapshot.db
-rw------- 1 1001 root 20512 Jun 10 15:39 20220610_014712_snapshot.db

启动新的 ETCD 集群,密码最好一致,不一样好像会无法恢复

# 记得改nodeport的端口,否则和旧集群冲突
helm install etcd-new bitnami/etcd --version 8.2.3 \
  --set replicaCount=3 \
  --set service.type=NodePort \
  --set auth.rbac.rootPassword=abcdef \
  --set service.nodePorts.client=32479 \
  --set service.nodePorts.peer=32480 \
  --set startFromSnapshot.enabled=true \
  --set global.storageClass=nfs-client \
  --set startFromSnapshot.existingClaim=etcd-backup-pvc \
  --set startFromSnapshot.snapshotFilename=data/etcd-snapshot/20220610_014712_snapshot.db

# 释义
  --set replicaCount=3                   # 副本数量
  --set service.type=NodePort            # 通过NodePort暴露端口
  --set auth.rbac.rootPassword=abcdef    # etcd用户密码,默认用户为root,密码不能为纯数字,这里的密码要与旧集群密码一致
  --set service.nodePorts.client=32479   # 暴露客户端通信端口
  --set service.nodePorts.peer=32480     # 暴露集群通信端口
  --set startFromSnapshot.enabled=true   # 开启从快照启动集群
  --set global.storageClass=nfs-client   # 指定可用的storageClass的名字
  --set startFromSnapshot.existingClaim=etcd-backup-pvc # 指定快照所在的pvc名字
  --set startFromSnapshot.snapshotFilename=data/etcd-snapshot/20220610_014712_snapshot.db  # 指定快照所在pvc内的路径

登录客户端验证数据

$ kubectl run etcd-new-client --restart='Never' --image docker.io/bitnami/etcd:3.5.4-debian-10-r25 --env ROOT_PASSWORD=$(kubectl get secret --namespace default etcd-new -o jsonpath="{.data.etcd-root-password}" | base64 -d) --env ETCDCTL_ENDPOINTS="192.168.1.12:32479" --namespace default --command -- sleep infinity

$ kubectl exec --namespace default -it etcd-new-client -- bash

$ etcdctl --user root:$ROOT_PASSWORD get /myname   
/myname
FeiYi
$ etcdctl --user root:$ROOT_PASSWORD get /myblogurl
/myblogurl
https://www.feiyiblog.com
$ etcdctl --user root:$ROOT_PASSWORD get /message  
/message
Hello

最后我真牛逼~

评论




正在载入...
PoweredHexo
HostedAliyun
DNSAliyun
ThemeVolantis
UV
PV
BY-NC-SA 4.0