CKADの試験概要と、1秒でも早く問題を解くために実践したこと


# 本記事の対象読者

- これから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を受験する人の少しでも参考になれば幸いです。

ただ、[こちら](https://docs.linuxfoundation.org/tc-docs/certification/lf-cert-agreement)の機密保持契約があるため、具体的な問題内容などについては触れません。



# 🔴 試験について

## 申し込み

Linux Foundation の cyber monday を利用して学習コース？込みで$199で受験をしました。
https://training.linuxfoundation.org/cyber-monday-2020/
付属のコースは利用しませんでした。

## 試験のための準備


### 試験場所

以下の条件を満たす必要があります。

- 綺麗な作業エリア
- 壁に貼り付けられた紙が無い
- 明るい
- 後ろが明るすぎない
- 公共スペースではない

私は自室で受けました。会社の会議室などでも良さそうです。
詳しくは[こちら](https://docs.linuxfoundation.org/tc-docs/certification/tips-cka-and-ckad#acceptable-testing-location)をご覧ください。



### 身分証明書

パスポートが無難だと思います。
詳しくは[こちら](https://docs.linuxfoundation.org/tc-docs/certification/tips-cka-and-ckad#id-requirements-to-take-the-exam)をご覧ください。

私はパスポートを利用しました。



### 持ち込み可能なもの

**飲み物**
ラベルを剥がした透明なボトルであれば問題ないと思います。

**サブモニター**
多分一つなら使えるらしいです。
試験監督にサブモニター使う?的なこと聞かれましたが、私は利用しませんでした。
公式ドキュメントをサブモニターに表示しておくというのもありだと思いました。

**キーボード・マウス**


### システム要件


- ブラウザはchrome
- 移動可能なウェブカメラ
- マイク
- 十分な通信帯域

試験監督に試験中の状況を共有する必要があるため、カメラとマイクが必要になります。
机の周辺の様子を確認してもらう必要があるため、カメラは移動可能である必要があります。
私は、MacBook内臓のカメラ、マイクを利用しました。
とは言っても、直接試験監督と会話したり顔を合わせたりすることはなく、一方通行なので、こちら側の出力音声はミュートにしていました。
（しないとめちゃくちゃハウリングしました。）



### chrome拡張のインストール

試験を使用する時にこちらの拡張を使用します。
予めインストールしておく必要があります。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422521/e7142477-1d40-4379-a385-610e6c1a7170.png">




### 予備のマシン

こちらはあればで大丈夫ですが、用意しておくのが無難だと思います。
私の場合、はじめに会社の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
https://www.udemy.com/course/certified-kubernetes-application-developer/

こちらは全て英語です。月2〜3回くらいで定期的に行われるUdemyのセールで買いました。
ミュートしながらでも概要は理解できると思うくらいに動画の図が非常にわかりやすかったです。

1時間分×2セット分の mock exam が付属しているので一通り理解してからの力試しとしてとても良いと思いました。
難易度も内容も本番に近い印象です。



### CKAD Exercises
https://github.com/dgkanatsios/CKAD-exercises

問題と回答がセットになった無料問題集です。試験範囲を網羅しているだけでなく、受験に不必要な知識はほとんど含まれていない、まさにCKAD特化といったイメージです。
また、本番で必要なリソースの操作方法は、ここで十分に身に付くかと感じました。

個人的にはこれがCKADの対策としては最も役に立ったと思っており、4周しました。
先ほども申し上げたとおり、CKADは最短時間で指定されたリソースを構築することなので、毎回時間を測って行いました。




### Kubernetes完全ガイド

https://www.amazon.co.jp/dp/B07HFS7TDT

まさに教科書と呼べる内容で、kubernetesを学習する人から中級者まで全ての方におすすめできる超良本です。
理想はCKADの勉強を始める前にざっと目を通しておくことですが、かなり量が多いということと、CKAD合格には必要のない知識もたくさん含まれているため、
CKADを最短で取得することが目的なのであれば、上記のUdemyとCKAD Exerciseを一周してからわからないところだけを本書で見直すという手法が良さそうだと思います。
私はCKADを受験する目的が「kubernetesの理解度を上げるため」だったので、最初に一通り時間をかけて目を通しました。







## 学習時間

30時間くらい。
このうちの大半は完全ガイドを読んでいました。





## 試験範囲

https://github.com/cncf/curriculum
ここに載っています。具体的には、CKAD Exerciseの通りのような印象です。

ちなみに先ほどおすすめ教材で説明した[Udemy](https://www.udemy.com/course/certified-kubernetes-application-developer/)では、

- Ingress
- TaintとToleration

が説明されていました。
私が受験したときはこのあたりの知識はなくても問題なかったなという印象でした。CKAD Exerciseにも含まれていません。
なので、もし最短でCKADを合格することだけを考えるのであれば飛ばしても問題ないかもしれません。
ただ必ず出ないとは言い切れないですし、kubernetesを利用する上ではどちらも非常に重要なので理解しておくことをおすすめします。












## 学習環境

私はGoogle CloudのKubernetes Engine (GKE)を利用しました。
GCPの無料枠で、0円で利用することができました。
欠点としては、GKEは試験で利用されるバージョンを利用できない可能性が高いので試験環境バージョンを再現することはできないということくらいです。
私が受験したときは試験環境のバージョンが1.20でしたが、そのときGKEで提供されているバージョンの最新が1.19でした。
CKADで出題される基本的な操作が変わるような破壊的変更はそこまで発生しないと思うので、少しくらい古いバージョンでも問題ないかと思います。
（ちなみに試験に使用されるバージョンは、kubernetesの最新のマイナーバージョンに4~8週間遅れて追従されるようです。詳しくは[こちら](https://docs.linuxfoundation.org/tc-docs/certification/faq-cka-ckad-cks#what-application-version-is-running-in-the-exam-environment)。）

また、GKEでは**試験範囲のNetworkPolicyがデフォルトで無効になっている**ので、試したい場合はコンソールから手動で有効にする必要があります。

![スクリーンショット 2021-02-14 9.57.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422521/fbef178e-d753-e221-ac36-4aa820d6f37d.png)

自分の手元の環境を汚したくないのでCloudShellを利用しました。
ブラウザ上からk8sクラスタに接続できる仮想環境をボタン一つで立ち上げることができるのでとてもオススメです。

![スクリーンショット 2021-02-14 10.13.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422521/3a7ccd3c-b6c0-d5a8-4b1a-7ce6584532d7.png)


# 🔴 １秒でも早く問題を解くために実践したこと


## 一からyamlを書かない。

具体的には、
podを作成するときは、`kubectl run`から、
serviceを作るときは`kubectl expose`から、
hpaを作るときは`kubectl autoscale`から、
deploymentやnsなどその他リソース作るときは`kubectl create`から作成するべき
などということです。
これらは他でも詳しく書かれているかと思うのでここでは説明は省略します。

ただし、中にはkubectlから作成できないリソースもあるので、そのような場合には公式ドキュメントのサンプルのyamlから作成しました。
それらのパターンを洗い出し、リソースを作成するために必要な最小のyamlへのリンクをブックマークに登録しておくことがオススメです。

## ドキュメントから欲しい情報を最速で取得


### ブックマークを活用する

本番でドキュメントを読み漁るのは時間がもったいないので、あらかじめ必要なだけブックマークを登録しておくことが非常に重要です。

私が登録したリンクは以下の通りです。

[PersistentVolumeClaims](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims)
[Claims As Volumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#claims-as-volumes)
[Persistent Volumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistent-volumes)

[Using Secrets as files from a Pod](https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod)
[Using Secrets as environment variables](https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables)
[configMapKeyRefのサンプル](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#use-configmap-defined-environment-variables-in-pod-commands)
[Populate a Volume with data stored in a ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#populate-a-volume-with-data-stored-in-a-configmap)
[configmap 全部環境変数として](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#configure-all-key-value-pairs-in-a-configmap-as-container-environment-variables)

[Define a liveness HTTP request](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-a-liveness-http-request)
[Define a liveness command](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-a-liveness-command)
[Define readiness probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes)

[kubectlチートシート](https://kubernetes.io/ja/docs/reference/kubectl/cheatsheet/)
[Set the security context for a Pod](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod)
[emptyDir configuration example](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod)
[The NetworkPolicy resource](https://kubernetes.io/docs/concepts/services-networking/network-policies/#networkpolicy-resource)
[Ingressリソースの最小構成](https://kubernetes.io/ja/docs/concepts/services-networking/ingress/#ingress%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9)
[sa pod](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#use-the-default-service-account-to-access-the-api-server)

[NodeAffinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity)
[tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/#concepts)

### 検索速度を上げる

公式ドキュメントのブックマークをしていない箇所の情報が必要になる場合もあるかと思います。
その場合は、(macの場合は)
`Cmd+F + "kind: {KIND}"`
でyamlに最速でたどり着ける確率が上がります。

例えば、configmapの内容をpodに環境変数として流し込む方法を調べる場合を想定してみます。
まずは短縮記法を使用してそれっぽい感じで検索します。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422521/e8b667d3-9ff5-e4de-3cc7-91855cc4880e.png">

kubernetesのドキュメントは結構検索の精度が高くだいたい一番上にヒットした記事を見れば欲しい情報があることが多いです。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422521/4e3c139c-235c-2622-2b69-e7ee44919b32.png">

一番上の記事de、今回はpodのyamlを書くので、`kind: Pod`で検索します。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422521/c750c401-d9a0-6686-e02b-e1b5fd4ce993.png">

**それっぽいpodのyamlが複数ヒット**します。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422521/bce05bed-3a6b-8822-40a3-9edc96ed43a4.png">


10秒もしないうちに欲しい情報にたどり着くことができました。


ちなみに、kindについては後述の

```
$ kubectl api-resources
```
で調べることができます。

## alias

私が本番で利用したaliasは以下の通りです。
（私は試していないですが、macであればこれらをユーザ辞書などに登録しておけば速攻で環境構築ができるかもです。ルール的に問題ないかは不明。）

```sh
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` でリソースの情報が欲しい場合がよくあるかと思うのですが、指定したワードが大文字なのか小文字なのか考えるのが面倒だからです。



![スクリーンショット 2021-02-14 23.21.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422521/c6fa2619-9d2d-7d99-f0bf-361b4eacf1fa.png)

![スクリーンショット 2021-02-14 23.28.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422521/c5b37c54-3650-5ee4-db18-63318f5b8ccf.png)

（ちなみに上記の例のようにpodがどこのnodeに乗っているかを知りたい場合は`kg po -owide`が最短かと思います。）


podやdeployment、serviceを作成するような場合にEndpointに対してhttpの疎通チェックすることがよくあるかと思うのですが、そのために毎回busyboxでpodをたてるのも大変だし時間がかかります。
そのため、podとの接続チェックの`coch`が地味に便利です。（名前は各自好きなものを利用すると良いと思います）

```sh
$ 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

以下公式ドキュメントの引用です。

---

```sh
source <(kubectl completion bash) # 現在のbashシェルにコマンド補完を設定するには、最初にbash-completionパッケージをインストールする必要があります。
echo "source <(kubectl completion bash)" >> ~/.bashrc # bashシェルでのコマンド補完を永続化するために.bashrcに追記します。
```

また、エイリアスを使用している場合にもkubectlコマンドを補完できます。

```sh
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は省略可能です。
例えば、以下はどれも同じです。

```sh

kubectl get pods
kubectl get pod
kubectl get po
```

短縮記法やkindなどが思い出せないときはこちら。

```sh

$ kubectl api-resources
```

<details> <summary>結果</summary><div>

```
$ 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
```

</div></details>

## podを削除するときは--forceフラグを利用する

たまにpodを削除する時にかなり時間がかかる場合があります。
`--force`フラグをつけるとだいたいすぐに消えてくれます。
多くの記事では`--grace-period=0`も同時につけているのをみますが、無くてもすぐに消えているような気がします...。（偶然?）

```sh
$ kubectl delete pod foo --grace-period=0 --force
```

```sh
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
```

この辺りの詳細は[この記事](https://qiita.com/superbrothers/items/3ac78daba3560ea406b2)がわかりやすかったです。

# 🔴 その他知っていると便利そうなこと



## kubectlのhelpを活用する

kubectlのhelpにはExampleがいくつか載っているのですが、CKADで出題されるレベルの操作は大体exampleに載っていそうな気がします。

![スクリーンショット 2021-02-15 0.17.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422521/7f166460-8204-5bd3-c02b-6f4ec131a55f.png)



## watchコマンド

一定間隔でコマンドを叩いてくれます。

```sh
$ 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では文法エラーなどある場合に行番号を教えてくれるので、行番号を表示するようにすると便利です。


```vim
:set nu
:set et
:set ts=2 sts=2 sw=2
```

## 全ネームスペースのリソースを取得する

具体的な問題内容は言えないですが、クラスタ上の全podから対象のpodをネームスペースを跨いで探す...などの操作が必要になるケースも存在するかと思います。
その場合は`-A`フラグを利用すると良いです。

```sh

$ 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を受けようと思っている方の参考に少しでもなれれば幸いです。