クラスターの状態の災害復旧バックアップを実行する必要がある。
適切なTLS証明書(--cacert、--cert、--key)とエンドポイントを使用して、`etcdctl snapshot save`を実行する。
理由: etcdはクラスター全体の状態を保存する。直接スナップショットを取ることが、バックアップの標準的な方法である。kubeadmクラスターではTLSが有効になっているため、`etcdctl`が認証するには証明書が必須となる。
CNCF Certified Kubernetes Administrator
最終確認:2026年5月
CKA 試験で問われるアーキテクチャパターンのスキャン可能なリファレンス。上から順に読むか、セクションへジャンプ。
クラスターの状態の災害復旧バックアップを実行する必要がある。
適切なTLS証明書(--cacert、--cert、--key)とエンドポイントを使用して、`etcdctl snapshot save`を実行する。
理由: etcdはクラスター全体の状態を保存する。直接スナップショットを取ることが、バックアップの標準的な方法である。kubeadmクラスターではTLSが有効になっているため、`etcdctl`が認証するには証明書が必須となる。
災害復旧バックアップからクラスターを復元する。
新しいデータディレクトリに`etcdctl snapshot restore`を使用する。その後、`etcd.yaml`静的Podマニフェストを更新して、`--data-dir`ボリュームマウントを新しい場所を指すようにし、kubeletを再起動する。
理由: 復元すると新しいデータディレクトリが作成される。静的Podマニフェストは、この新しいデータを使用するように更新する必要がある。そうしないと、etcdは古い(または空の)データディレクトリで起動する。
kubeadmで管理されているクラスターのバージョンアップグレードを実行する。
1. コントロールプレーンで: `kubeadm`をアップグレードし、`kubeadm upgrade plan`を実行し、その後`kubeadm upgrade apply`を実行する。 2. 各ワーカーノードで: `kubectl drain`、`kubelet`をアップグレードし、kubeletサービスを再起動し、`kubectl uncordon`を実行する。
理由: このプロセスは多段階で順次実行される。`kubeadm`はコントロールプレーンコンポーネントのみをアップグレードする。`kubelet`は各ノードで手動でアップグレードする必要がある。ノードをドレインすることで、メンテナンス前にワークロードが安全に退避されることを保証する。
クラスター証明書が期限切れになるため、確認または更新が必要である。
`kubeadm certs check-expiration`を使用して有効期限を表示する。`kubeadm certs renew all`(または特定のコンポーネントの場合)を使用して証明書を更新する。更新後、コントロールプレーンのPodを再起動する。
理由: Kubeadmで生成された証明書は1年間の有効期間を持つ。更新は一般的なメンテナンス作業である。新しい証明書をロードするためには、コントロールプレーンコンポーネントを再起動する必要がある。
コントロールプレーンコンポーネント(例: APIサーバー)の構成または再起動が必要である。
`/etc/kubernetes/manifests/`にあるコンポーネントのマニフェストを修正する。ノード上のkubeletは変更を自動的に検出し、Podを再起動する。
理由: kubeadmのコントロールプレーンコンポーネントは、APIサーバーではなくkubeletによって直接管理される静的Podとして実行される。すべての管理は、監視対象ディレクトリ内のマニフェストファイルを介して行われる。
ユーザーまたはアプリケーションのアクセス制御を定義する。
Namespaceスコープのパーミッションには`Role`と`RoleBinding`を使用する。クラスター全体のパーミッションには`ClusterRole`と`ClusterRoleBinding`を使用する。
理由: これはRBACにおける基本的な分離である。Roleは常にNamespaceに紐付けられるが、ClusterRoleはNamespaceに属さないリソース(ノードなど)や、すべてのNamespaceにわたるリソースへのアクセスを許可できる。
サービスアカウントがすべてのNamespaceにわたるリソースにアクセスする必要がある。
パーミッションを定義する`ClusterRole`を作成する。そのClusterRoleを特定の`ServiceAccount`に付与するために`ClusterRoleBinding`を作成する。
理由: ServiceAccountはNamespaceに属するが、ClusterRoleBindingを使用するとクラスター全体のパーミッションを付与できる。`RoleBinding`は、そのRoleBinding自身のNamespace内のパーミッションのみを付与する。
クラウドロードバランサーなしで、アプリケーションを外部トラフィックに公開する。
`type: NodePort`のServiceを使用する。これにより、各ノードのIPアドレス上の静的ポート(デフォルト範囲: 30000-32767)でサービスが公開される。
理由: NodePortは、外部トラフィックをクラスターに取り込むための簡単な方法である。`type: LoadBalancer`と比較して、コストが低くプラットフォームに依存しないが、クライアントがノードIPを知っている必要がある。
単一のIPアドレスの下で、ホストベースまたはパスベースのルーティングを使用して複数のHTTP/Sサービスを公開する。
Ingress Controller(例: NGINX)をデプロイする。ホスト/パスからバックエンド`Services`へのルーティングルールを定義する`Ingress`リソースを作成する。
理由: IngressはL7ルーティングのための標準的なKubernetesリソースである。ルーティングロジックを実際に実装するには、個別のコントローラーが必要となる。これにより、ルーティングルールとプロキシ実装が分離される。
デフォルトですべてのイングレストラフィックを拒否することで、Namespaceを保護する。
すべてのPodを選択し(`podSelector: {}`)、空のイングレスルール(`ingress: []`)を指定する`NetworkPolicy`を作成する。
理由: 一度いずれかのNetworkPolicyによってPodが選択されると、明示的に許可されていないすべてのトラフィックは拒否される。空のイングレスルールを持つすべてのPodを選択するポリシーは、Namespaceに対して実質的に「すべて拒否」のファイアウォールを作成する。
「フロントエンド」Namespace内のPodが「バックエンド」Namespace内のPodにアクセスできるようにする。
「バックエンド」NamespaceでNetworkPolicyを作成する。`ingress.from`ルールで、`namespaceSelector`を使用して「フロントエンド」`Namespace`リソースのラベルと一致させる。
理由: `podSelector`はポリシー自身のNamespace内でのみ機能する。他のNamespaceからのトラフィックを許可するには、`namespaceSelector`を使用する必要がある。これには、`Namespace`オブジェクト自体にラベルを付ける必要がある。
アプリケーションがクラスター内の別のサービスに接続する必要がある。
サービスの内部DNS名: `<service-name>.<namespace>.svc.cluster.local`を使用する。同じNamespace内にある場合は、`<service-name>`で十分である。
理由: KubernetesはCoreDNSを介して安定したDNSベースのサービスディスカバリを提供する。これにより、アプリケーションは一時的なPod IPから分離される。
ステートフルなアプリケーション(例: データベースレプリカセット)が、各Podに直接的なネットワーク識別子を必要とする。
`StatefulSet`用にヘッドレス`Service` (`clusterIP: None`) を作成する。これにより、各Podに一意のDNS Aレコード(例: `pod-0.my-service.my-ns...`)が提供される。
理由: ヘッドレスサービスはロードバランシングを行わない。代わりに、各PodのDNSレコードを提供し、クライアントが特定のインスタンスに接続できるようにする。これは、ステートフルシステムにおけるリーダー選出やピアディスカバリにとって重要である。
外部に公開されているサービスが、ログ記録やIPベースのフィルタリングのために元のクライアントIPアドレスを必要とする。
`NodePort`または`LoadBalancer` Serviceで`externalTrafficPolicy: Local`を設定する。
理由: デフォルトの`Cluster`ポリシーはSNATによってクライアントIPを隠蔽する。`Local`は、トラフィックを受信したノード上のPodにのみトラフィックをルーティングすることで、この余分なネットワークホップを回避し、送信元IPを保持する。
パフォーマンスまたは高可用性のために、Podを同じ場所に配置したり、離して配置したりする。
`podAffinity`を使用して、特定の他のPodと同じノード/ゾーンにPodをスケジュールする。`podAntiAffinity`を使用して、それらを一緒にスケジュールするのを避ける。
理由: これにより、ノードレベルのアフィニティよりも高度なスケジューリング制御が可能になる。アンチアフィニティと`requiredDuringScheduling...`は、HAのためにサービスのレプリカをノードまたはゾーンに分散させる上で非常に重要である。
特定のワークロードにノードを割り当てる、または特定のワークロードがノード上で実行されないようにする。
ノードに`taint`を適用し(例: `gpu=true:NoSchedule`)、そのノードで実行を許可されるPodに一致する`toleration`を追加する。
理由: TaintはPodを拒否し、TolerationはPodを許可する。これはノードを専用化するための主要なメカニズムである。`NoExecute`エフェクトは、Tolerationを持たないすでに実行中のPodを退避させる。
クラスター内のすべてのノードに監視またはログ記録エージェントをデプロイする。
`DaemonSet`を使用する。これにより、スケジューリング基準に一致する各ノードでPodのコピーが実行されることが保証される。
理由: DaemonSetはこの目的に特化して設計されている。新しいノードに自動的にデプロイされ、ノードレベルのPod管理を処理する。これはDeploymentでは困難である。
一度限りのバッチタスク、または定期的にスケジュールされるタスクを実行する。
一度実行して完了するタスクには`Job`を使用する。定期的なスケジュール(例: 夜間バックアップ)でJobを作成するには`CronJob`を使用する。
理由: Jobは、指定された数の完了までPodが実行されることを保証する。CronJobは、cronスケジュールに基づいてJobを管理する上位レベルのコントローラーである。
アプリケーションをゼロダウンタイムで新しいバージョンに更新する。
デフォルトの`RollingUpdate`ストラテジーを持つ`Deployment`を使用する。`maxSurge`と`maxUnavailable`を設定して、更新速度と可用性を制御する。
理由: ローリングアップデートは古いPodを新しいPodに徐々に置き換え、サービスが利用可能であることを保証する。`maxUnavailable`は最小限のPodが稼働していることを保証し、`maxSurge`はデプロイを高速化するために必要なレプリカ数を超えてPodを一時的に増やすことを許可する。
Podが保証されたリソースを取得し、ノード上で過剰なリソースを消費しないようにする。
`resources.requests` (CPU/メモリ) を設定して、スケジューリングの最小値を保証する。`resources.limits`を設定して、コンテナが一定量を超えないようにする。
理由: リクエストはスケジューラーによって配置とリソース保証のために使用される。制限はkubeletとコンテナランタイムによって強制され、メモリ制限を超えるとOOMKillが発生する。
安定した一意のネットワーク識別子とレプリカごとの永続ストレージを必要とするステートフルなアプリケーションをデプロイする。
`volumeClaimTemplate`を持つ`StatefulSet`を使用する。これにより、各Podに一意の`PersistentVolumeClaim`が作成され、再起動時にデータが同じPodの識別子に再アタッチされることが保証される。
理由: StatefulSetは安定したPod名(例: `web-0`、`web-1`)と、各Podに一意の永続PVCを提供する。これは、安定した識別子とストレージに依存するアプリケーションにとって不可欠である。
ボリュームを事前にプロビジョニングすることなく、アプリケーションに永続ストレージを提供する。
ストレージプロビジョナーを定義する`StorageClass`を作成する。次に、そのクラスからストレージを要求する`PersistentVolumeClaim` (PVC) を作成する。`PersistentVolume` (PV) は動的にプロビジョニングされる。
理由: これにより、アプリケーションと基盤となるストレージインフラストラクチャが分離される。開発者はPVCを介してストレージを要求し、クラスター管理者はStorageClassを介してそのストレージがどのようにプロビジョニングされるかを定義する。
Persistent Volumeのクレームが削除された後、そのボリュームがどうなるかを制御する。
PVまたはStorageClassで`persistentVolumeReclaimPolicy`を設定する。`Delete`は基盤となるストレージを自動的に削除する。`Retain`はボリュームとデータをそのまま残し、手動でのクリーンアップが必要となる。
理由: `Retain`は偶発的なデータ損失を防ぐため、本番データにとって最も安全なオプションである。`Delete`は一時的または開発環境に便利である。デフォルトはプロビジョナーに依存する。
ボリュームがPodによってどのようにマウントできるかを定義する。
`accessModes`を使用する: `ReadWriteOnce` (RWO) はシングルノードの読み書き用、`ReadOnlyMany` (ROX) はマルチノードの読み取り専用用、`ReadWriteMany` (RWX) はマルチノードの読み書き用。
理由: アクセスモードは基盤となるストレージプロバイダーによってサポートされている必要がある。アプリケーションの要件(例: RWXが必要)とストレージの機能(RWOのみサポート)の不一致は、Pending状態のPVCの一般的な原因である。
Podに設定ファイルまたは機密データを注入する。
`ConfigMap`または`Secret`をボリュームとしてマウントする。データオブジェクト内の各キーは、マウントパス内のファイルになる。
理由: これはPodに構成を提供する標準的な方法である。構成をKubernetesオブジェクトとして管理し、Podイメージとは独立して更新できる。
アプリケーションが既存のPersistent Volumeにより多くのストレージ容量を必要とする。
`StorageClass`に`allowVolumeExpansion: true`が設定されていることを確認する。`PVC`を編集して、`spec.resources.requests.storage`でより大きなサイズを要求する。
理由: ボリューム拡張はオプトイン機能である。StorageClassが明示的に許可し、基盤となるCSIドライバーがそれをサポートしている必要がある。ファイルシステムのリサイズのためにPodの再起動が必要になる場合がある。
Podが`Pending`状態のままスケジュールされない。
`kubectl describe pod <pod-name>`を実行する。スケジューラーからのメッセージについて`Events`セクションを確認する。
理由: `describe`コマンドはこれのための主要なツールである。そこには「Insufficient cpu/memory」、「node(s) had taints the pod didn't tolerate」、または「didn't match node selector」のような理由が表示される。
Podが繰り返し起動と失敗を繰り返し、`CrashLoopBackOff`ステータスになっている。
1. 失敗したコンテナのログを見るために`kubectl logs <pod-name> --previous`を実行する。 2. 終了コードと理由を確認するために`kubectl describe pod <pod-name>`を実行する。
理由: `CrashLoopBackOff`は、コンテナ内のアプリケーションが終了していることを意味する。現在のコンテナがまだ有用なログを出力していない可能性があるため、以前のインスタンスのログ(`--previous`)が重要である。終了コードもエラーの種類を示すことができる。
Podが`ImagePullBackOff`または`ErrImagePull`ステータスで起動に失敗する。
イベントメッセージを見るために`kubectl describe pod <pod-name>`を実行する。イメージ名とタグが正しいことを確認する。プライベートレジストリの場合、`imagePullSecrets`が設定されており、シークレットが有効であることを確認する。
理由: これはレジストリまたはイメージ名の問題であり、アプリケーションの問題ではない。一般的な原因としては、タイプミス、不正確なタグ、またはプライベートレジストリでの認証失敗が挙げられる。
ノードが`NotReady`ステータスになっている。
影響を受けているノードにSSHで接続する。`systemctl status kubelet`でkubeletサービスのステータスを確認する。`journalctl -u kubelet`でそのログを表示する。
理由: `kubelet`はノードのヘルスレポートを担当するエージェントである。ダウンしているか、APIサーバーと通信できない場合、ノードはNotReadyとマークされる。そのログが最初に確認すべき場所である。
サービスは存在するが、トラフィックがバックエンドのPodに到達しない。
1. `kubectl describe svc <service-name>`を実行し、`Selector`がPodのラベルと一致していることを確認する。 2. `kubectl get endpoints <service-name>`を実行し、正しいPod IPがリストされていることを確認する。一致しない場合、ラベルがミスマッチしている。
理由: ServiceとPod間のリンクはラベルセレクターである。セレクターが間違っているか、Podに適切なラベルがない場合、Endpointsオブジェクトは空になり、サービスはトラフィックをルーティングする場所がなくなる。
Podがサービス名または外部ホスト名を解決できない。
1. `kube-system`内でCoreDNSのPodが実行されているか確認する。 2. CoreDNSのログを確認する。 3. デバッグPod(例: `busybox`)を実行し、`nslookup`を使用してクラスター内からの解決をテストする。
理由: DNSはクラスターの重要な依存関係である。障害は通常、CoreDNSデプロイメント自体、その設定(ConfigMap内)、またはUDP/TCPポート53でのDNSトラフィックをブロックするネットワークポリシーに起因する。
ノードをメンテナンスのためにオフラインにする必要がある。
まず、`kubectl cordon <node-name>`を実行して、そのノードをスケジュール不能としてマークする。次に、`kubectl drain <node-name> --ignore-daemonsets`を実行して、すべてのユーザーPodを安全に退避させる。
理由: `cordon`は新しいPodがスケジュールされるのを防ぐ。`drain`はPodDisruptionBudgetを尊重し、Podを正常に退避させる。`--ignore-daemonsets`はDaemonSetのPodは退避できないため、必要である。
どのPodまたはノードが最もCPUまたはメモリを消費しているかを特定する。
`kubectl top pods`と`kubectl top nodes`を使用する。これには、`metrics-server`がクラスターにデプロイされている必要がある。
理由: `kubectl top`は、リソース消費量の迅速かつリアルタイムなビューを提供し、リソースを大量に消費するアプリケーションやノードのリソース圧力を特定するために不可欠である。
Podが長期間`Terminating`状態のままで、削除されない。
`kubectl delete pod <pod-name> --grace-period=0 --force`を使用して、Podを強制的に削除する。
理由: これは、ファイナライザーが停止しているか、kubeletがリソースをクリーンアップできない場合に発生する可能性がある。強制削除はPodをAPIサーバーからすぐに削除するが、ノード上に孤立したリソースを残す可能性があるため、最後の手段として使用すべきである。