Skip to content
Published on

Kubernetes CKAD 認定試験 実践問題集(55問 + 実技シミュレーション10問)

Authors

CKAD試験概要

CKAD(Certified Kubernetes Application Developer)は、CNFCが提供するKubernetesアプリケーション開発者向けの実技重視の認定試験です。

項目内容
試験時間120分
問題数15-20問(実技形式)
合格基準66%以上
試験形式オンライン、監督付き
有効期間3年
Kubernetesバージョン最新安定版

ドメイン別出題比率

ドメイン比率
Application Design & Build20%
Application Deployment20%
Application Observability & Maintenance15%
Application Environment, Configuration & Security25%
Services & Networking20%

開発者視点のkubectlチートシート

# ConfigMap作成
kubectl create configmap app-config --from-literal=key=value
kubectl create configmap app-config --from-file=config.properties
kubectl create configmap app-config --from-env-file=.env

# Secret作成
kubectl create secret generic db-secret --from-literal=password=mypassword
kubectl create secret docker-registry regcred \
  --docker-server=REGISTRY \
  --docker-username=USER \
  --docker-password=PASS

# ロールアウト管理
kubectl rollout status deployment myapp
kubectl rollout history deployment myapp
kubectl rollout undo deployment myapp
kubectl rollout pause deployment myapp
kubectl rollout resume deployment myapp

# リソース設定
kubectl set resources deployment myapp --limits=cpu=200m,memory=512Mi
kubectl set resources deployment myapp --requests=cpu=100m,memory=256Mi

# 環境変数設定
kubectl set env deployment myapp ENV=production
kubectl set env deployment myapp --from=configmap/app-config

# ラベル管理
kubectl label pod mypod env=production
kubectl label pod mypod env-   # ラベル削除

# エフェメラルコンテナ(デバッグ用)
kubectl debug -it POD_NAME --image=busybox --target=CONTAINER_NAME

# Helmの基本コマンド
helm repo add stable https://charts.helm.sh/stable
helm install myrelease stable/nginx
helm upgrade myrelease stable/nginx --set image.tag=latest
helm rollback myrelease 1
helm uninstall myrelease
helm list

# dry-runでYAML生成
kubectl create deployment myapp --image=nginx --dry-run=client -o yaml > deploy.yaml
kubectl run mypod --image=nginx --dry-run=client -o yaml > pod.yaml

選択問題(Q1 〜 Q55)

ドメイン1: Application Design & Build

Q1. SidecarパターンとAmbassadorパターンの違いは?

A) Sidecarはメインコンテナを置き換え、Ambassadorは補助機能を提供する B) Sidecarはメインコンテナの機能を拡張(ロギング、監視)し、Ambassadorは外部サービスとの通信をプロキシする C) 2つのパターンは同一である D) AmbassadorはKubernetes 1.25で削除された

答え: B

解説: Sidecarパターンはメインコンテナと並行してログ収集、監視、セキュリティ機能を追加します。Ambassadorパターンはメインコンテナが外部サービスと通信する際の中間プロキシとして機能します。Adapterパターンはメインコンテナの出力形式を変換します。

Q2. Init Containerの特徴として正しいものは?

A) メインコンテナと同時に実行される B) メインコンテナが起動する前に順番に実行され、完了後にメインコンテナが起動する C) 失敗するとPodはRunning状態を維持する D) 無期限に実行される

答え: B

解説: Init Containerはメインコンテナが起動する前に順番に実行されます。すべてのInit Containerが正常完了した後にのみメインコンテナが起動します。Init Containerが失敗するとPodのrestartPolicyに従って再起動されます。DBマイグレーション、設定ファイルの準備などに活用されます。

Q3. JobのbackoffLimitフィールドの役割は?

A) Jobの最大実行時間を指定する B) Job失敗時の最大リトライ回数を指定する C) 同時実行Pod数を制限する D) 完了したJobを自動削除する

答え: B

解説: backoffLimitはJob失敗時の最大リトライ回数です。デフォルト値は6です。リトライ間隔は指数的に増加します(10秒、20秒、40秒...)。activeDeadlineSecondsはJobの最大実行時間を制限します。

Q4. Dockerfileでマルチステージビルドの利点は?

A) ビルド速度を上げる B) 最終イメージサイズを削減し、不要なビルドツールを除外できる C) キャッシングを無効化する D) 複数のOSで同時にビルドできる

答え: B

解説: マルチステージビルドはビルド環境(コンパイラ、ビルドツール)と実行環境を分離します。最初のステージでビルドアーティファクトを生成し、2番目のステージ(軽量ベースイメージ)でアーティファクトのみをコピーします。これによりイメージサイズを大幅に削減できます。

Q5. CronJobのconcurrencyPolicy: Forbidの動作は?

A) 前のJobが完了していなくても新しいJobを同時実行する B) 前のJobがまだ実行中の場合、新しいJobをスキップする C) 前のJobを強制終了して新しいJobを開始する D) すべてのJobをキューに保存する

答え: B

解説: concurrencyPolicy: Forbidは前のJobがまだ実行中の場合、新しいJob作成をスキップします。Allow(デフォルト)は同時実行を許可します。Replaceは実行中のJobを終了して新しいJobを開始します。

Q6. レイヤーキャッシングを最適化するためのDockerfile作成方法は?

