$ CLUSTER_NAME=my-cluster
您可以备份和恢复本地环境中托管集群上的 etcd 以修复故障。
通过备份和恢复托管集群上的 etcd,您可以修复故障,例如三节点集群的 etcd 成员中的数据损坏或丢失。如果 etcd 集群的多个成员遇到数据丢失或具有 `CrashLoopBackOff` 状态,此方法有助于防止 etcd 仲裁丢失。
此过程需要 API 停机。 |
已安装 `oc` 和 `jq` 二进制文件。
首先,设置环境变量并缩减 API 服务器
通过输入以下命令设置托管集群的环境变量,根据需要替换值
$ CLUSTER_NAME=my-cluster
$ HOSTED_CLUSTER_NAMESPACE=clusters
$ CONTROL_PLANE_NAMESPACE="${HOSTED_CLUSTER_NAMESPACE}-${CLUSTER_NAME}"
通过输入以下命令暂停托管集群的协调,根据需要替换值
$ oc patch -n ${HOSTED_CLUSTER_NAMESPACE} hostedclusters/${CLUSTER_NAME} -p '{"spec":{"pausedUntil":"true"}}' --type=merge
通过输入以下命令缩减 API 服务器
缩减 `kube-apiserver`
$ oc scale -n ${CONTROL_PLANE_NAMESPACE} deployment/kube-apiserver --replicas=0
缩减 `openshift-apiserver`
$ oc scale -n ${CONTROL_PLANE_NAMESPACE} deployment/openshift-apiserver --replicas=0
缩减 `openshift-oauth-apiserver`
$ oc scale -n ${CONTROL_PLANE_NAMESPACE} deployment/openshift-oauth-apiserver --replicas=0
接下来,使用以下方法之一对 etcd 进行快照
使用以前备份的 etcd 快照。
如果您有可用的 etcd pod,请通过完成以下步骤从活动 etcd pod 拍摄快照
通过输入以下命令列出 etcd pod
$ oc get -n ${CONTROL_PLANE_NAMESPACE} pods -l app=etcd
通过输入以下命令对 pod 数据库进行快照并将其保存到您本地的机器上
$ ETCD_POD=etcd-0
$ oc exec -n ${CONTROL_PLANE_NAMESPACE} -c etcd -t ${ETCD_POD} -- env ETCDCTL_API=3 /usr/bin/etcdctl \
--cacert /etc/etcd/tls/etcd-ca/ca.crt \
--cert /etc/etcd/tls/client/etcd-client.crt \
--key /etc/etcd/tls/client/etcd-client.key \
--endpoints=https://127.0.0.1:2379 \
snapshot save /var/lib/snapshot.db
通过输入以下命令验证快照是否成功
$ oc exec -n ${CONTROL_PLANE_NAMESPACE} -c etcd -t ${ETCD_POD} -- env ETCDCTL_API=3 /usr/bin/etcdctl -w table snapshot status /var/lib/snapshot.db
通过输入以下命令创建快照的本地副本
$ oc cp -c etcd ${CONTROL_PLANE_NAMESPACE}/${ETCD_POD}:/var/lib/snapshot.db /tmp/etcd.snapshot.db
从 etcd 持久性存储中复制快照数据库
通过输入以下命令列出 etcd pod
$ oc get -n ${CONTROL_PLANE_NAMESPACE} pods -l app=etcd
找到正在运行的 pod 并将其名称设置为 `ETCD_POD: ETCD_POD=etcd-0` 的值,然后通过输入以下命令复制其快照数据库
$ oc cp -c etcd ${CONTROL_PLANE_NAMESPACE}/${ETCD_POD}:/var/lib/data/member/snap/db /tmp/etcd.snapshot.db
接下来,通过输入以下命令缩减 etcd statefulset
$ oc scale -n ${CONTROL_PLANE_NAMESPACE} statefulset/etcd --replicas=0
通过输入以下命令删除第二和第三个成员的卷
$ oc delete -n ${CONTROL_PLANE_NAMESPACE} pvc/data-etcd-1 pvc/data-etcd-2
创建一个 pod 以访问第一个 etcd 成员的数据
通过输入以下命令获取 etcd 镜像
$ ETCD_IMAGE=$(oc get -n ${CONTROL_PLANE_NAMESPACE} statefulset/etcd -o jsonpath='{ .spec.template.spec.containers[0].image }')
创建一个允许访问 etcd 数据的 pod
$ cat << EOF | oc apply -n ${CONTROL_PLANE_NAMESPACE} -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: etcd-data
spec:
replicas: 1
selector:
matchLabels:
app: etcd-data
template:
metadata:
labels:
app: etcd-data
spec:
containers:
- name: access
image: $ETCD_IMAGE
volumeMounts:
- name: data
mountPath: /var/lib
command:
- /usr/bin/bash
args:
- -c
- |-
while true; do
sleep 1000
done
volumes:
- name: data
persistentVolumeClaim:
claimName: data-etcd-0
EOF
通过输入以下命令检查 `etcd-data` pod 的状态并等待其运行
$ oc get -n ${CONTROL_PLANE_NAMESPACE} pods -l app=etcd-data
通过输入以下命令获取 `etcd-data` pod 的名称
$ DATA_POD=$(oc get -n ${CONTROL_PLANE_NAMESPACE} pods --no-headers -l app=etcd-data -o name | cut -d/ -f2)
通过输入以下命令将 etcd 快照复制到 pod 中
$ oc cp /tmp/etcd.snapshot.db ${CONTROL_PLANE_NAMESPACE}/${DATA_POD}:/var/lib/restored.snap.db
通过输入以下命令从 `etcd-data` pod 中删除旧数据
$ oc exec -n ${CONTROL_PLANE_NAMESPACE} ${DATA_POD} -- rm -rf /var/lib/data
$ oc exec -n ${CONTROL_PLANE_NAMESPACE} ${DATA_POD} -- mkdir -p /var/lib/data
通过输入以下命令恢复 etcd 快照
$ oc exec -n ${CONTROL_PLANE_NAMESPACE} ${DATA_POD} -- etcdutl snapshot restore /var/lib/restored.snap.db \
--data-dir=/var/lib/data --skip-hash-check \
--name etcd-0 \
--initial-cluster-token=etcd-cluster \
--initial-cluster etcd-0=https://etcd-0.etcd-discovery.${CONTROL_PLANE_NAMESPACE}.svc:2380,etcd-1=https://etcd-1.etcd-discovery.${CONTROL_PLANE_NAMESPACE}.svc:2380,etcd-2=https://etcd-2.etcd-discovery.${CONTROL_PLANE_NAMESPACE}.svc:2380 \
--initial-advertise-peer-urls https://etcd-0.etcd-discovery.${CONTROL_PLANE_NAMESPACE}.svc:2380
输入以下命令,删除 Pod 中的临时 etcd 快照:
$ oc exec -n ${CONTROL_PLANE_NAMESPACE} ${DATA_POD} -- rm /var/lib/restored.snap.db
输入以下命令,删除数据访问部署:
$ oc delete -n ${CONTROL_PLANE_NAMESPACE} deployment/etcd-data
输入以下命令,扩展 etcd 集群:
$ oc scale -n ${CONTROL_PLANE_NAMESPACE} statefulset/etcd --replicas=3
输入以下命令,等待 etcd 成员 Pod 返回并报告可用:
$ oc get -n ${CONTROL_PLANE_NAMESPACE} pods -l app=etcd -w
输入以下命令,扩展所有 etcd-writer 部署:
$ oc scale deployment -n ${CONTROL_PLANE_NAMESPACE} --replicas=3 kube-apiserver openshift-apiserver openshift-oauth-apiserver
输入以下命令,恢复托管集群的协调:
$ oc patch -n ${CLUSTER_NAMESPACE} hostedclusters/${CLUSTER_NAME} -p '{"spec":{"pausedUntil":""}}' --type=merge