原文 - The Ultimate Guide to Disaster Recovery for Your Kubernetes Clustersnode
Kubernetes容许咱们运行大规模容器化app而不须要过多关注app的负载均衡细节。你能够经过在Kubernetes上运行多个app副本(replicas)(pods)来保证你的app的高可用性。全部容器编排的复杂细节安全地隐藏着,因此你能够专一于开发app而不是专一在如何部署它。你能够在这里了解更多关于Kubernetes集群高可用以及如何经过Kubeadm实现Kubernetes高可用(use Kubedm for high availability in Kubernetes)。docker
可是使用Kubernetes有它自己的一些挑战以及要让Kubernetes运行起来须要花一些功夫。若是你不熟悉如何运行Kubernetes,你或许能够看看这个。api
Kubernetes可让咱们实现零停机的部署,可是必然仍是会有可能在任什么时候候发生服务中断的事件。你的网络可能down掉,你的最新的app镜像可能引发一个严重的bug,或者在最罕见的案例下,你可能面临一个天然灾害。安全
当你在使用Kubernetes的时候,或早或晚,你须要设置一个备份。为了以防你的集群进入到一个不可回复的状态,你须要一个备份来回复到集群早前的稳定状态。bash
关于你为何须要为你的Kubernetes集群准备备份和回复机制,有3个理由:网络
如今你知道为何,让咱们看看具体备份要作什么。你须要备份2个东西:app
有各类工具好比Heptio ark和Kube-backup支持搭建于cloud provider上的Kubernetes集群的备份和回复。可是若是你没有在使用已经被管理(指云供应商提供的)的Kubernetes集群呢?你可能会须要亲自上阵,若是你的Kubernetes运行在裸机上,就像咱们同样。 咱们运行拥有3个master的Kubernetes集群,而且有3个etcd member同时运行在每一个master上。若是咱们失去了一个master,咱们还能够恢复master,因为依然知足etcd的最低运行数。如今若是在生产环境下咱们失去2个master,咱们就须要一个机制去恢复集群运做。负载均衡
想知道如何构建多个master的Kubernetes集群?继续阅读吧!ide
给etcd备份机制的不一样之处取决于你是如何在Kubernetes环境中构建etcd集群的。 在Kubernetes环境中有2种方法来设置etcd集群:工具
为了给一个内部etcd pod取备份,咱们须要使用Kubernetes CronJob机能,这个方法不须要在宿主机(node)上安装任何etcdctl客户端。 如下是定义了Kubernetes CronJob,用来每分钟获取etcd备份:
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: backup
namespace: kube-system
spec:
# activeDeadlineSeconds: 100
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
# Same image as in /etc/kubernetes/manifests/etcd.yaml
image: k8s.gcr.io/etcd:3.2.24
env:
- name: ETCDCTL_API
value: "3"
command: ["/bin/sh"]
args: ["-c", "etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key snapshot save /backup/etcd-snapshot-$(date +%Y-%m-%d_%H:%M:%S_%Z).db"]
volumeMounts:
- mountPath: /etc/kubernetes/pki/etcd
name: etcd-certs
readOnly: true
- mountPath: /backup
name: backup
restartPolicy: OnFailure
hostNetwork: true
volumes:
- name: etcd-certs
hostPath:
path: /etc/kubernetes/pki/etcd
type: DirectoryOrCreate
- name: backup
hostPath:
path: /data/backup
type: DirectoryOrCreate
复制代码
若是你在Linux主机上做为一个service来运行etcd集群,你应该设置一个Linux的定时任务(cron job)来备份你的集群。 运行如下的命令来备份etcd。
ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save /path/for/backup/snapshot.db
复制代码
如今,假设Kubernetes集群彻底downn掉以后,咱们须要经过etcd snapshot恢复Kubernetes集群。 通常来讲,咱们须要启动etcd集群,而后在master节点兼etcd endpoint的这个(这些)主机上执行kubeadm init。 保证你把备份了的证书放到/etc/kubernetes/pki(kubeadm init建立集群时建立的存放Kubernetes集群用到的证书的默认目录)目录下。
docker run --rm \
-v '/data/backup:/backup' \
-v '/var/lib/etcd:/var/lib/etcd' \
--env ETCDCTL_API=3 \
'k8s.gcr.io/etcd:3.2.24' \
/bin/sh -c "etcdctl snapshot restore '/backup/etcd-snapshot-2018-12-09_11:12:05_UTC.db' ; mv /default.etcd/member/ /var/lib/etcd/"
kubeadm init --ignore-preflight-errors=DirAvailable--var-lib-etcd
复制代码
经过如下命令恢复3个etcd节点:
ETCDCTL_API=3 etcdctl snapshot restore snapshot-188.db \
--name master-0 \
--initial-cluster master-0=http://10.0.1.188:2380,master-01=http://10.0.1.136:2380,master-2=http://10.0.1.155:2380 \
--initial-cluster-token my-etcd-token \
--initial-advertise-peer-urls http://10.0.1.188:2380
ETCDCTL_API=3 etcdctl snapshot restore snapshot-136.db \
--name master-1 \
--initial-cluster master-0=http://10.0.1.188:2380,master-1=http://10.0.1.136:2380,master-2=http://10.0.1.155:2380 \
--initial-cluster-token my-etcd-token \
--initial-advertise-peer-urls http://10.0.1.136:2380
ETCDCTL_API=3 etcdctl snapshot restore snapshot-155.db \
--name master-2 \
--initial-cluster master-0=http://10.0.1.188:2380,master-1=http://10.0.1.136:2380,master-2=http://10.0.1.155:2380 \
--initial-cluster-token my-etcd-token \
--initial-advertise-peer-urls http://10.0.1.155:2380
The above three commands will give you three restored folders on three nodes named master:
0.etcd, master-1.etcd and master-2.etcd
复制代码
如今,中止全部节点上的etcd服务,用恢复了的文件夹替换为全部节点上etcd的文件夹,再启动etcd服务。如今你能够看到全部节点,可是有可能只能看见master是ready状态,你须要从新使用现存的ca.crt(你应该作一个备份)文件将另外2个节点join进集群。 在master上运行如下命令:
kubeadm token create --print-join-command
复制代码
这会给你kubeadm join命令,添加一个参数--ignore-preflight-errors
在另外2个节点上运行此命令,让它们变为ready状态。
其中一个处理master故障的方法是建立多master的Kubernetes集群,可是即使这样也不能让你彻底消除Kubernetes etcd备份和恢复的需求,并且你也有可能会意外地销毁HA环境下的数据。