A) すべてのRUNコマンドを1つにまとめる B) 頻繁に変更されるコマンド(COPYソースコード)をDockerfileの下部に配置する C) FROMコマンドを複数回使用する D) LABELコマンドを多く使用する

答え: B

解説: Dockerレイヤーキャッシング最適化には、頻繁に変更されないコマンド(パッケージインストールなど)を上部に、頻繁に変更されるコマンド(ソースコードのコピー)を下部に配置します。これにより、ソースコード変更時にパッケージレイヤーキャッシュを再利用できます。

Q7. JobとCronJobで使うべきrestartPolicyの値は?

A) Always — Jobに推奨 B) OnFailureまたはNever — JobとCronJobで使用 C) OnSuccess — Jobでのみ使用可能 D) Never — すべての場合に推奨

答え: B

解説: JobとCronJobのPodにはOnFailure(失敗時に再起動)またはNever(再起動なし)を使用する必要があります。AlwaysはDeployment、DaemonSetなどの長時間実行ワークロードに使用します。JobのPodにAlwaysを使用するとJobが完了しても再起動し続けます。

Q8. StatefulSetとDeploymentの主な違いは?

A) StatefulSetはより多くのレプリカをサポートする B) StatefulSetは順序付きPod名、安定したネットワークID、Pod別個別PVCを提供する C) Deploymentはステートフルアプリに向いている D) StatefulSetはローリングアップデートをサポートしない

答え: B

解説: StatefulSetはステートフルアプリケーション向けに設計されています: 1) 予測可能なPod名(app-0、app-1)、2) 安定したネットワークID(ヘッドレスサービス経由)、3) Pod別独立PVC(volumeClaimTemplates)、4) 順序付きデプロイ/更新/削除。データベース、Kafka、ZooKeeperなどに適しています。

ドメイン2: Application Deployment

Q9. DeploymentのRecreate戦略とRollingUpdate戦略の違いは?

A) Recreateはより多くのリソースを使用する B) Recreateはすべての既存Podを削除してから新しいPodを作成(ダウンタイムあり)、RollingUpdateは段階的に置き換え(ダウンタイムなし) C) RollingUpdateは大規模クラスターでのみ可能 D) どちらも同じように動作する

答え: B

解説: Recreateは現在のReplicaSetのPodをすべて削除してから新しいPodを作成します。ダウンタイムが発生しますが、古いバージョンと新しいバージョンが同時に実行されません。RollingUpdateは段階的にPodを置き換えてサービス中断なしにデプロイします。

Q10. kubectl rollout pausekubectl rollout resumeの目的は?

A) Podを一時停止/再開する B) ロールアウトを一時中断して一部のPodのみ新バージョンで実行してカナリアテストを行い、問題なければ再開するカナリアデプロイ方式 C) Deploymentを完全に停止する D) 自動スケーリングを一時停止する

答え: B

解説: kubectl rollout pause deploymentは進行中のロールアウトを一時中断します。これにより一部のPodのみ新バージョンに切り替えられた状態でカナリアテストを実行できます。問題なければkubectl rollout resumeで残りの更新を続けます。

Q11. Helmチャートのvalues.yamlファイルの役割は?

A) Helmチャートの必須コンポーネントのリスト B) チャートデプロイ時に使用されるデフォルト設定値を定義する C) Kubernetesマニフェストファイル D) Helmリポジトリの認証情報

答え: B

解説: values.yamlはHelmチャートのデフォルト設定値を定義します。helm installhelm upgrade時に--setまたは-f custom-values.yamlで上書きできます。テンプレートファイルで{{ .Values.image.tag }}のように参照します。

Q12. Kustomizeのoverlayとbaseはどのような関係か?

A) overlayはbaseと同一ファイル B) baseは共通設定を、overlayは環境別(dev/staging/prod)の変更を定義する C) overlayはbaseを完全に置き換える D) Kustomizeはoverlayをサポートしない

答え: B

解説: Kustomizeのbaseは共通のKubernetesリソース定義を含みます。overlayはbaseを参照して環境別のパッチや変更を追加します。kubectl apply -k overlays/production/のように使用します。Helmチャートなしでマルチ環境デプロイが可能です。

Q13. kubectl set imageで特定のコンテナイメージのみを更新する方法は?

A) kubectl set image deployment/myapp *=nginx:1.26 B) kubectl set image deployment/myapp nginx=nginx:1.26 C) kubectl update image deployment/myapp nginx:1.26 D) kubectl patch image deployment/myapp nginx=nginx:1.26

答え: B

解説: kubectl set image deployment/DEPLOY_NAME CONTAINER_NAME=IMAGE:TAGの形式で特定コンテナのみ更新します。例: kubectl set image deployment/myapp nginx=nginx:1.26。複数コンテナを同時に更新する場合はスペース区切りで列挙します。

Q14. DeploymentのrevisionHistoryLimitフィールドの機能は?

A) 保持するロールアウト履歴(旧ReplicaSet)の数を指定する B) 最大Pod数を制限する C) 自動ロールバック回数を制限する D) 旧バージョン保持期間を時間で指定する

答え: A

解説: revisionHistoryLimitはDeploymentが保持する旧ReplicaSetの数を指定します。デフォルト値は10です。ロールバック可能な旧バージョン数と直接関連します。0に設定すると旧ReplicaSetをすぐに削除します。

Q15. Helmリリースを以前のバージョンにロールバックするコマンドは?

A) helm undo myrelease B) helm rollback myrelease REVISION C) helm revert myrelease D) helm restore myrelease

