[譯 ] Kubernetes集羣災備(disaster recovery)的終極指南

原文 - The Ultimate Guide to Disaster Recovery for Your Kubernetes Clustersnode

backup

序言

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個理由:網絡

  1. 爲了在災難後恢復: 好比某人意外地將你的deployment所處的namespace刪除了的狀況。
  2. 爲了複製環境: 你想要複製你的生產環境到一個臨時環境,以便在一個重大升級前作一些測試。
  3. 遷移Kubernetes集羣: 比方說,你想要遷移的你的Kubernetes集羣到另外一個環境。

須要備份什麼?

如今你知道爲何,讓咱們看看具體備份要作什麼。你須要備份2個東西:app

  1. 你的Kubernetes control plane(一般是master節點)是把數據存放在etcd存儲中,因而你須要備份etcd全部陳述以便獲取全部Kubernetes資源。
  2. 若是你有"有狀態"(stateful)容器(一般在實際使用中是會遇到的),你還須要備份持久卷(persistent volume)。

如何備份?

有各類工具好比Heptio ark和Kube-backup支持搭建於cloud provider上的Kubernetes集羣的備份和回覆。可是若是你沒有在使用已經被管理(指雲供應商提供的)的Kubernetes集羣呢?你可能會須要親自上陣,若是你的Kubernetes運行在裸機上,就像咱們同樣。 咱們運行擁有3個master的Kubernetes集羣,而且有3個etcd member同時運行在每一個master上。若是咱們失去了一個master,咱們還能夠恢復master,因爲依然知足etcd的最低運行數。如今若是在生產環境下咱們失去2個master,咱們就須要一個機制去恢復集羣運做。負載均衡

Kubernetes_backup_machanism

想知道如何構建多個master的Kubernetes集羣?繼續閱讀吧!ide

給etcd作備份:

給etcd備份機制的不一樣之處取決於你是如何在Kubernetes環境中構建etcd集羣的。 在Kubernetes環境中有2種方法來設置etcd集羣:工具

  1. 內部etcd集羣: 這表示你正在Kubernetes集羣中運行容器/pod形式的etcd集羣,而且管理這些pod的責任在於Kubernetes。
  2. 外部etcd集羣: 大多數狀況下Etcd集羣以Linux service的形式運行在Kubernetes集羣外,而且提供endpoint給Kubernetes集羣以便Kubernetes集羣來讀寫。

給內部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
複製代碼

給外部Etcd集羣作備份的策略:

若是你在Linux主機上做爲一個service來運行etcd集羣,你應該設置一個Linux的定時任務(cron job)來備份你的集羣。 運行如下的命令來備份etcd。

ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save /path/for/backup/snapshot.db
複製代碼

災難恢復(disaster recovery)

如今,假設Kubernetes集羣徹底downn掉以後,咱們須要經過etcd snapshot恢復Kubernetes集羣。 通常來講,咱們須要啓動etcd集羣,而後在master節點兼etcd endpoint的這個(這些)主機上執行kubeadm init。 保證你把備份了的證書放到/etc/kubernetes/pki(kubeadm init建立集羣時建立的存放Kubernetes集羣用到的證書的默認目錄)目錄下。

內部etcd集羣恢復策略:

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
複製代碼

外部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環境下的數據。

相關文章
相關標籤/搜索