原文 - 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環境下的數據。