答え: B

解説: helm rollback myrelease REVISION_NUMBERで特定のリビジョンにロールバックします。helm history myreleaseでリリース履歴とリビジョン番号を確認できます。リビジョンを指定しない場合は直近の前バージョンにロールバックされます。

Q16. Blue/GreenデプロイをKubernetesで実装する方法は?

A) DeploymentのRecreate戦略を使用する B) 2つのDeployment(blue/green)を運用し、ServiceのselectorをSwitchしてトラフィックを切り替える C) StatefulSetで実装する D) DaemonSetで実装する

答え: B

解説: Blue/Greenデプロイ: 1) blueデプロイメント(現在の本番)とgreenデプロイメント(新バージョン)を同時に運用、2) greenのテスト完了後、Serviceのselectorをblueからgreenに変更して即座にトラフィック切り替え、3) 問題なければblueを削除。即時切り替えとロールバックが可能です。

ドメイン3: Application Observability & Maintenance

Q17. Liveness Probeが失敗したとき、Kubernetesの動作は?

A) Podが削除されて再作成される B) コンテナが再起動される C) Podが別のノードに移動される D) アラートが送信される

答え: B

解説: Liveness Probeが失敗すると、Kubernetesは該当コンテナを再起動します(Pod全体ではなくコンテナのみ)。restartPolicyが適用されます。failureThreshold回連続して失敗すると再起動が始まります。アプリケーションのデッドロックや無限ループの検出に使用します。

Q18. Readiness Probeが失敗するとどうなるか?

A) コンテナが再起動される B) PodがServiceのエンドポイントから削除される C) Podが削除される D) 新しいPodが作成される

答え: B

解説: Readiness Probeが失敗すると、該当PodがServiceのEndpointリストから削除されてトラフィックを受け取らなくなります。コンテナは再起動されません。Probeが再び通過するとEndpointに再追加されます。デプロイ中に準備できていないPodへのトラフィックを防ぎます。

Q19. Startup Probeの主な用途は?

A) 起動時間が長いレガシーアプリで、Liveness Probeが早期に失敗しないようアプリが準備完了するまで待機する B) コンテナ起動前に環境変数を初期化する C) コンテナ終了後にクリーンアップ作業を実行する D) 外部依存関係の状態を確認する

答え: A

解説: Startup Probeは起動時間が長いアプリケーションでLiveness Probeが早期に失敗することを防ぎます。Startup Probeが成功するまでLivenessとReadiness Probeは有効化されません。既存のモノリシックアプリをコンテナ化する際に特に有用です。

Q20. kubectl logs --since=1hの意味は?

A) 直近1時間のログのみ表示する B) 1時間前から現在までのログを表示する C) ログファイルの最初の1時間分を表示する D) ログを1時間ストリーミングする

答え: B

解説: kubectl logs POD_NAME --since=1hは過去1時間以内のログのみを表示します。--since-time=2024-01-01T00:00:00Zで特定時間以降のログを取得することもできます。--tail=100は最後の100行のみを表示します。

Q21. kubectl top podコマンドが動作するための前提条件は?

A) Prometheusがインストールされている必要がある B) Metrics Serverがクラスターにインストールされている必要がある C) Grafanaが設定されている必要がある D) kube-proxyがIPVSモードである必要がある

答え: B

解説: kubectl top podkubectl top nodeはKubernetes Metrics Serverを通じてCPUとメモリ使用量を取得します。Metrics Serverは別途インストールする必要があります。PrometheusやGrafanaはkubectl topコマンドには影響しません。

Q22. Ephemeral Containerを使用する目的は?

A) 一時的なPodを作成する B) デバッグツールのない実行中のPodに一時コンテナを追加してデバッグする C) Podを一時停止する D) リソース使用量を削減する

答え: B

解説: Ephemeral Containerはdistrolessやslimイメージのようにシェルやデバッグツールのないコンテナをデバッグする際に使用します。kubectl debug -it POD_NAME --image=busybox --target=CONTAINERで実行中のPodに一時コンテナを追加します。Kubernetes 1.23以降でGAです。

Q23. コンテナのLiveness ProbeをHTTPで設定する方法は?

A) livenessProbe.tcpSocketを使用する B) livenessProbe.httpGetを使用する C) livenessProbe.execを使用する D) livenessProbe.httpを使用する

答え: B

解説: HTTP Liveness ProbeはhttpGetを使用します。pathportを指定し、レスポンスコードが200-399であれば成功とみなします。tcpSocketはTCP接続確認、execはコマンド実行後の終了コード0確認で使用します。

ドメイン4: Application Environment, Configuration & Security

Q24. ConfigMapを環境変数としてPodに注入する方法は?

A) spec.containers.env.valueFrom.configMapKeyRefを使用する B) spec.containers.configmapを使用する C) spec.volumes.configmapを使用する D) spec.env.configmapを使用する

答え: A

解説: ConfigMapを環境変数として注入する2つの方法: 1) 特定キーのみ注入: env[].valueFrom.configMapKeyRefで特定のキーと値を参照、2) ConfigMap全体を注入: envFrom[].configMapRefですべてのキーを環境変数として注入。ボリュームマウントはファイルとして使用する場合に適しています。

Q25. KubernetesのSecretはetcdにどのように保存されるか?

