本記事の対象読者
- これからCKADを受験する方
- CKADに興味がある方
- CKAD合格のためにどれくらい勉強したらよいのかを参考にしたい方
- Linuxのシェル操作経験がある、kubernetesの基本的な知識がある方
本記事で説明すること
- CKADを受験するために必要な準備、試験について
- CKAD合格のために行った学習方法
- CKADの問題を早く解くために実践したこと
本記事で説明しないこと
- 試験の具体的な問題内容について
- kubernetesに関する基本知識について
🔴 はじめに
CKADとは、Certified Kubernetes Application Developerの略で、Cloud Native Computing Foundation(CNCF)がLinux Foundationと共同で開発した、kubernetesアプリ開発者向けの試験です。
業務でkubernetesを利用しているのですが、しっかり理解せずに使用していたため、kubernetesの基本を理解しようと思いCKADを受験することにしました。
先日受験し、結果92/100点で無事に合格することができました。合格最低点は66点で固定です。
CKADでは時間が足りないことが多いと聞いていました。
実際、本番の試験問題は文章量だけでなく問題数も多いので、問われていることを理解するだけでも時間がかかってしまいます。
そのためCKADを合格するために最も重要なことは、最短時間で指定されたリソースを構築することだと思います。
私は特にそこを意識して対策を進めたため、見直し含めて15分程度残した状態で試験を終了することができました。
ただ、対策をしないと試験時間は確実に足りなくなりそうだな...という印象でした。
また、CKADの試験はLPICやGoogle CloudなどのようなIT資格によくあるようなテストセンターで解く選択問題形式ではなく、
遠隔かつ実際にシェルからk8sリソースを操作するという実践的なものとなっています。そのような試験形式には慣れておらず個人的にはとても不安でしたし、そのように感じている方も多いかもしれません。
そのため、本記事では、試験までの流れ、およびCKADの問題を早く解くために私が実践したことを重点的に説明します。
これからCKADを受験する人の少しでも参考になれば幸いです。
ただ、こちらの機密保持契約があるため、具体的な問題内容などについては触れません。
🔴 試験について
申し込み
Linux Foundation の cyber monday を利用して学習コース?込みで$199で受験をしました。
https://training.linuxfoundation.org/cyber-monday-2020/
付属のコースは利用しませんでした。
試験のための準備
試験場所
以下の条件を満たす必要があります。
- 綺麗な作業エリア
- 壁に貼り付けられた紙が無い
- 明るい
- 後ろが明るすぎない
- 公共スペースではない
私は自室で受けました。会社の会議室などでも良さそうです。
詳しくはこちらをご覧ください。
身分証明書
パスポートが無難だと思います。
詳しくはこちらをご覧ください。
私はパスポートを利用しました。
持ち込み可能なもの
飲み物
ラベルを剥がした透明なボトルであれば問題ないと思います。
サブモニター
多分一つなら使えるらしいです。
試験監督にサブモニター使う?的なこと聞かれましたが、私は利用しませんでした。
公式ドキュメントをサブモニターに表示しておくというのもありだと思いました。
キーボード・マウス
システム要件
- ブラウザはchrome
- 移動可能なウェブカメラ
- マイク
- 十分な通信帯域
試験監督に試験中の状況を共有する必要があるため、カメラとマイクが必要になります。
机の周辺の様子を確認してもらう必要があるため、カメラは移動可能である必要があります。
私は、MacBook内臓のカメラ、マイクを利用しました。
とは言っても、直接試験監督と会話したり顔を合わせたりすることはなく、一方通行なので、こちら側の出力音声はミュートにしていました。
(しないとめちゃくちゃハウリングしました。)
chrome拡張のインストール
試験を使用する時にこちらの拡張を使用します。
予めインストールしておく必要があります。
予備のマシン
こちらはあればで大丈夫ですが、用意しておくのが無難だと思います。
私の場合、はじめに会社のMacBookProで受験をしようと思ったのですが、
後述のトラブルによって予備のMacBookで受験することになりました。
試験
試験開始時刻の15分前から、試験開始ボタンがactiveになります。
試験開始ボタンを押すとすぐにチャット越しに試験監督との会話が始まります。
とは言っても、向こうは基本テンプレの文章をバンバン送ってくることが多かったです。
何かトラブルが発生したり質問などがない限りはこちらからチャットを送る必要はなさそうでした。
また、もちろんやりとりは全て英語なのですが、chromeのGoogle翻訳も利用できるので、英語が苦手な方でも問題ないかと思います。
私の場合、画面共有ができないというトラブルがありました。
なぜか何度画面共有しても画面共有モードにならなかったです。
画面共有やカメラ共有ができているかどうかは、試験ページ上部のカメラや画面共有のマークがオレンジ色か緑色かで判断できます。
そのため、試験監督に別のマシンで受験するからチョイマッテとチャットを送信しました。
幸い別のマシンがすぐに使用できる状態だったので、そちらを利用しました。こちらは画面共有もすぐにできました。
遠隔での試験のためか、試験中の様子については結構厳しく、口元を隠したりするだけでも注意を受けるらしいです。
私も、問題文を読む時に画面に少し顔を近づけたために画面から少し顔が映らなくなっただけでもチャットが飛んできました。
問題
問題については詳しく説明できません。
ただ、どれも文章量が多かったように感じます。
求められているリソースの状態を再現するためのプロセス自体はどれも基本的なもので、
操作自体は後述のCKAD Exerciseができれば十分だと思いました。
各問題には配点の重み付けがされており、全て示されています。
問題の配点の重みと難易度は全然一致していない印象なので、配点が少ない問題はどんどんあと回しにしていくのが良いかと思いました。
試験問題は、日本語、英語などを試験中に切り替えられるようになっております。
私は基本日本語で解いていましたが、翻訳がおかしかったり、日本語では全然理解できないような問題もありました。
そのため、必要に応じて英語に切り替えつつ、といった感じに解きました。
また、最終的にどのようにしてほしいのかわかりにくい問題が多い印象で、読解力と用語の理解が必要だと感じました。
私の場合は、結局何をして欲しいのか全くわからない問題が二問あり、それっぽい感じにやって提出しましたが、多分その2つを落としたのかと思いました。
サイドカーパターンやアンバサダーパターンなど、コンテナのデザインパターンの用語も出てくることもあるかと思うので、予め理解しておくとスラスラ理解できるかと思います。
この記事がとてもわかりやすいので、試験前に目を通しておくと良いかもしれません。
https://qiita.com/MahoTakara/items/03fc0afe29379026c1f3
試験結果
試験終了後36時間以内に結果のメールが送信されます。
私の場合は昼の12時頃に終わり、次の日の夜22時頃に結果のメールを受信したので、だいたい34時間くらいでした。
🔴 学習について
利用した教材
以下の三つを利用しました。
どれもCKADやCKA受験者にとっては超有名な教材です。
どれも本当に有益でオススメです。
[Udemy] Kubernetes Certified Application Developer (CKAD) with Tests
こちらは全て英語です。月2〜3回くらいで定期的に行われるUdemyのセールで買いました。
ミュートしながらでも概要は理解できると思うくらいに動画の図が非常にわかりやすかったです。
1時間分×2セット分の mock exam が付属しているので一通り理解してからの力試しとしてとても良いと思いました。
難易度も内容も本番に近い印象です。
CKAD Exercises
問題と回答がセットになった無料問題集です。試験範囲を網羅しているだけでなく、受験に不必要な知識はほとんど含まれていない、まさにCKAD特化といったイメージです。
また、本番で必要なリソースの操作方法は、ここで十分に身に付くかと感じました。
個人的にはこれがCKADの対策としては最も役に立ったと思っており、4周しました。
先ほども申し上げたとおり、CKADは最短時間で指定されたリソースを構築することなので、毎回時間を測って行いました。
Kubernetes完全ガイド
まさに教科書と呼べる内容で、kubernetesを学習する人から中級者まで全ての方におすすめできる超良本です。
理想はCKADの勉強を始める前にざっと目を通しておくことですが、かなり量が多いということと、CKAD合格には必要のない知識もたくさん含まれているため、
CKADを最短で取得することが目的なのであれば、上記のUdemyとCKAD Exerciseを一周してからわからないところだけを本書で見直すという手法が良さそうだと思います。
私はCKADを受験する目的が「kubernetesの理解度を上げるため」だったので、最初に一通り時間をかけて目を通しました。
学習時間
30時間くらい。
このうちの大半は完全ガイドを読んでいました。
試験範囲
https://github.com/cncf/curriculum
ここに載っています。具体的には、CKAD Exerciseの通りのような印象です。
ちなみに先ほどおすすめ教材で説明したUdemyでは、
- Ingress
- TaintとToleration
が説明されていました。
私が受験したときはこのあたりの知識はなくても問題なかったなという印象でした。CKAD Exerciseにも含まれていません。
なので、もし最短でCKADを合格することだけを考えるのであれば飛ばしても問題ないかもしれません。
ただ必ず出ないとは言い切れないですし、kubernetesを利用する上ではどちらも非常に重要なので理解しておくことをおすすめします。
学習環境
私はGoogle CloudのKubernetes Engine (GKE)を利用しました。
GCPの無料枠で、0円で利用することができました。
欠点としては、GKEは試験で利用されるバージョンを利用できない可能性が高いので試験環境バージョンを再現することはできないということくらいです。
私が受験したときは試験環境のバージョンが1.20でしたが、そのときGKEで提供されているバージョンの最新が1.19でした。
CKADで出題される基本的な操作が変わるような破壊的変更はそこまで発生しないと思うので、少しくらい古いバージョンでも問題ないかと思います。
(ちなみに試験に使用されるバージョンは、kubernetesの最新のマイナーバージョンに4~8週間遅れて追従されるようです。詳しくはこちら。)
また、GKEでは試験範囲のNetworkPolicyがデフォルトで無効になっているので、試したい場合はコンソールから手動で有効にする必要があります。
自分の手元の環境を汚したくないのでCloudShellを利用しました。
ブラウザ上からk8sクラスタに接続できる仮想環境をボタン一つで立ち上げることができるのでとてもオススメです。
🔴 1秒でも早く問題を解くために実践したこと
一からyamlを書かない。
具体的には、
podを作成するときは、kubectl run
から、
serviceを作るときはkubectl expose
から、
hpaを作るときはkubectl autoscale
から、
deploymentやnsなどその他リソース作るときはkubectl create
から作成するべき
などということです。
これらは他でも詳しく書かれているかと思うのでここでは説明は省略します。
ただし、中にはkubectlから作成できないリソースもあるので、そのような場合には公式ドキュメントのサンプルのyamlから作成しました。
それらのパターンを洗い出し、リソースを作成するために必要な最小のyamlへのリンクをブックマークに登録しておくことがオススメです。
ドキュメントから欲しい情報を最速で取得
ブックマークを活用する
本番でドキュメントを読み漁るのは時間がもったいないので、あらかじめ必要なだけブックマークを登録しておくことが非常に重要です。
私が登録したリンクは以下の通りです。
PersistentVolumeClaims
Claims As Volumes
Persistent Volumes
Using Secrets as files from a Pod
Using Secrets as environment variables
configMapKeyRefのサンプル
Populate a Volume with data stored in a ConfigMap
configmap 全部環境変数として
Define a liveness HTTP request
Define a liveness command
Define readiness probes
kubectlチートシート
Set the security context for a Pod
emptyDir configuration example
The NetworkPolicy resource
Ingressリソースの最小構成
sa pod
検索速度を上げる
公式ドキュメントのブックマークをしていない箇所の情報が必要になる場合もあるかと思います。
その場合は、(macの場合は)
Cmd+F + "kind: {KIND}"
でyamlに最速でたどり着ける確率が上がります。
例えば、configmapの内容をpodに環境変数として流し込む方法を調べる場合を想定してみます。
まずは短縮記法を使用してそれっぽい感じで検索します。
kubernetesのドキュメントは結構検索の精度が高くだいたい一番上にヒットした記事を見れば欲しい情報があることが多いです。
一番上の記事de、今回はpodのyamlを書くので、kind: Pod
で検索します。
それっぽいpodのyamlが複数ヒットします。
10秒もしないうちに欲しい情報にたどり着くことができました。
ちなみに、kindについては後述の
$ kubectl api-resources
で調べることができます。
alias
私が本番で利用したaliasは以下の通りです。
(私は試していないですが、macであればこれらをユーザ辞書などに登録しておけば速攻で環境構築ができるかもです。ルール的に問題ないかは不明。)
alias k='kubectl'
alias kg='kubectl get'
alias kd='kubectl describe'
alias kc='kubectl create'
alias kr='kubectl run'
alias grep='grep -i --color=auto'
alias coch='kubectl run connect-check --image=busybox --restart=Never -it --rm -- wget --timeout=2 -O-'
k
はほぼ全員が設定しているかと思います。
実際の試験ではkubectlを叩くうちの大半はget
やdescribe
, create
を利用するので、これらも登録しておくとだけでもかなり時短になります。
alias grep='grep -i --color=auto'
こちらもオススメです。-i
は大文字小文字の違いを無視するフラグです。
こちらがオススメな理由は、kubectl describe
→ grep
や、 kubectl get -oyaml
→ grep
でリソースの情報が欲しい場合がよくあるかと思うのですが、指定したワードが大文字なのか小文字なのか考えるのが面倒だからです。
(ちなみに上記の例のようにpodがどこのnodeに乗っているかを知りたい場合はkg po -owide
が最短かと思います。)
podやdeployment、serviceを作成するような場合にEndpointに対してhttpの疎通チェックすることがよくあるかと思うのですが、そのために毎回busyboxでpodをたてるのも大変だし時間がかかります。
そのため、podとの接続チェックのcoch
が地味に便利です。(名前は各自好きなものを利用すると良いと思います)
$ coch 10.104.3.76
Connecting to 10.104.3.76 (10.104.3.76:80)
writing to stdout
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- 100% |********************************| 612 0:00:00 ETA
written to stdout
pod "connect-check" deleted
補完
pod名など、補完することができます。
公式ドキュメントのこのページをブックマークに登録しておくことをオススメします。
https://kubernetes.io/ja/docs/reference/kubectl/cheatsheet/#bash
以下公式ドキュメントの引用です。
source <(kubectl completion bash) # 現在のbashシェルにコマンド補完を設定するには、最初にbash-completionパッケージをインストールする必要があります。
echo "source <(kubectl completion bash)" >> ~/.bashrc # bashシェルでのコマンド補完を永続化するために.bashrcに追記します。
また、エイリアスを使用している場合にもkubectlコマンドを補完できます。
alias k=kubectl
complete -F __start_kubectl k
短縮記法を使用する
大抵のリソースはpods=po
のような短縮記法的なaliasが存在します。
こちらも時短になるので始めからこれを利用して叩く癖をつけておくと良いかもしれません。
CKADで使うものはこれくらいでしょうか。
name | short name |
---|---|
configmaps | cm |
endpoints | ep |
namespaces | ns |
nodes | no |
persistentvolumeclaims | pvc |
persistentvolumes | pv |
pods | po |
resourcequotas | quota |
secrets | なし |
serviceaccounts | sa |
services | svc |
deployments | deploy |
replicasets | rs |
horizontalpodautoscalers | hpa |
cronjobs | cj |
jobs | なし |
ingresses | ing |
networkpolicies | netpol |
ちなみにいずれも複数形としてのsは省略可能です。
例えば、以下はどれも同じです。
kubectl get pods
kubectl get pod
kubectl get po
短縮記法やkindなどが思い出せないときはこちら。
$ kubectl api-resources
結果
$ kubectl api-resources
NAME SHORTNAMES APIGROUP NAMESPACED KIND
bindings true Binding
componentstatuses cs false ComponentStatus
configmaps cm true ConfigMap
endpoints ep true Endpoints
events ev true Event
limitranges limits true LimitRange
namespaces ns false Namespace
nodes no false Node
persistentvolumeclaims pvc true PersistentVolumeClaim
persistentvolumes pv false PersistentVolume
pods po true Pod
podtemplates true PodTemplate
replicationcontrollers rc true ReplicationController
resourcequotas quota true ResourceQuota
secrets true Secret
serviceaccounts sa true ServiceAccount
services svc true Service
mutatingwebhookconfigurations admissionregistration.k8s.io false MutatingWebhookConfiguration
validatingwebhookconfigurations admissionregistration.k8s.io false ValidatingWebhookConfiguration
customresourcedefinitions crd,crds apiextensions.k8s.io false CustomResourceDefinition
apiservices apiregistration.k8s.io false APIService
controllerrevisions apps true ControllerRevision
daemonsets ds apps true DaemonSet
deployments deploy apps true Deployment
replicasets rs apps true ReplicaSet
statefulsets sts apps true StatefulSet
tokenreviews authentication.k8s.io false TokenReview
localsubjectaccessreviews authorization.k8s.io true LocalSubjectAccessReview
selfsubjectaccessreviews authorization.k8s.io false SelfSubjectAccessReview
selfsubjectrulesreviews authorization.k8s.io false SelfSubjectRulesReview
subjectaccessreviews authorization.k8s.io false SubjectAccessReview
horizontalpodautoscalers hpa autoscaling true HorizontalPodAutoscaler
cronjobs cj batch true CronJob
jobs batch true Job
certificatesigningrequests csr certificates.k8s.io false CertificateSigningRequest
backendconfigs bc cloud.google.com true BackendConfig
leases coordination.k8s.io true Lease
endpointslices discovery.k8s.io true EndpointSlice
ingresses ing extensions true Ingress
capacityrequests capreq internal.autoscaling.k8s.io true CapacityRequest
nodes metrics.k8s.io false NodeMetrics
pods metrics.k8s.io true PodMetrics
frontendconfigs networking.gke.io true FrontendConfig
managedcertificates mcrt networking.gke.io true ManagedCertificate
servicenetworkendpointgroups svcneg networking.gke.io true ServiceNetworkEndpointGroup
ingresses ing networking.k8s.io true Ingress
networkpolicies netpol networking.k8s.io true NetworkPolicy
runtimeclasses node.k8s.io false RuntimeClass
updateinfos updinf nodemanagement.gke.io true UpdateInfo
poddisruptionbudgets pdb policy true PodDisruptionBudget
podsecuritypolicies psp policy false PodSecurityPolicy
clusterrolebindings rbac.authorization.k8s.io false ClusterRoleBinding
clusterroles rbac.authorization.k8s.io false ClusterRole
rolebindings rbac.authorization.k8s.io true RoleBinding
roles rbac.authorization.k8s.io true Role
scalingpolicies scalingpolicy.kope.io true ScalingPolicy
priorityclasses pc scheduling.k8s.io false PriorityClass
volumesnapshotclasses snapshot.storage.k8s.io false VolumeSnapshotClass
volumesnapshotcontents snapshot.storage.k8s.io false VolumeSnapshotContent
volumesnapshots snapshot.storage.k8s.io true VolumeSnapshot
csidrivers storage.k8s.io false CSIDriver
csinodes storage.k8s.io false CSINode
storageclasses sc storage.k8s.io false StorageClass
volumeattachments storage.k8s.io false VolumeAttachment
podを削除するときは--forceフラグを利用する
たまにpodを削除する時にかなり時間がかかる場合があります。
--force
フラグをつけるとだいたいすぐに消えてくれます。
多くの記事では--grace-period=0
も同時につけているのをみますが、無くてもすぐに消えているような気がします...。(偶然?)
$ kubectl delete pod foo --grace-period=0 --force
alias kdelete='kubectl delete --grace-period=0 --force'
的なaliasを登録しておくと良いかもです。
$ kdelete po nginx-test
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "nginx-test" force deleted
この辺りの詳細はこの記事がわかりやすかったです。
🔴 その他知っていると便利そうなこと
kubectlのhelpを活用する
kubectlのhelpにはExampleがいくつか載っているのですが、CKADで出題されるレベルの操作は大体exampleに載っていそうな気がします。
watchコマンド
一定間隔でコマンドを叩いてくれます。
$ watch kubectl get pod
--
Every 2.0s: kubectl get pod cs-258263388927-default-boost-v5mmd: Sun Feb 14 02:41:35 2021
NAME READY STATUS RESTARTS AGE
foo-6bfc595996-mvlzp 1/1 Running 0 13m
foo-6bfc595996-qqtct 1/1 Running 0 13m
nginx-6799fc88d8-kw8vl 1/1 Running 0 32s
nginx-6799fc88d8-zvm6f 1/1 Running 0 32s
nginx-test 1/1 Running 0 71m
vimrc
空白とタブが混在するとyamlのエラーを吐くのでタブが空白2つとなるようにしました。
また、kubectlでは文法エラーなどある場合に行番号を教えてくれるので、行番号を表示するようにすると便利です。
:set nu
:set et
:set ts=2 sts=2 sw=2
全ネームスペースのリソースを取得する
具体的な問題内容は言えないですが、クラスタ上の全podから対象のpodをネームスペースを跨いで探す...などの操作が必要になるケースも存在するかと思います。
その場合は-A
フラグを利用すると良いです。
$ kg po
NAME READY STATUS RESTARTS AGE
foo-6bfc595996-mvlzp 1/1 Running 0 70m
foo-6bfc595996-qqtct 1/1 Running 0 70m
nginx-6799fc88d8-kw8vl 1/1 Running 0 58m
nginx-6799fc88d8-zvm6f 1/1 Running 0 58m
nginx-test 1/1 Running 0 129m
$ kg po -A
NAMESPACE NAME READY STATUS RESTARTS AGE
default foo-6bfc595996-mvlzp 1/1 Running 0 70m
default foo-6bfc595996-qqtct 1/1 Running 0 70m
default nginx-6799fc88d8-kw8vl 1/1 Running 0 58m
default nginx-6799fc88d8-zvm6f 1/1 Running 0 58m
default nginx-test 1/1 Running 0 129m
kube-system calico-node-59kbw 1/1 Running 0 3d14h
kube-system calico-node-lkv9f 1/1 Running 0 3d14h
kube-system calico-node-vertical-autoscaler-7bcd8dd657-dkbkk 1/1 Running 0 3d
kube-system calico-node-xshnf 1/1 Running 0 3d14h
kube-system calico-typha-69b5ddffb9-624b9 1/1 Running 0 3d14h
kube-system calico-typha-horizontal-autoscaler-9db848dc5-gx5m8 1/1 Running 0 3d
kube-system calico-typha-vertical-autoscaler-66f498f45d-dznf4 1/1 Running 0 3d14h
...
tmux screen などを活用する
私は使用していないですが、使用すると場合によっては時短につながるかもしれません。
explainコマンド
yamlの文法について調べることができます。
例えば、podのsecurityContextあたりの書き方が知りたいとき、以下のコマンドを叩くことでわかるでしょう。
$ k explain po.spec.securityContext --recursive
KIND: Pod
VERSION: v1
RESOURCE: securityContext <Object>
DESCRIPTION:
SecurityContext holds pod-level security attributes and common container
settings. Optional: Defaults to empty. See type description for default
values of each field.
PodSecurityContext holds pod-level security attributes and common container
settings. Some fields are also present in container.securityContext. Field
values of container.securityContext take precedence over field values of
PodSecurityContext.
FIELDS:
fsGroup <integer>
runAsGroup <integer>
runAsNonRoot <boolean>
runAsUser <integer>
seLinuxOptions <Object>
level <string>
role <string>
type <string>
user <string>
supplementalGroups <[]integer>
sysctls <[]Object>
name <string>
value <string>
windowsOptions <Object>
gmsaCredentialSpec <string>
gmsaCredentialSpecName <string>
runAsUserName <string>
ちなみに、Objectの中身を再帰的に展開したくない場合や、その階層の詳細を知りたい場合は--recursive
フラグをつけなければ良いです。
🔴 最後に
CKADの試験の流れや、CKADで使えそうなテクニックについて、自分が実践したものについて説明しました。
実際に試験を受けてみて、問題数の多さや、文章量の多さから、早く正確に確実に解くことが重要だととても感じました。
これからCKADを受けようと思っている方の参考に少しでもなれれば幸いです。