Certified Kubernetes Administrator (CKA) #27 フルスケール実技模擬試験: 17 のタスク + 解説
#1 試験環境 から #26 試験のコツ まで、全ドメインを一周しました。このシリーズの最終回は読む記事ではなく 解く記事 です。実際の CKA と同じく、全ドメインを統合した 17 のタスクを一か所に集めました。択一式ではなく、空のターミナルとノードの上で直接クラスターを作り、直す実技シナリオで、各タスクには配点が付いています。
推奨される制限時間は実際の試験と同じ 2 時間 です。合格ラインは 66% で、17 のタスクの配点を合算して採点します。あるタスクで詰まったら印を付けて飛ばし、配点が高く手に馴染んだタスクから点数を積み上げる運用が合格ラインを越える道です。
CKA はクラスターが複数あるため、コンテキスト切り替えを最初に 行う習慣が誤答を防ぎます。各タスクは指定されたコンテキストで解いて初めて採点され、ノードの中に入るタスクが多いので、SSH・systemctl・etcdctl の感覚も併せて必要です。各タスクは まず自力で最後まで解いてから 正解を開いてください。先に正解を読むと手が慣れません。
解き方 #
- kubeadm で立てたマルチノードクラスターで解くのが最も実戦に近いです。ローカルで難しければ、クラウド VM 2、3 台で control plane 1 台とワーカー 1 台を立てておきます。etcd バックアップ・リストアとノードのトラブルシューティングは、単一ノードの minikube では感覚が活きません。
- タスクごとに指定された コンテキストを先に切り替えます。このシリーズで繰り返したとおり、コンテキストの設定ミスは正解を書いても 0 点です。
k config use-context <問題で指定したコンテキスト>- SSH でノードに入るタスクがあるので、試験が提示するホスト名 (
node01など) で接続できるかを事前に確認します。ノードの上で root 権限が必要ならsudo -iで切り替えます。 - 17 個を 最後まで解いてから 正解を開いて一度に採点します。途中で正解を見ると実際の試験感覚が薄れます。#1 で整えた
alias k=kubectlとexport do="--dry-run=client -o yaml"のセットアップを先に適用すると時間を節約できます。
ドメイン分布 #
実際の CKA のドメイン比重に合わせて 17 のタスクを配置しました。Troubleshooting が 30% で最も大きいため、タスク数も最も多いです。
| # | ドメイン | タスク数 | タスク番号 |
|---|---|---|---|
| 1 | Cluster Architecture, Installation, Configuration | 5 | 1, 2, 3, 4, 5 |
| 2 | Workloads and Scheduling | 3 | 6, 7, 8 |
| 3 | Services and Networking | 3 | 9, 10, 11 |
| 4 | Storage | 2 | 12, 13 |
| 5 | Troubleshooting | 4 | 14, 15, 16, 17 |
配点はドメイン比重とタスクの難易度を反映し、合計 100 点としました。採点基準は記事末にまとめています。
タスク 1 (8 点): Cluster Architecture, Installation, Configuration #
コンテキスト cluster1 で実行中の etcd のスナップショットを /opt/etcd-backup.db に保存してください。control plane ノードに SSH で接続して作業し、etcd は static Pod として立ち上がっていて、証明書は /etc/kubernetes/pki/etcd の下にあります。
正解
control plane ノードに接続して root に切り替えた後、スナップショットを保存します。
ssh cluster1-controlplane
sudo -i
ETCDCTL_API=3 etcdctl snapshot save /opt/etcd-backup.db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key保存が終わったらスナップショットの状態を確認します。
ETCDCTL_API=3 etcdctl --write-out=table snapshot status /opt/etcd-backup.db解説: snapshot save はクライアント証明書で etcd に接続するため --cacert・--cert・--key の 3 つがすべて必要で、パスは etcd static Pod マニフェスト (/etc/kubernetes/manifests/etcd.yaml) の --cert-file・--key-file・--trusted-ca-file の値で確認できます。ETCDCTL_API=3 を外すと v2 API で動作してコマンドが失敗するのが最もよくある落とし穴です。
タスク 2 (8 点): Cluster Architecture, Installation, Configuration #
タスク 1 で作ったスナップショット /opt/etcd-backup.db を新しいデータディレクトリ /var/lib/etcd-restore にリストアし、etcd static Pod がこのディレクトリを使うようにマニフェストを修正してください。リストア後にクラスターが正常化するかを確認します。
正解
スナップショットを新しいディレクトリにリストアします。
ETCDCTL_API=3 etcdctl snapshot restore /opt/etcd-backup.db \
--data-dir=/var/lib/etcd-restoreetcd static Pod マニフェストで host パスを新しいディレクトリに変えます。
vim /etc/kubernetes/manifests/etcd.yaml volumes:
- name: etcd-data
hostPath:
path: /var/lib/etcd-restore
type: DirectoryOrCreatekubelet がマニフェストの変更を検知して etcd Pod を立て直すまで待った後、確認します。
crictl ps | grep etcd
k get nodes解説: snapshot restore は新しいデータディレクトリを作るだけで、etcd を再起動しません。実際の切り替えは、static Pod マニフェストの hostPath.path を新しいディレクトリに変えて、kubelet が etcd Pod を新しいデータで再生成させる段階で起こります。--data-dir の親パスの権限と、既存の etcd コンテナがしばらく落ちる点に注意します。
タスク 3 (8 点): Cluster Architecture, Installation, Configuration #
コンテキスト cluster1 の control plane とワーカーノードを v1.31.0 から v1.31.1 にアップグレードしてください。まず control plane をアップグレードした後、ワーカー node01 をアップグレードします。ワーカーのアップグレード中はワークロードを空にする必要があります。
正解
control plane ノードで kubeadm を上げた後、アップグレード計画を確認して適用します。
ssh cluster1-controlplane
sudo -i
apt-get update && apt-get install -y kubeadm=1.31.1-1.1
kubeadm upgrade plan
kubeadm upgrade apply v1.31.1control plane の kubelet と kubectl を上げた後、drain·uncordon で再起動します。
kubectl drain cluster1-controlplane --ignore-daemonsets
apt-get install -y kubelet=1.31.1-1.1 kubectl=1.31.1-1.1
systemctl daemon-reload && systemctl restart kubelet
kubectl uncordon cluster1-controlplaneワーカーは control plane から drain した後、ノードの上でアップグレードします。
kubectl drain node01 --ignore-daemonsets
ssh node01
sudo -i
apt-get update && apt-get install -y kubeadm=1.31.1-1.1
kubeadm upgrade node
apt-get install -y kubelet=1.31.1-1.1
systemctl daemon-reload && systemctl restart kubelet
exit
kubectl uncordon node01解説: control plane は kubeadm upgrade apply、ワーカーは kubeadm upgrade node を使うのが核心的な違いです。アップグレードの順序は kubeadm インストール → upgrade → kubelet・kubectl インストール → kubelet 再起動で、--ignore-daemonsets なしで drain すると DaemonSet Pod のせいで止まります。バージョンのジャンプはマイナーを 1 つずつだけ許可されます。
タスク 4 (8 点): Cluster Architecture, Installation, Configuration #
ネームスペース dev だけで動作する ServiceAccount deployer を作り、この ServiceAccount が dev の中で Deployment を作成・照会・修正・削除できるように RBAC を構成してください。権限が正しいかを kubectl auth can-i で検証します。
正解
ServiceAccount と Role、RoleBinding を作ります。
k -n dev create serviceaccount deployer
k -n dev create role deploy-manager \
--verb=create,get,list,update,delete \
--resource=deployments.apps
k -n dev create rolebinding deployer-binding \
--role=deploy-manager \
--serviceaccount=dev:deployer権限を検証します。
k -n dev auth can-i create deployments --as=system:serviceaccount:dev:deployer
k -n dev auth can-i delete deployments --as=system:serviceaccount:dev:deployer解説: Role はネームスペース限定の権限で、RoleBinding がその Role を主体 (ここでは ServiceAccount) に紐付けます。--resource=deployments.apps のように API グループまで明示しないと core グループとして扱われ、空のルールになることがあります。検証時の主体は system:serviceaccount:<ns>:<name> の形式で書く必要があり、両方のコマンドとも yes が出る必要があります。
タスク 5 (6 点): Cluster Architecture, Installation, Configuration #
/etc/kubernetes/pki/apiserver.crt 証明書の有効期限を確認し、kubeadm でクラスター証明書をすべて更新してください。更新後に有効期限が未来に変わったかを再確認します。
正解
control plane ノードで証明書の失効状況を確認します。
ssh cluster1-controlplane
sudo -i
kubeadm certs check-expiration特定の証明書の有効期限を直接見たい場合は openssl で確認します。
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -enddateすべての証明書を更新した後、control plane の static Pod を再起動します。
kubeadm certs renew all
systemctl restart kubelet解説: kubeadm certs check-expiration は各証明書と kubeconfig の有効期限を表で見せます。certs renew all は証明書ファイルだけを新たに発行するため、apiserver などの static Pod が新しい証明書を読むようにコンポーネントを再起動して初めて実際に反映されます。kubeadm は control plane のアップグレード時に証明書を自動更新するため、定期的なアップグレードが更新を兼ねることもあります。
タスク 6 (6 点): Workloads and Scheduling #
ネームスペース apps に fluentd ログ収集器をすべてのノードに正確に 1 つずつ立てる DaemonSet log-agent を作ってください。イメージは fluent/fluentd:v1.16 を使い、control plane ノードの taint のためにそこには立たなくてかまいません。
正解
dry-run で骨組みを作れない kind なので、マニフェストを直接書きます。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: log-agent
namespace: apps
spec:
selector:
matchLabels:
app: log-agent
template:
metadata:
labels:
app: log-agent
spec:
containers:
- name: fluentd
image: fluent/fluentd:v1.16k apply -f log-agent.yaml
k -n apps get ds log-agent解説: DaemonSet はワーカーノードごとに Pod を 1 つずつ配置し、replicas フィールドがありません。control plane ノードには通常 node-role.kubernetes.io/control-plane:NoSchedule taint があり、別途 toleration なしでは立たないため、「そこには立たなくてよい」という要求は toleration を追加しないことで満たされます。Deployment と違い、selector と template label が一致する必要があります。
タスク 7 (7 点): Workloads and Scheduling #
ワーカーノード node01 に gpu=true:NoSchedule taint を掛け、ネームスペース apps にこの taint に耐えつつ disktype=ssd ラベルがあるノードにだけスケジュールされる Pod ml-job (イメージ nginx) を作ってください。
正解
ノードに taint を掛け、ラベルがあるかを確認します。
k taint node node01 gpu=true:NoSchedule
k label node node01 disktype=ssdtoleration と nodeAffinity を持つ Pod を作ります。
apiVersion: v1
kind: Pod
metadata:
name: ml-job
namespace: apps
spec:
tolerations:
- key: gpu
operator: Equal
value: "true"
effect: NoSchedule
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: ml-job
image: nginxk apply -f ml-job.yaml
k -n apps get pod ml-job -o wide解説: taint はノードが Pod を押しのける仕組みで、toleration は Pod がその taint に耐えるという宣言です。toleration だけだと他のノードにも立つことがあるため、特定のノードに固定するには nodeAffinity か nodeSelector を併せて使う必要があります。toleration の value は引用符で文字列として置いて "true" の boolean 解釈エラーを避けます。
タスク 8 (7 点): Workloads and Scheduling #
ネームスペース data に StatefulSet cache を作ってください。イメージは redis:7、replicas は 3 で、headless Service cache で Pod に安定した DNS 名を付与してください。各 Pod は volumeClaimTemplates で 1Gi PVC を持ちます。
正解
headless Service と StatefulSet を一緒に定義します。
apiVersion: v1
kind: Service
metadata:
name: cache
namespace: data
spec:
clusterIP: None
selector:
app: cache
ports:
- port: 6379
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: cache
namespace: data
spec:
serviceName: cache
replicas: 3
selector:
matchLabels:
app: cache
template:
metadata:
labels:
app: cache
spec:
containers:
- name: redis
image: redis:7
ports:
- containerPort: 6379
volumeMounts:
- name: data
mountPath: /data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gik apply -f cache.yaml
k -n data get pods -l app=cache解説: StatefulSet は serviceName で headless Service (clusterIP: None) と結ばれて初めて cache-0.cache.data.svc.cluster.local の形の安定的な DNS を付与します。volumeClaimTemplates は Pod ごとに別々の PVC を自動生成し、Pod が再生成されても同じ PVC に再び付きます。Pod 名が 0 から順に付くのも Deployment との違いです。
タスク 9 (6 点): Services and Networking #
ネームスペース net に nginx イメージの Deployment web を replicas 2 で作り、クラスター外部からノードの 30080 ポートでアクセスできる NodePort Service web-np で公開してください。Service のポートは 80、ターゲットポートは 80 です。
正解
k -n net create deploy web --image=nginx --replicas=2
k -n net expose deploy web --name=web-np --type=NodePort --port=80 --target-port=80nodePort 値を 30080 に固定します。
k -n net patch svc web-np --type='json' \
-p='[{"op":"replace","path":"/spec/ports/0/nodePort","value":30080}]'解説: expose で NodePort を作ると nodePort は 30000〜32767 の範囲で自動割り当てされるため、特定の値に固定するには patch するか、dry-run の YAML に nodePort: 30080 を直接書いて apply します。検証は curl <ノード IP>:30080 で応答を確認します。
タスク 10 (6 点): Services and Networking #
ネームスペース net に Ingress web-ing を作ってください。ホスト web.example.com のパス / に入ってくるトラフィックをタスク 9 の Service web-np の 80 ポートにルーティングし、pathType は Prefix、ingressClassName は nginx を使ってください。
正解
k -n net create ingress web-ing \
--class=nginx \
--rule="web.example.com/*=web-np:80" $do > ing.yaml生成されたマニフェストは次のとおりです。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ing
namespace: net
spec:
ingressClassName: nginx
rules:
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-np
port:
number: 80k apply -f ing.yaml解説: create ingress の --rule は host/path=service:port の形式で、パス末尾の /* が pathType: Prefix に変換されます。--class=nginx を外すと ingressClassName が空になり、デフォルトの IngressClass がないクラスターではルーティングができません。実際の動作には ingress-nginx コントローラが必要ですが、採点はリソース定義の正確さを見ます。
タスク 11 (6 点): Services and Networking #
ネームスペース net に NetworkPolicy db-allow を作ってください。ラベル app=db を持つ Pod への ingress トラフィックを、同じネームスペースでラベル role=api を持つ Pod が TCP 5432 ポートでアクセスするときだけ許可し、それ以外の ingress はすべて遮断してください。
正解
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-allow
namespace: net
spec:
podSelector:
matchLabels:
app: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: api
ports:
- protocol: TCP
port: 5432k apply -f db-allow.yaml解説: podSelector はポリシーが適用される対象 Pod (app=db) を選び、ingress.from は許可する出発地 (role=api) を選びます。NetworkPolicy は 1 つの Pod に 1 つでも適用されると、明示されていないトラフィックはすべて遮断されるため、別途の deny-all なしでもそれ以外の ingress が塞がれます。from と ports を同じルールに置くと 2 つの条件の AND になり、Calico のようなポリシー対応 CNI でのみ強制されます。
タスク 12 (8 点): Storage #
ネームスペース storage にホストパス /mnt/data を使う 2Gi PersistentVolume pv-data (accessMode ReadWriteOnce、reclaimPolicy Retain) を作り、これに正確にバインドする 1Gi PVC pvc-data を作った後、この PVC を /usr/share/nginx/html にマウントする Pod pv-user (nginx) を作ってください。
正解
PV、PVC、Pod を順に定義します。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-data
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /mnt/data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-data
namespace: storage
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: pv-user
namespace: storage
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumes:
- name: data
persistentVolumeClaim:
claimName: pvc-datak apply -f pv.yaml
k -n storage get pvc pvc-data解説: PVC が PV にバインドされるには accessMode が同じで、PV の容量が PVC の要求以上である必要があります (2Gi ≥ 1Gi)。PV はクラスター全域のリソースなので namespace がなく、PVC と Pod は同じネームスペースにある必要があります。reclaimPolicy: Retain なら PVC を消しても PV のデータが残り、PV は Released 状態になります。
タスク 13 (6 点): Storage #
ネームスペース storage に動的プロビジョニング用の StorageClass fast を作ってください。provisioner は rancher.io/local-path、volumeBindingMode は WaitForFirstConsumer、allowVolumeExpansion は true です。続いてこの StorageClass で 3Gi PVC pvc-fast を作ってください。
正解
StorageClass と PVC を定義します。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: rancher.io/local-path
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-fast
namespace: storage
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast
resources:
requests:
storage: 3Gik apply -f sc.yaml
k -n storage get pvc pvc-fast解説: WaitForFirstConsumer は PVC を使う Pod がスケジュールされるまでボリュームの生成を遅らせるため、PVC だけ作ると Pending 状態にとどまるのが正常です。allowVolumeExpansion: true でなければ、後で PVC の resources.requests.storage を大きくしてオンライン拡張をすることができません。PVC に storageClassName を指定しないと、デフォルトの StorageClass が使われます。
タスク 14 (7 点): Troubleshooting #
コンテキスト cluster1 のワーカーノード node01 が NotReady 状態です。原因を診断し、ノードを Ready に戻してください。
正解
まずノードの状態と condition を確認します。
k get nodes
k describe node node01ノードに接続して kubelet の状態とログを見ます。
ssh node01
sudo -i
systemctl status kubelet
journalctl -u kubelet -ekubelet が止まっていれば再起動し、設定エラーならログが指すファイルを直してから再起動します。
systemctl enable --now kubelet
systemctl restart kubelet解説: NotReady の最もよくある原因は、kubelet サービスが死んだこと (systemctl restart kubelet)、kubeconfig・CA パスのエラー、ディスク・メモリの pressure です。describe node の Conditions と journalctl -u kubelet が原因を分け、kubelet が起動時に無効なら enable --now で起動時の自動開始まで点けておきます。control plane 側の問題ではなくノード自体を見るべきだという点が核心です。
タスク 15 (7 点): Troubleshooting #
コンテキスト cluster2 の control plane で kubectl が connection refused で応答しません。apiserver static Pod マニフェストが誤って修正されています。原因を見つけて直し、apiserver を正常化してください。
正解
control plane ノードに接続して apiserver コンテナの状態を見ます。
ssh cluster2-controlplane
sudo -i
crictl ps -a | grep kube-apiserver
crictl logs <apiserver-container-id>static Pod マニフェストを検討し、誤ったフィールド (例: 誤字のポート、誤った証明書パス、壊れたインデント) を直します。
vim /etc/kubernetes/manifests/kube-apiserver.yamlkubelet がマニフェストの変更を検知して apiserver Pod を立て直すまで待った後、確認します。
crictl ps | grep kube-apiserver
k get nodes解説: apiserver が立って初めて kubectl が動作するため、この状態では kubectl の代わりに crictl でコンテナログを直接読むのが核心です。static Pod はマニフェストファイルを直すと kubelet が自動的に再生成するため、ファイルをいったん別の場所に移してから戻すと強制再起動の効果が出ます。--etcd-servers のパスや証明書パスの誤字がよくある原因です。
タスク 16 (7 点): Troubleshooting #
ネームスペース apps の Service frontend に送る要求が応答しません。Pod はすべて Running ですが、Service の endpoint が空です。原因を診断し、トラフィックが Pod に届くように直してください。
正解
Service と endpoint、Pod のラベルを比較します。
k -n apps get svc frontend -o wide
k -n apps get endpoints frontend
k -n apps describe svc frontend
k -n apps get pods --show-labelsService の selector と Pod のラベルがずれていれば、selector を Pod のラベルに合わせて直します。
k -n apps patch svc frontend \
-p '{"spec":{"selector":{"app":"frontend"}}}'
k -n apps get endpoints frontend解説: endpoint が空だということは、Service の selector がどの Pod ラベルとも一致しないという信号です。Pod が Running でも selector がずれていると endpoint に登録されず、トラフィックが届きません。selector を直した後、get endpoints に Pod IP が埋まるかで検証し、ポート名・番号の不一致も併せて点検します。
タスク 17 (7 点): Troubleshooting #
ネームスペース apps の Pod report が CrashLoopBackOff 状態です。原因を診断し、最も最近に終了したコンテナの直前のログをファイル /tmp/report.log に保存した後、原因がメモリ不足 (OOMKilled) ならメモリ limit を 256Mi に上げて正常化してください。
正解
状態と終了原因を診断します。
k -n apps describe pod report
k -n apps logs report --previous > /tmp/report.logLast State が OOMKilled ならメモリ limit を上げます。Pod の resources は直接修正できないため、マニフェストを受け取って直してから再生成します。
k -n apps get pod report -o yaml > report.yaml resources:
limits:
memory: "256Mi"
requests:
memory: "128Mi"k -n apps delete pod report
k apply -f report.yaml解説: CrashLoopBackOff はコンテナが繰り返し終了する状態なので現在のログが空のことがあり、--previous (-p) で直前のコンテナのログを取得します。describe の Last State の Reason が OOMKilled なら、メモリ limit 不足が原因です。実行中の Pod の resources は不変なのでマニフェストを直して削除・再生成する必要があり、Deployment が管理する Pod なら Deployment 側の template を直します。
採点基準 #
各タスクの配点を合算して採点します。合計は 100 点で、66 点以上が合格圏 です。
| ドメイン | タスク・配点 | 小計 |
|---|---|---|
| Cluster Architecture, Installation, Configuration | 1(8) · 2(8) · 3(8) · 4(8) · 5(6) | 38 |
| Workloads and Scheduling | 6(6) · 7(7) · 8(7) | 20 |
| Services and Networking | 9(6) · 10(6) · 11(6) | 18 |
| Storage | 12(8) · 13(6) | 14 |
| Troubleshooting | 14(7) · 15(7) · 16(7) · 17(7) | 28 |
| 合計 | (合計) | 100 |
採点は実際の試験と同じく 成果物基準 です。コマンドをどう打ったかではなく、作られたリソースと復旧されたクラスターの状態が要件と一致するかを見ます。1 つのタスクの中でもラベル・ポート・パス・フィールドのような項目別に部分点が分かれるため、詰まる項目があっても埋められる部分は最後まで埋めるほうが点数に有利です。
ドメイン別の弱点復習 #
採点後、点数が低いドメインを下表の該当記事に戻って復習してください。
| ドメイン | 関連タスク | 復習する記事 |
|---|---|---|
| Cluster Architecture, Installation, Configuration | 1, 2, 3, 4, 5 | #6 · #7 · #8 · #9 |
| Workloads and Scheduling | 6, 7, 8 | #11 · #13 · #14 |
| Services and Networking | 9, 10, 11 | #18 · #19 · #20 |
| Storage | 12, 13 | #16 · #17 |
| Troubleshooting | 14, 15, 16, 17 | #22 · #23 · #24 · #25 |
特定のタスクで時間が足りなかったなら、ドメイン知識より手の速さの問題かもしれません。その場合は #1 セットアップ と #26 時間管理 を読み直し、同じ 17 のタスクを時間を計ってもう一度解いてください。etcd バックアップ・リストアとノードのトラブルシューティングは一度手に馴染むと、タスクあたりの所要時間が目に見えて減ります。
シリーズを終えて #
#1 の試験環境セットアップから出発し、control plane・ノード・kubeadm インストール・HA・アップグレード・etcd バックアップリストア・証明書・RBAC・ワークロード・スケジューリング・リソース・ストレージ・Service・Ingress・NetworkPolicy・トラブルシューティング 4 種まで、CKA の全ドメインを 27 編で通過しました。この模擬試験で 66 点を越えたなら、実際の試験会場でも十分に合格ラインを越えられる手ができています。おめでとうございます。
CKA がクラスター運用者の実技だったとすれば、次の段階はそのクラスターを安全に守る CKS (Certified Kubernetes Security Specialist) で、ここで磨いた etcd・証明書・RBAC・トラブルシューティングの感覚がそのまま足がかりになるので、合格の勢いを引き継いで次の実技に進まれることをおすすめします。