A) AES-256で暗号化されて保存される B) デフォルトでは base64エンコードのみで保存され(暗号化ではない)、etcd暗号化は別途設定が必要 C) SHA-256ハッシュで保存される D) 完全に暗号化されて保存される

答え: B

解説: KubernetesのSecretはデフォルトではbase64エンコードのみでetcdに保存されます(暗号化ではありません)。etcdへの保存時に暗号化するにはkube-apiserverに--encryption-provider-configを設定する必要があります。RBACでSecretのアクセス制御とetcd暗号化の有効化がセキュリティのベストプラクティスです。

Q26. SecurityContextのrunAsNonRoot設定の効果は?

A) コンテナをrootユーザーで実行する B) コンテナがroot(UID 0)で実行しようとすると起動を拒否する C) コンテナのすべてのファイルを読み取り専用にする D) ネットワーク権限を削除する

答え: B

解説: securityContext.runAsNonRoot: trueはコンテナがroot(UID 0)で実行しようとした場合、コンテナの起動を拒否します。runAsUser: 1000と組み合わせると特定のUIDでの実行を強制できます。コンテナエスケープ攻撃時の被害を最小化するセキュリティのベストプラクティスです。

Q27. PodSecurityContextとコンテナレベルのSecurityContextの違いは?

A) PodSecurityContextは特定のコンテナにのみ適用される B) spec.securityContextはPod内のすべてのコンテナに適用され、コンテナレベルの設定はそのコンテナにのみ適用されてPodレベルの設定を上書きする C) 2つの設定は同一 D) コンテナレベルのSecurityContextはKubernetes 1.24で削除された

答え: B

解説: spec.securityContext(Podレベル)はPodのすべてのコンテナに適用されます(runAsUser、fsGroup、supplementalGroupsなど)。spec.containers[].securityContext(コンテナレベル)はそのコンテナにのみ適用され、Podレベルの設定を上書きします(capabilities、readOnlyRootFilesystemなど)。

Q28. capabilities.drop: ["ALL"]の効果は?

A) コンテナにすべてのLinux capabilitiesを追加する B) コンテナからすべてのLinux capabilitiesを削除して最小権限で実行する C) コンテナをprivilegedモードで実行する D) ネットワークアクセスをブロックする

答え: B

解説: capabilities.drop: ["ALL"]はコンテナからすべてのLinux capabilitiesを削除します。必要なcapabilitiesのみをcapabilities.addで再追加する方式で最小権限の原則を適用します。例えばWebサーバーはNET_BIND_SERVICEのみ必要な場合があります。

Q29. LimitRangeの役割は?

A) クラスター全体のリソース使用量を制限する B) 名前空間内の個別Pod/Containerのデフォルトおよび最大リソースリクエスト/制限を設定する C) PVCのサイズを制限する D) ユーザーごとのPod数を制限する

答え: B

解説: LimitRangeは名前空間内の個別リソース(Pod、Container、PVC)のデフォルト値(default)、最小値(min)、最大値(max)を設定します。requests/limitsを明示しないコンテナにはデフォルト値が自動的に適用されます。ResourceQuotaは名前空間全体の合計を制限します。

Q30. ResourceQuotaを使用する目的は?

A) 個別Podの最大CPU/メモリを制限する B) 名前空間全体で使用できるリソースの合計を制限する C) ノードのリソース使用量を制限する D) コンテナのネットワーク帯域幅を制限する

答え: B

解説: ResourceQuotaは名前空間全体で作成できるリソースの総量を制限します。CPU、メモリ、Pod数、PVC数、LoadBalancerサービス数などを制限できます。複数チームがクラスターを共有する際に特定チームがリソースを独占することを防ぎます。

Q31. imagePullPolicy: IfNotPresentAlwaysの違いは?

A) IfNotPresentは常に新しいイメージを取得し、Alwaysはキャッシュを使用する B) IfNotPresentはローカルにイメージがない場合のみ取得し、Alwaysは常にレジストリから最新イメージを取得する C) 2つのオプションは同一 D) IfNotPresentはlatestタグでのみ動作する

答え: B

解説: IfNotPresent: ノードにイメージがない場合のみレジストリから取得します。イメージがあれば既存のものを使用します。Always: 毎回レジストリから最新イメージを確認して取得します。latestタグや、ダイジェストなしでタグを使用する場合はAlwaysを推奨します。

Q32. PodでSecretを環境変数として安全に使用する方法は?

A) spec.containers.env.valueに直接値を入力する B) spec.containers.env.valueFrom.secretKeyRefを使用する C) spec.containers.argsに秘密の値を含める D) ConfigMapにSecret値を含める

答え: B

解説: env[].valueFrom.secretKeyRefを使用してSecretの特定キーを環境変数として注入します。envFrom[].secretRefでSecretのすべてのキーを一度に注入することもできます。Secretの値をYAMLに直接入力したり、ConfigMapに保存することはセキュリティ上危険です。

Q33. ServiceAccountトークンが自動的にマウントされるパスは?

A) /etc/kubernetes/ B) /var/run/secrets/kubernetes.io/serviceaccount/ C) /home/app/.kube/ D) /tmp/secrets/

答え: B

解説: ServiceAccountトークンはデフォルトで/var/run/secrets/kubernetes.io/serviceaccount/パスに自動マウントされます。このパスにはtokenca.crtnamespaceファイルがあります。自動マウントが不要な場合はautomountServiceAccountToken: falseで無効化します。

