Kubernetes v1.25 では、コンテナ チェックポイント API がアルファ機能として導入されました。これにより、コンテナを停止せずに、Pod で実行されているコンテナをバックアップおよび復元できるようになります。この機能は主にデバッグ分析を目的としていますが、Kubernetes ユーザーであれば誰でも通常のバックアップおよび復元機能を利用できます。 次に、この機能を確認し、クラスターでこの機能を有効にして、バックアップとリカバリ、またはデバッグ分析に活用する方法を理解しましょう。 インストールコンテナのチェックポイントを開始する前に、kubelet とそのワークロードを操作できるプレイグラウンドが必要です。これを行うには、コンテナ チェックポイントをサポートする Kubernetes クラスターとコンテナ ランタイム v1.25+ が必要になります。 ここでは、kubeadm を使用して、Vagrant で構築された仮想マシンにクラスターを作成します。関連する設定ファイルは GitHub リポジトリ (https://github.com/MartinHeinz/kubeadm-vagrant-playground/tree/container-checkpoint-api) に保存されています。クラスターをすばやく起動するには、 vagrant up を実行するだけです。 独自のクラスターを構築する場合は、クラスターで ContainerCheckpoint 機能フラグが有効になっていることを確認してください。 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: "Cnotallow=true" controllerManager: extraArgs: feature-gates: "Cnotallow=true" scheduler: extraArgs: feature-gates: "Cnotallow=true" networking: podSubnet: 10.244.0.0/16 これにより、--feature-gates フラグがクラスター コンポーネントに渡されます。さらに、チェックポイントをサポートするコンテナ ランタイムも使用する必要があります。この記事の執筆時点では CRI-O のみがサポートしていますが、Containerd も近々サポートする可能性があります (https://github.com/containerd/containerd/pull/6965)。 crictl の最新バージョンでは、crictl checkpoint によるチェックポイントの作成がすでにサポートされています。 CRI-O を使用してクラスターを構成するには、ドキュメントの説明に従ってインストールするか、上記のリポジトリのスクリプトを使用します (このスクリプトはローカルではなく VM で実行する必要があります)。 さらに、バックグラウンドで実際のチェックポイントを実行するツールである CRI-O に対して CRIU を有効にする必要もあります。これを有効にするには、--enable-criu-support=true フラグを設定する必要があります。上記のスクリプトでこれを実行できます。 また、Pod に復元する予定の場合は、--drop-infra-ctr を false に設定する必要もあります。そうしないと、次のようなメッセージを含む CreateContainerError が発生します。 kubelet Error: pod level PID namespace requested for the container, ... ... but pod sandbox was not similarly configured, and does not have an infra container 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" --- 次に、次のコマンドを使用してクラスターをすばやく起動できます。 kubeadm init --cnotallow=.../kubeadm-config.yaml --upload-certs | tee kubeadm-init.out これにより、次のような単一ノード クラスターが作成されます (コンテナーのランタイム バージョンに注意してください)。 $ kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION ... OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME kubemaster Ready control-plane 82s v1.25.4 ... Ubuntu 20.04.5 LTS 5.4.0-125-generic cri-o://1.25.0 チェックポイントクラスターがインストールされたら、チェックポイントを作成してみます。 Kubernetes では通常、kubectl を使用するか、curl コマンドを実行して一般的な操作を実行し、クラスター APIServer にアクセスできます。ただし、チェックポイント API は各クラスター ノード上の kubelet にのみ公開されるため、ここでこれを行うことは現実的ではありません。したがって、ノードに移動して kubelet と直接対話する必要があります。 $ vagrant ssh kubemaster $ sudo su - # Check if it's running... $ systemctl status kubelet kubelet.service - kubelet: The Kubernetes Node Agent Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled) Drop-In: /etc/systemd/system/kubelet.service.d └─10-kubeadm.conf Active: active (running) since Sat 2022-11-12 10:25:29 UTC; 30s ago Docs: https://kubernetes.io/docs/home/ Main PID: 29501 (kubelet) Tasks: 14 (limit: 2339) Memory: 34.7M CGroup: /system.slice/kubelet.service └─29501 /usr/bin/kubelet --bootstrap-kubecnotallow=... --kubecnotallow=... チェックポイントを作成するには、実行中の Pod も必要です。デフォルトの名前空間に Nginx Pod を作成しましょう。 $ kubectl taint nodes --all node-role.kubernetes.io/control-plane- $ kubectl run webserver --image=nginx -n default $ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE webserver 1/1 Running 0 27s 10.85.0.4 kubemaster ここでは、コントロール プレーンであってもノード上でワークロードをスケジュールできるように、ノードから汚染を削除しました。 次に、kubelet にサンプル API リクエストを送信して、動作するかどうかを確認しましょう。 $ curl -skv -X GET "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 はポート 10250 で実行されるため、curl コマンドを使用してすべての Pod を要求します。また、認証用の CA 証明書、クライアント証明書、キーも指定する必要があります。 これでチェックポイントを作成できます。 $ curl -sk -X POST "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-12T10:28:13Z.tar"]} # Check the directory: $ ls -l /var/lib/kubelet/checkpoints/ total 3840 -rw------- 1 root root 3931136 Nov 12 10:28 checkpoint-webserver_default-webserver-2022-11-12T10:28:13Z.tar # Verify that original container is still running: $ crictl ps --name webserver CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD 880ee7ddff7f3 docker.io/library/nginx@sha256:... 48 seconds ago Running webserver 0 d584446dd8d5e webserver チェックポイント API は、.../checkpoint/${NAMESPACE}/${POD}/${CONTAINER} にあります。ここでは、先ほど作成した Pod を使用します。このリクエストは、/var/lib/kubelet/checkpoints/checkpoint-<pod>_<namespace>-<container>-<timestamp>.tar にアーカイブを作成します。 上記の curl を実行すると、次のようなエラーが表示される場合があります。 checkpointing of default/webserver/webserver failed (CheckpointContainer is only supported in the CRI v1 runtime API) # or checkpointing of default/webserver/webserver failed (rpc error: code = Unknown desc = checkpoint/restore support not available) これは、コンテナがチェックポイント サポート付きで実行されていないか、正しく有効化されていないことを意味します。 分析するチェックポイント コンテナ アーカイブが作成されたので、その内容を確認してみましょう。 $ cd /var/lib/kubelet/checkpoints/ # Rename because "tar" doesn't like ":" in names $ mv "checkpoint-webserver_default-webserver-2022-11-12T10:28:13Z.tar" webserver.tar # View contents: $ tar --exclude="*/*" -tf webserver.tar dump.log checkpoint/ config.dump spec.dump rootfs-diff.tar io.kubernetes.cri-o.LogPath # Extract: $ tar -xf checkpoint-webserver_default-webserver-2022-09-04T10:15:37Z.tar $ ls checkpoint/ cgroup.img fdinfo-4.img ids-31.img mountpoints-13.img pages-2.img tmpfs-dev-139.tar.gz.img core-1.img files.img inventory.img netns-10.img pages-3.img tmpfs-dev-140.tar.gz.img core-30.img fs-1.img ipcns-var-11.img pagemap-1.img pages-4.img tmpfs-dev-141.tar.gz.img core-31.img fs-30.img memfd.img pagemap-30.img pstree.img tmpfs-dev-142.tar.gz.img descriptors.json fs-31.img mm-1.img pagemap-31.img seccomp.img utsns-12.img fdinfo-2.img ids-1.img mm-30.img pagemap-shmem-94060.img timens-0.img fdinfo-3.img ids-30.img mm-31.img pages-1.img tmpfs-dev-136.tar.gz.img $ cat config.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-12T10:27:56.460946241Z" } $ tar -tf rootfs-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/ 分析のために実行中の Pod/コンテナが必要ない場合は、上記のファイルの一部を抽出して読み取ると、必要な情報が得られる可能性があります。 回復するチェックポイント API は現在デバッグ分析に重点を置いていますが、アーカイブからポッド/コンテナを復元するためにも使用できます。最も簡単な方法は、チェックポイント アーカイブからイメージを作成することです。 FROM scratch # Need to use ADD because it extracts archives ADD webserver.tar . ここでは、空の(スクラッチ)イメージを使用し、それにアーカイブ ファイルを追加します。 ADD コマンドはアーカイブ ファイルを自動的に解凍するため、ここで必要です。次に、docker または buildah を使用してビルドします。 $ cd /var/lib/kubelet/checkpoints/ # Or docker build ... $ buildah bud \ --annotatinotallow=io.kubernetes.cri-o.annotations.checkpoint.name=webserver \ -t restore-webserver:latest \ Dockerfile . $ buildah push localhost/restore-webserver:latest docker.io/martinheinz/restore-webserver:latest 上記では、コンテナの生の人間が判読できる名前を記述する注釈も追加し、Kubernetes がプルできるようにそれをリポジトリにプッシュしました。最後に、先ほどプッシュしたイメージを指定して 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 アドレスにアクセスします。 $ kubectl expose pod restore-webserver --port=80 --target-port=80 $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 14m restore-webserver ClusterIP 10.104.30.90 <none> 80/TCP 17s $ curl http://10.104.30.90 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ... </html> 動作し、実行中の Pod を停止せずに正常にバックアップおよび復元できたことがわかります。 要約するKubernetes のチェックポイント機能は、コンテナ化されたアプリケーションのフォールト トレランスと回復力を高める強力なツールです。適切に計画されたチェックポイント戦略を実装することで、ダウンタイムを最小限に抑え、リソースの使用率を向上させ、アプリケーションの移行を簡素化できます。 アドバンテージ- 強化されたフォールト トレランス - チェックポイントにより、障害発生時にアプリケーションを最後の既知のチェックポイントから回復できるため、ダウンタイムが短縮され、アプリケーションの高可用性が維持されます。
- 移行の簡素化 - チェックポイント機能により、実行中のアプリケーションを別のホストに簡単に移動できます。アプリケーションの状態を保存することで、進行状況を失ったり中断したりすることなく、アプリケーションを別のノードに移行できます。アプリケーションのウォームアップに長い時間がかかる場合は、この機能を利用できます。これにより、アプリケーションの起動時間が大幅に短縮されます。
- スケーラビリティの向上 - チェックポイント機能を使用すると、変動する需要に合わせてアプリケーションを簡単に拡張できます。 1 つのノードが過負荷になった場合、より多くのリソースを持つ別のノードにアプリケーションを移行して、最適なパフォーマンスを確保できます。
- 効率的なリソース使用 - チェックポイントを使用すると、長時間実行されるアプリケーションを一時停止し、他のタスクのためにリソースを解放できます。アプリケーションが再度必要になった場合は、チェックポイントから復元できます。
Kubernetes チェックポイントのベストプラクティス- チェックポイントを定期的に作成する – 障害発生時のデータ損失を最小限に抑えるために、アプリケーションの必要に応じてチェックポイントを定期的に作成します。
- リソースの監視と管理 - チェックポイント機能は、特にメモリなど、大量のシステム リソースを消費する可能性があります。クラスターのリソース使用状況を監視し、パフォーマンスの問題を回避するために必要に応じてチェックポイント戦略を調整します。
- チェックポイント戦略をテストする – チェックポイント プロセスを定期的にテストして、期待どおりに動作し、障害が発生した場合にアプリケーションを回復できることを確認します。
- 自動チェックポイント管理 - cron ジョブや Kubernetes Operators などの自動化ツールを使用して、事前に決定されたスケジュールでチェックポイントを作成および管理し、アプリケーションが常に保護されるようにします。
参照ドキュメント- https://martinheinz.dev/blog/85。
- https://faun.pub/kubernetes-checkpointing-a-definitive-guide-33dd1a0310f6。
- https://github.com/containerd/containerd/pull/6965。
- https://github.com/MartinHeinz/kubeadm-vagrant-playground/tree/container-checkpoint-api。
|