Kubernetes v1.25 引入了容器檢查點(diǎn) API 作為 alpha 特性。這提供了一種在不停止容器的情況下備份和恢復(fù)運(yùn)行在 Pod 中的容器的方式。此功能主要用于調(diào)試分析,但任何 Kubernetes 用戶都可以利用常規(guī)備份和恢復(fù)功能。
接下來,讓我們來看看這個特性,并了解如何在我們的集群中啟用它,并利用它進(jìn)行備份和恢復(fù)或調(diào)試分析。
安裝
在我們開始對任何容器進(jìn)行檢查點(diǎn)處理之前,我們需要一個 playgroud,在這個 playgroud 上我們可以操作 kubelet 和它的工作負(fù)載。為此,我們將需要一個支持容器檢查點(diǎn)處理的 v1.25+ 版本的 Kubernetes集 群和容器運(yùn)行時環(huán)境。
這里我們將使用在 Vagrant 中構(gòu)建的虛擬機(jī)內(nèi)使用 kubeadm 創(chuàng)建一個集群,只需執(zhí)行vagrant up即可快速啟動該集群。
如果你想搭建自己的集群,請確保集群必須啟用ContainerCheckpoint功能標(biāo)志。對于 kubeadm 使用以下配置:
#kubeadm-config.yaml apiVersion:kubelet.config.k8s.io/v1beta1 kind:KubeletConfiguration featureGates: ContainerCheckpoint:true --- apiVersion:kubeadm.k8s.io/v1beta3 kind:ClusterConfiguration kubernetesVersion:v1.25.0 apiServer: extraArgs: feature-gates:"ContainerCheckpoint=true" controllerManager: extraArgs: feature-gates:"ContainerCheckpoint=true" scheduler: extraArgs: feature-gates:"ContainerCheckpoint=true" networking: podSubnet:10.244.0.0/16
這將向集群組件傳遞--feature-gates標(biāo)志。此外,我們還需要使用支持檢查點(diǎn)的容器運(yùn)行時。撰寫本文時,僅CRI-O支持它,而 Containerd 可能很快也會支持(https://github.com/containerd/containerd/pull/6965),最新版本的crictl已經(jīng)支持通過crictl checkpoint創(chuàng)建檢查點(diǎn)。
要使用 CRI-O 配置集群,請按照文檔中的說明安裝它,或者使用上述存儲庫中的腳本(你應(yīng)該在虛擬機(jī)而不是本地運(yùn)行此腳本)。
另外,我們還需要為 CRI-O 啟用CRIU,這是在后臺執(zhí)行實(shí)際檢查點(diǎn)的工具。要啟用它,我們需要設(shè)置--enable-criu-support=true標(biāo)志。上面的腳本可以為你做到這一點(diǎn)。
另外,如果你打算將其恢復(fù)到 Pod 中,還需要將--drop-infra-ctr設(shè)置為 false,否則您將收到CreateContainerError并顯示如下消息:
kubeletError:podlevelPIDnamespacerequestedforthecontainer,... ...butpodsandboxwasnotsimilarlyconfigured,anddoesnothaveaninfracontainer
在安裝了 CRI-O 之后,我們還需要告訴 kubeadm 使用它的 sock 文件,下面的配置將會處理這個問題:
apiVersion:kubeadm.k8s.io/v1beta3 kind:InitConfiguration localAPIEndpoint: advertiseAddress:192.168.56.2 bindPort:6443 nodeRegistration: criSocket:"unix:///var/run/crio/crio.sock" ---
然后我們就可以使用以下命令快速啟動集群:
kubeadminit--config=.../kubeadm-config.yaml--upload-certs|teekubeadm-init.out
這將給我們提供一個單節(jié)點(diǎn)集群,如下(注意容器運(yùn)行時版本):
$kubectlgetnodes-owide NAMESTATUSROLESAGEVERSION...OS-IMAGEKERNEL-VERSIONCONTAINER-RUNTIME kubemasterReadycontrol-plane82sv1.25.4...Ubuntu20.04.5LTS5.4.0-125-genericcri-o://1.25.0
Checkpointing
集群安裝完成后,我們可以嘗試創(chuàng)建一個檢查點(diǎn)。在 Kubernetes 上通??梢允褂?kubectl 或者運(yùn)行 curl 命令來執(zhí)行常規(guī)操作,訪問集群 APIServer。然而,在這里這樣做是行不通的,因?yàn)闄z查點(diǎn) API 只暴露在每個集群節(jié)點(diǎn)上的 kubelet 上。因此,我們必須前往節(jié)點(diǎn)上并直接與 kubelet 交互:
$vagrantsshkubemaster $sudosu- #Checkifit'srunning... $systemctlstatuskubelet kubelet.service-kubelet:TheKubernetesNodeAgent Loaded:loaded(/lib/systemd/system/kubelet.service;enabled;vendorpreset:enabled) Drop-In:/etc/systemd/system/kubelet.service.d └─10-kubeadm.conf Active:active(running)sinceSat2022-11-121029UTC;30sago Docs:https://kubernetes.io/docs/home/ MainPID:29501(kubelet) Tasks:14(limit:2339) Memory:34.7M CGroup:/system.slice/kubelet.service └─29501/usr/bin/kubelet--bootstrap-kubeconfig=...--kubeconfig=...
為了創(chuàng)建檢查點(diǎn),我們還需要一個正在運(yùn)行的 Pod。讓我們在 default 命名空間中創(chuàng)建一個 Nginx Pod:
$kubectltaintnodes--allnode-role.kubernetes.io/control-plane- $kubectlrunwebserver--image=nginx-ndefault $kubectlgetpods-owide NAMEREADYSTATUSRESTARTSAGEIPNODE webserver1/1Running027s10.85.0.4kubemaster
這里我們從節(jié)點(diǎn)中刪除了污點(diǎn),這樣即使它是控制平面,我們也可以在節(jié)點(diǎn)上調(diào)度工作負(fù)載。
接下來,讓我們向 kubelet 發(fā)出一個示例 API 請求,來查看是否正常:
$curl-skv-XGET"https://localhost:10250/pods" --key/etc/kubernetes/pki/apiserver-kubelet-client.key --cacert/etc/kubernetes/pki/ca.crt --cert/etc/kubernetes/pki/apiserver-kubelet-client.crt { "kind":"PodList", "apiVersion":"v1", "metadata":{}, "items":[ { "metadata":{ "name":"webserver", "namespace":"default", ... } } ... }
kubelet 默認(rèn)運(yùn)行在端口 10250 上,因此我們使用 curl 命令并請求其所有的 Pod。我們還需要指定 CA 證書、客戶端證書和密鑰進(jìn)行身份驗(yàn)證。
接下來就可以創(chuàng)建一個檢查點(diǎn)了:
$curl-sk-XPOST"https://localhost:10250/checkpoint/default/webserver/webserver" --key/etc/kubernetes/pki/apiserver-kubelet-client.key --cacert/etc/kubernetes/pki/ca.crt --cert/etc/kubernetes/pki/apiserver-kubelet-client.crt #Response: #{"items":["/var/lib/kubelet/checkpoints/checkpoint-webserver_default-webserver-2022-11-12T1013Z.tar"]} #Checkthedirectory: $ls-l/var/lib/kubelet/checkpoints/ total3840 -rw-------1rootroot3931136Nov1210:28checkpoint-webserver_default-webserver-2022-11-12T1013Z.tar #Verifythatoriginalcontainerisstillrunning: $crictlps--namewebserver CONTAINERIMAGECREATEDSTATENAMEATTEMPTPODIDPOD 880ee7ddff7f3docker.io/library/nginx@sha256:...48secondsagoRunningwebserver0d584446dd8d5ewebserver
檢查點(diǎn) API 位于.../checkpoint/${NAMESPACE}/${POD}/${CONTAINER},這里我們使用之前創(chuàng)建的 Pod,此請求在/var/lib/kubelet/checkpoints/checkpoint-
運(yùn)行上述 curl 后,您可能會收到如下錯誤:
checkpointingofdefault/webserver/webserverfailed(CheckpointContainerisonlysupportedintheCRIv1runtimeAPI) #or checkpointingofdefault/webserver/webserverfailed(rpcerror:code=Unknowndesc=checkpoint/restoresupportnotavailable)
這意味著您的容器運(yùn)行時尚不支持檢查點(diǎn)功能,或者未正確啟用。
分析
我們現(xiàn)在有了一個檢查點(diǎn)容器存檔,所以讓我們看看里面有什么:
$cd/var/lib/kubelet/checkpoints/ #Renamebecause"tar"doesn'tlike":"innames $mv"checkpoint-webserver_default-webserver-2022-11-12T1013Z.tar"webserver.tar #Viewcontents: $tar--exclude="*/*"-tfwebserver.tar dump.log checkpoint/ config.dump spec.dump rootfs-diff.tar io.kubernetes.cri-o.LogPath #Extract: $tar-xfcheckpoint-webserver_default-webserver-2022-09-04T1037Z.tar $lscheckpoint/ cgroup.imgfdinfo-4.imgids-31.imgmountpoints-13.imgpages-2.imgtmpfs-dev-139.tar.gz.img core-1.imgfiles.imginventory.imgnetns-10.imgpages-3.imgtmpfs-dev-140.tar.gz.img core-30.imgfs-1.imgipcns-var-11.imgpagemap-1.imgpages-4.imgtmpfs-dev-141.tar.gz.img core-31.imgfs-30.imgmemfd.imgpagemap-30.imgpstree.imgtmpfs-dev-142.tar.gz.img descriptors.jsonfs-31.imgmm-1.imgpagemap-31.imgseccomp.imgutsns-12.img fdinfo-2.imgids-1.imgmm-30.imgpagemap-shmem-94060.imgtimens-0.img fdinfo-3.imgids-30.imgmm-31.imgpages-1.imgtmpfs-dev-136.tar.gz.img $catconfig.dump { "id":"880ee7ddff7f3ce11ee891bd89f8a7356c97b23eb44e0f4fbb51cb7b94ead540", "name":"k8s_webserver_webserver_default_91ad1757-424e-4195-9f73-349b332cbb7a_0", "rootfsImageName":"docker.io/library/nginx:latest", "runtime":"runc", "createdTime":"2022-11-12T1056.460946241Z" } $tar-tfrootfs-diff.tar var/cache/nginx/proxy_temp/ var/cache/nginx/scgi_temp/ var/cache/nginx/uwsgi_temp/ var/cache/nginx/client_temp/ var/cache/nginx/fastcgi_temp/ etc/mtab run/nginx.pid run/secrets/kubernetes.io/ run/secrets/kubernetes.io/serviceaccount/
如果您不需要一個正在運(yùn)行的 Pod/容器進(jìn)行分析,那么提取并閱讀上面顯示的一些文件可能會為您提供必要的信息。
恢復(fù)
雖然 Checkpointing API 目前更加注重于調(diào)試分析,但它仍然可以用于從存檔中恢復(fù) Pod/容器。最簡單的方法是從檢查點(diǎn)存檔創(chuàng)建一個鏡像:
FROMscratch #NeedtouseADDbecauseitextractsarchives ADDwebserver.tar.
這里我們使用一個空(scratch)鏡像,然后向其添加歸檔文件。這里需要使用 ADD 命令,因?yàn)樗鼤詣咏鈮嚎s歸檔文件。接下來,我們使用 docker 或 buildah 構(gòu)建它。
$cd/var/lib/kubelet/checkpoints/ #Ordockerbuild... $buildahbud --annotation=io.kubernetes.cri-o.annotations.checkpoint.name=webserver -trestore-webserver:latest Dockerfile. $buildahpushlocalhost/restore-webserver:latestdocker.io/martinheinz/restore-webserver:latest
在上面,我們還添加了一個注解,描述了容器的原始可讀名稱,然后我們將其推送到一些倉庫,以便 Kubernetes 可以拉取它。最后,我們創(chuàng)建一個Pod,指定之前推送的鏡像。
#pod.yaml apiVersion:v1 kind:Pod metadata: name:restore-webserver labels: app:nginx spec: containers: -name:webserver image:docker.io/martinheinz/restore-webserver:latest nodeName:kubemaster
為了測試是否成功,我們可以通過 Service 將 Pod 暴露出來,并使用 curl 命令訪問其IP地址。
$kubectlexposepodrestore-webserver--port=80--target-port=80 $kubectlgetsvc NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE kubernetesClusterIP10.96.0.1443/TCP14m restore-webserverClusterIP10.104.30.90 80/TCP17s $curlhttp://10.104.30.90 Welcometonginx! ...
可以看到生效了,我們成功地在不停止它的情況下備份了并恢復(fù)一個正在運(yùn)行的 Pod。
總結(jié)
Kubernetes 的檢查點(diǎn)功能是增強(qiáng)容器化應(yīng)用程序容錯性和彈性的強(qiáng)大工具。通過實(shí)施良好規(guī)劃的檢查點(diǎn)策略,你可以將停機(jī)時間降至最低,改善資源利用情況,并簡化應(yīng)用程序遷移。
優(yōu)點(diǎn)
增強(qiáng)的容錯性——檢查點(diǎn)功能使應(yīng)用程序能夠在故障發(fā)生時從最后一個已知檢查點(diǎn)恢復(fù),減少停機(jī)時間,并確保應(yīng)用程序保持高可用性。
簡化遷移——檢查點(diǎn)功能使將正在運(yùn)行的應(yīng)用程序移動到不同主機(jī)變得更加容易。通過保存應(yīng)用程序的狀態(tài),您可以將其遷移到不同的節(jié)點(diǎn),而不會丟失進(jìn)度或造成中斷。如果您的應(yīng)用程序需要很長時間的預(yù)熱,您可以利用這個功能。這將大大減少應(yīng)用程序的啟動時間。
改進(jìn)的擴(kuò)展性——通過檢查點(diǎn)功能,您可以輕松地?cái)U(kuò)展應(yīng)用程序以滿足波動的需求。如果一個節(jié)點(diǎn)過載了,您可以將應(yīng)用程序遷移到擁有更多資源的另一個節(jié)點(diǎn),確保最佳性能。
高效的資源使用——檢查點(diǎn)功能允許您暫停長時間運(yùn)行的應(yīng)用程序,釋放資源給其他任務(wù)使用。當(dāng)再次需要應(yīng)用程序時,可以從檢查點(diǎn)恢復(fù)。
Kubernetes 檢查點(diǎn)的最佳實(shí)踐
定期創(chuàng)建檢查點(diǎn)——根據(jù)應(yīng)用程序的要求,定期創(chuàng)建檢查點(diǎn),以最小化在故障發(fā)生時的數(shù)據(jù)丟失。
監(jiān)控和管理資源——檢查點(diǎn)功能可能消耗大量系統(tǒng)資源,尤其是內(nèi)存。監(jiān)控集群的資源使用情況,并根據(jù)需要調(diào)整檢查點(diǎn)策略,以避免性能問題。
測試您的檢查點(diǎn)策略——定期測試您的檢查點(diǎn)過程,確保其按預(yù)期工作,并能在故障發(fā)生時恢復(fù)應(yīng)用程序。
自動化檢查點(diǎn)管理——使用像 cron 作業(yè)或 Kubernetes Operator 這樣的自動化工具,在預(yù)定的時間表上創(chuàng)建和管理檢查點(diǎn),確保您的應(yīng)用程序始終受到保護(hù)。
審核編輯:劉清
-
虛擬機(jī)
+關(guān)注
關(guān)注
1文章
917瀏覽量
28202 -
CRI
+關(guān)注
關(guān)注
1文章
16瀏覽量
12238 -
POD
+關(guān)注
關(guān)注
0文章
16瀏覽量
6025
原文標(biāo)題:如何使用 Kubernetes 檢查點(diǎn) API 快速進(jìn)行容器的備份和恢復(fù)
文章出處:【微信號:良許Linux,微信公眾號:良許Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論