ドメイン5: Services & Networking

Q34. ServiceのselectorがPodのラベルと一致しない場合はどうなるか?

A) Serviceがエラーを返す B) Serviceのエンドポイントが空になりトラフィックが届かない C) すべてのPodにトラフィックが届く D) Serviceが自動削除される

答え: B

解説: ServiceのselectorがPodのラベルと一致しない場合、ServiceにEndpointがなくなります。kubectl get endpoints SERVICE_NAMEで"none"が表示されます。kubectl describe serviceのEndpointsフィールドが空になっていることで確認できます。

Q35. Ingressのpath-basedルーティングとhost-basedルーティングの違いは?

A) path-basedはIPアドレスベース、host-basedはドメインベース B) path-basedはURLパス(/api、/web)でルーティングし、host-basedはホスト名(api.example.com、web.example.com)でルーティングする C) 2つの方式は同一 D) host-basedはTLSをサポートしない

答え: B

解説: path-basedルーティングは同じドメインでパス別に異なるサービスにルーティングします(example.com/api → api-service)。host-basedルーティングは異なるホスト名で異なるサービスにルーティングします(api.example.com → api-service)。

Q36. IngressでTLSを設定する方法は?

A) spec.sslフィールドを使用する B) spec.tlsにsecretName(TLS証明書を含むSecret)とhostsを指定する C) spec.annotationsにTLS情報を含める D) Ingress Controllerの設定でのみ可能

答え: B

解説: Ingress TLS設定: spec.tlshosts(TLSを適用するホストのリスト)とsecretName(TLS証明書が入ったkubernetes.io/tls型のSecret)を指定します。SecretにはTLS証明書をtls.crttls.keyキーで含める必要があります。

Q37. NetworkPolicyでegressルールを設定する理由は?

A) 受信トラフィックを制御する B) Podから出るトラフィックを制御して意図しない外部接続を防ぐ C) ノード間の通信を制御する D) DNSクエリをブロックする

答え: B

解説: egressルールはPodから出る(アウトバウンド)トラフィックを制御します。例えば、データベースPodがインターネットに接続するのを防いだり、特定のポート(例: 5432のPostgreSQL)のみ外部に出られるよう制限できます。DNS通信(ポート53)は明示的に許可する必要があります。

Q38. ServiceをDNS名にマッピングするServiceタイプは?

A) ClusterIP B) NodePort C) LoadBalancer D) ExternalName

答え: D

解説: ExternalNameサービスはクラスター内部で外部DNS名を内部サービス名のように使用できるようにします。例えばmy-database.default.svc.cluster.localmysql.external.comにCNAMEマッピングします。クラスター外部のサービスに内部からアクセスするときに便利です。

Q39. NetworkPolicyがない場合のPod間通信のデフォルト動作は?

A) すべてのトラフィックがデフォルトでブロックされる B) NetworkPolicyがなければすべてのPod間通信が許可される C) 同じ名前空間のPodのみ通信できる D) Serviceを経由してのみ通信できる

答え: B

解説: KubernetesのデフォルトネットワークモデルではNetworkPolicyがない場合、すべてのPod間通信が許可されます。特定のPodにNetworkPolicyが適用されると、ポリシーに明示されたトラフィックのみ許可されます。名前空間にデフォルト拒否のNetworkPolicyを適用し、必要な通信のみ許可することがセキュリティのベストプラクティスです。

Q40. IngressのpathType: PrefixとExactの違いは?

A) Prefixはパスの先頭部分のみ確認し、Exactは全パスが正確に一致する必要がある B) Prefixは正規表現を使用し、Exactは文字列を比較する C) 2つのタイプは同一 D) Exactは大文字小文字を区別しない

答え: A

解説: Prefixは指定されたパスで始まるすべてのURLをマッチします(/apiは/api/users、/api/postsもマッチ)。Exactは指定されたパスと正確に一致するURLのみマッチします(/apiは/apiのみマッチ、/api/usersは不一致)。ImplementationSpecificはIngress Controllerによって動作が異なります。

Q41. ServiceにsessionAffinity: ClientIPを設定するとどうなるか?

A) 同じクライアントIPからのリクエストが常に同じPodにルーティングされる B) セッションが期限切れになる C) すべてのリクエストが1つのPodに集中する D) ロードバランシングが無効化される

答え: A

解説: sessionAffinity: ClientIPを設定すると、同じクライアントIPからのリクエストが常に同じPodにルーティングされます(スティッキーセッション)。sessionAffinityConfig.clientIP.timeoutSecondsでセッション維持時間を設定できます。デフォルト値はNone(ランダムルーティング)です。

Q42. 同じ名前空間内の別のサービスへのリクエストに使用する正しいDNS名は?

A) service-name.cluster.local B) service-name(またはservice-name.namespace.svc.cluster.local) C) namespace.service-name D) http://service-name:port

答え: B

解説: 同じ名前空間内ではサービス名だけでアクセスできます(service-name)。別の名前空間からアクセスする場合はservice-name.namespaceまたは完全なFQDNであるservice-name.namespace.svc.cluster.localを使用します。

Q43. Podへの外部からの直接アクセスを可能にするServiceタイプは?

A) ClusterIP B) NodePortとLoadBalancer C) headless service D) ExternalName

答え: B

解説: NodePortはすべてのノードの特定ポート(30000-32767)で外部アクセスを許可します。LoadBalancerはクラウドプロバイダーのロードバランサーを自動作成して外部IPを提供します。ClusterIPはクラスター内部からのみアクセスできます。

Q44. kubectl port-forwardコマンドの用途は?

A) Serviceのポートを永続的に変更する B) ローカルポートをPodのポートに一時的に転送してクラスター内部サービスにローカルからアクセスする C) ノードのポートをPodにマッピングする D) Ingressの設定をテストする

答え: B

解説: kubectl port-forward pod/POD_NAME LOCAL_PORT:POD_PORTはローカルマシンのポートをPodのポートに一時的に転送します。開発中にクラスター内部サービスに直接アクセスしたり、デバッグする際に便利です。サービスにも使用可能: kubectl port-forward service/SVC_NAME LOCAL_PORT:SVC_PORT

Q45. Podに複数のネットワークインターフェースを追加する方法は?

A) spec.networksフィールドに追加ネットワークを指定する B) Multus CNIを使用してNetworkAttachmentDefinitionで追加インターフェースを設定する C) kube-proxyの設定を変更する D) 複数のServiceを作成する

答え: B

解説: Multus CNIはPodに複数のネットワークインターフェースを追加できるメタCNIプラグインです。NetworkAttachmentDefinition CRDで追加ネットワークを定義し、Podのannotationで参照します。テレコム、NFV、高性能ネットワーキングが必要な環境で使用されます。

Q46. ConfigMapから特定のキーのみを環境変数として注入する方法は?

A) envFrom.configMapRefを使用する B) env[].valueFrom.configMapKeyRef.keyで特定のキーを指定する C) volumeMountsを使用する D) spec.config.envを使用する

答え: B

解説: 特定のキーのみ注入: env[].valueFrom.configMapKeyRefname(ConfigMap名)とkey(キー名)を指定します。すべてのキーを注入する場合はenvFrom[].configMapRef.nameを使用します。特定のキーのみ取得すると不要な環境変数を防げます。

Q47. Podコンテナのgraceful shutdownのための設定は?

A) spec.terminationGracePeriodSecondsで十分な終了時間を確保し、コンテナ内でSIGTERMを処理する B) restartPolicy: Neverを設定する C) Liveness Probeを無効化する D) privileged: trueを設定する

答え: A

解説: spec.terminationGracePeriodSeconds(デフォルト30秒)はSIGTERMシグナル後に強制終了(SIGKILL)まで待機する時間です。アプリケーションはSIGTERM受信時に進行中のリクエスト処理を完了してから終了すべきです。Readiness Probeで終了中のPodに新しいリクエストが来ないようにします。preStopライフサイクルフックで追加のクリーンアップ作業も可能です。

Q48. CKAD試験でよく使われるkubectlエイリアス設定として正しいものは?

A) alias kubectl=k B) alias k=kubectl; export do="--dry-run=client -o yaml" C) kubectl config set alias k=kubectl D) export KUBECTL_ALIAS=k

答え: B

解説: alias k=kubectlexport do="--dry-run=client -o yaml"は試験時間を節約するための重要な設定です。例: k create deploy myapp --image=nginx $do > deploy.yamlで素早くYAMLテンプレートを生成できます。vimのYAMLインデント設定も重要です: :set et ts=2 sw=2

Q49. コンテナのSecurityContextにreadOnlyRootFilesystem: trueを設定すると?

A) コンテナがファイルを読めなくなる B) コンテナのルートファイルシステムが読み取り専用になり、ランタイム中にファイルの変更ができなくなる C) ボリュームマウントが無効化される D) ネットワークアクセスがブロックされる

答え: B

解説: readOnlyRootFilesystem: trueはコンテナのルートファイルシステムを読み取り専用にします。攻撃者がコンテナに侵入してもファイルを変更したり悪意のあるコードをインストールしにくくなります。書き込みが必要なディレクトリはemptyDirボリュームでマウントします。

Q50. コンテナがホストの名前空間を使用するよう設定するフィールドは?

A) spec.hostPID、spec.hostNetwork、spec.hostIPC B) spec.network.host = true C) spec.containers.hostNamespace = true D) spec.shareHostNamespace = true

答え: A

解説: spec.hostPID: trueはホストのPID名前空間を共有し、spec.hostNetwork: trueはホストのネットワークスタックを使用し、spec.hostIPC: trueはホストのIPC名前空間を共有します。これらの設定はセキュリティリスクがあるため必要な場合のみ使用すべきです。

Q51. kubectl applykubectl createの違いは?

A) kubectl createはYAMLファイルをサポートしない B) kubectl applyは宣言型アプローチで変更のみを適用し既存の場合は更新する、kubectl createはリソースが既に存在するとエラーを返す C) kubectl createの方が速い D) kubectl applyは削除も実行する

答え: B

解説: kubectl applyはリソースを宣言型に管理します。存在しなければ作成、すでに存在すれば変更点のみ更新します。kubectl createは命令型で既存のリソースにはエラーを返します。CI/CDパイプラインではkubectl applyが推奨されます。

Q52. Podで特定のホストパスをボリュームとしてマウントする方法は?

A) spec.volumes.emptyDirを使用する B) spec.volumes.hostPathを使用する C) spec.volumes.configMapを使用する D) spec.volumes.secretを使用する

答え: B

解説: hostPathボリュームはノードのファイルシステムパスをコンテナにマウントします。Dockerソケット(/var/run/docker.sock)、ノードのログ(/var/log)などへのアクセスに使用されます。セキュリティリスク(ノードファイルシステムへの直接アクセス)があるため注意が必要です。typeフィールドでDirectory、File、Socketなどを指定します。

Q53. 環境変数KUBERNETES_SERVICE_HOSTは何を表すか?

A) kubeletが実行中のノードのIP B) Pod内部からKubernetes APIサーバーにアクセスするためのClusterIP(自動注入される) C) etcdサーバーのアドレス D) Ingress Controllerのアドレス

答え: B

解説: KubernetesはすべてのPodにKUBERNETES_SERVICE_HOSTKUBERNETES_SERVICE_PORT環境変数を自動注入します。これらはPod内からKubernetes APIにプログラム的にアクセスするときに使用されます。ServiceAccountトークンと組み合わせてクラスター内部からAPIを呼び出せます。

Q54. ProbeのinitialDelaySeconds、periodSeconds、failureThresholdの役割は?

A) それぞれ最大時間、周期、リトライ回数を設定する B) initialDelaySeconds: 最初のProbe実行前の待機時間、periodSeconds: Probe実行周期、failureThreshold: 連続失敗回数のしきい値 C) すべてタイムアウト関連の設定 D) すべてデータベース接続関連の設定

答え: B

解説: initialDelaySeconds: コンテナ起動後から最初のProbe実行までの待機時間(アプリの初期化時間を考慮)。periodSeconds: Probeを実行する周期(デフォルト10秒)。failureThreshold: この回数だけ連続して失敗すると再起動(Liveness)またはトラフィック除外(Readiness)。timeoutSeconds: 1回のProbeのタイムアウト。

Q55. PodレベルのfsGroup設定の役割は?

A) ファイルシステム暗号化グループを指定する B) マウントされたボリュームのファイル所有権を指定されたGIDに設定し、グループベースのファイルアクセスを可能にする C) コンテナユーザーを指定する D) ネットワークグループを指定する

答え: B

解説: spec.securityContext.fsGroupはPodにマウントされたボリューム(PVCを含む)のファイル所有グループGIDを指定します。マウントされたボリュームのファイル権限が自動的にそのGIDに変更されます。複数のコンテナがボリュームを共有する際のファイルアクセス権限の問題解決に役立ちます。


実技シミュレーション(P1 〜 P10)

P1. Sidecarを使ったマルチコンテナPod

シナリオ: nginxメインコンテナとbusyboxサイドカーコンテナで構成されたPodを作成しなさい。サイドカーは/var/log/nginx/access.logを読んでstdoutに出力します。両コンテナはemptyDirボリュームでログディレクトリを共有する必要があります。

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: nginx-with-sidecar
  labels:
    app: nginx-sidecar
spec:
  containers:
  - name: nginx
    image: nginx:latest
    volumeMounts:
    - name: log-volume
      mountPath: /var/log/nginx
  - name: log-sidecar
    image: busybox:latest
    command: ['sh', '-c', 'tail -f /var/log/nginx/access.log']
    volumeMounts:
    - name: log-volume
      mountPath: /var/log/nginx
  volumes:
  - name: log-volume
    emptyDir: {}
EOF

kubectl logs nginx-with-sidecar -c log-sidecar -f

P2. ConfigMapとSecretを使うDeployment

シナリオ: db-config ConfigMapとdb-secret Secretを作成し、環境変数として注入したDeploymentを作成しなさい。

kubectl create configmap db-config \
  --from-literal=DB_HOST=mysql-service \
  --from-literal=DB_PORT=3306 \
  --from-literal=DB_NAME=myapp

kubectl create secret generic db-secret \
  --from-literal=DB_USER=admin \
  --from-literal=DB_PASSWORD=secretpassword

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: nginx:latest
        envFrom:
        - configMapRef:
            name: db-config
        env:
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: DB_USER
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: DB_PASSWORD
EOF

kubectl exec -it deploy/myapp -- env | grep -E "DB_"

P3. Probeの設定

シナリオ: nginx DeploymentにLiveness Probe(HTTP、/、ポート80)、Readiness Probe(HTTP、/、ポート80)、Startup Probeを設定しなさい。

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-with-probes
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-probes
  template:
    metadata:
      labels:
        app: nginx-probes
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        startupProbe:
          httpGet:
            path: /
            port: 80
          failureThreshold: 30
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 15
          failureThreshold: 3
          timeoutSeconds: 5
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 10
          failureThreshold: 3
          successThreshold: 1
EOF

P4. ローリングアップデートとロールバック

シナリオ: webapp Deploymentを作成してイメージを更新し、ロールアウト状態を監視しなさい。更新後にロールバックしなさい。

kubectl create deployment webapp \
  --image=nginx:1.24 \
  --replicas=4

kubectl patch deployment webapp -p \
  '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":1}}}}'

kubectl set image deployment/webapp nginx=nginx:1.25
kubectl rollout status deployment/webapp
kubectl rollout history deployment/webapp

# カナリアテストのために一時停止
kubectl rollout pause deployment/webapp
kubectl get pods -l app=webapp -o wide
kubectl rollout resume deployment/webapp

# またはロールバック
kubectl rollout undo deployment/webapp

P5. SecurityContextの設定

シナリオ: 以下のセキュリティ要件を持つPodを作成しなさい: UID 1000で実行、rootでの実行禁止、読み取り専用ルートファイルシステム、すべてのLinux capabilitiesを削除。

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  securityContext:
    runAsUser: 1000
    runAsNonRoot: true
    fsGroup: 2000
  containers:
  - name: app
    image: nginx:latest
    securityContext:
      readOnlyRootFilesystem: true
      allowPrivilegeEscalation: false
      capabilities:
        drop:
        - ALL
    volumeMounts:
    - name: tmp-dir
      mountPath: /tmp
    - name: var-cache
      mountPath: /var/cache/nginx
    - name: var-run
      mountPath: /var/run
  volumes:
  - name: tmp-dir
    emptyDir: {}
  - name: var-cache
    emptyDir: {}
  - name: var-run
    emptyDir: {}
EOF

kubectl exec secure-pod -- id
kubectl exec secure-pod -- cat /proc/1/status | grep Cap

P6. Init Containerの使用

シナリオ: メインコンテナが起動する前にデータベース接続を確認するInit Containerを使ったPodを作成しなさい。

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: app-with-init
spec:
  initContainers:
  - name: wait-for-db
    image: busybox:latest
    command: ['sh', '-c',
      'until nc -z mysql-service 3306; do echo "Waiting for MySQL..."; sleep 5; done; echo "MySQL is ready!"']
  - name: migrate-db
    image: busybox:latest
    command: ['sh', '-c', 'echo "Running DB migration..."; sleep 2; echo "Migration complete"']
  containers:
  - name: app
    image: nginx:latest
    ports:
    - containerPort: 80
EOF

kubectl logs app-with-init -c wait-for-db
kubectl logs app-with-init -c migrate-db
kubectl describe pod app-with-init

P7. ResourceQuotaとLimitRangeの設定

シナリオ: team-dev名前空間にResourceQuota(CPU 4コア、メモリ8Gi、Pod 10個)とLimitRange(コンテナデフォルト CPU 100m/メモリ 128Mi、最大 CPU 1/メモリ 1Gi)を設定しなさい。

kubectl create namespace team-dev

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-quota
  namespace: team-dev
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi
    pods: "10"
    services: "5"
---
apiVersion: v1
kind: LimitRange
metadata:
  name: container-limits
  namespace: team-dev
spec:
  limits:
  - type: Container
    default:
      cpu: 200m
      memory: 256Mi
    defaultRequest:
      cpu: 100m
      memory: 128Mi
    max:
      cpu: "1"
      memory: 1Gi
    min:
      cpu: 50m
      memory: 64Mi
EOF

kubectl describe resourcequota team-quota -n team-dev
kubectl describe limitrange container-limits -n team-dev

P8. TLS付きIngress

シナリオ: TLSを使ったIngressを設定してsecure.example.comへのhttpsアクセスができるようにしなさい。

openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /tmp/tls.key \
  -out /tmp/tls.crt \
  -subj "/CN=secure.example.com/O=myorg"

kubectl create secret tls secure-tls \
  --cert=/tmp/tls.crt \
  --key=/tmp/tls.key

kubectl create deployment secure-app --image=nginx --replicas=2
kubectl expose deployment secure-app --port=80 --name=secure-app-service

cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: secure-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - secure.example.com
    secretName: secure-tls
  rules:
  - host: secure.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: secure-app-service
            port:
              number: 80
EOF

kubectl get ingress secure-ingress

P9. NetworkPolicyのEgress制御

シナリオ: backend PodがポートTCP 5432のdatabase PodにのみトラフィックをEgressできるようにNetworkPolicyを設定しなさい。DNSクエリは許可する必要があります。

cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-egress-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Egress
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: database
    ports:
    - protocol: TCP
      port: 5432
  - ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53
EOF

kubectl get networkpolicy backend-egress-policy
kubectl describe networkpolicy backend-egress-policy

P10. JobとCronJob

シナリオ: 1から10までの合計を計算するJobを作成し、毎分現在時刻とホスト名を出力するCronJobを作成しなさい。

cat <<EOF | kubectl apply -f -
apiVersion: batch/v1
kind: Job
metadata:
  name: sum-calculator
spec:
  completions: 1
  parallelism: 1
  backoffLimit: 3
  template:
    spec:
      containers:
      - name: calculator
        image: busybox:latest
        command:
        - /bin/sh
        - -c
        - |
          sum=0
          for i in 1 2 3 4 5 6 7 8 9 10; do
            sum=$((sum + i))
          done
          echo "Sum of 1 to 10 is: $sum"
      restartPolicy: OnFailure
---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: heartbeat
spec:
  schedule: "* * * * *"
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: heartbeat
            image: busybox:latest
            command:
            - /bin/sh
            - -c
            - echo "Heartbeat at $(date) from $(hostname)"
          restartPolicy: OnFailure
EOF

kubectl logs -l job-name=sum-calculator
kubectl get cronjob heartbeat
kubectl get jobs --watch

試験のヒント

  1. ドメインの把握: Application Environment, Configuration & Security(25%)が最も高い比率
  2. YAML高速生成: --dry-run=client -o yamlでテンプレートを作成
  3. Probeフィールドの暗記: initialDelaySeconds、periodSeconds、failureThresholdを覚える
  4. SecurityContextのレベル区別: Podレベル vs コンテナレベル
  5. ConfigMap vs Secret: 機密情報は必ずSecretを使用
  6. kubectl explainを活用: kubectl explain pod.spec.containers.securityContextでフィールドを確認