CKA合格を目指しながら学ぶKubernetes

# はじめに
2022年11月、CKAを取得しましたので振り返りとKubernetes学習に有用なコンテンツをまとめてみました。これからKubernetesを学習される方やCKA取得を目指されている方の参考になれば幸いです。

https://www.credly.com/badges/a5489712-5e40-4e22-b87b-e46bdf4226d7

# CKA(Certified Kubernetes Administrator)
## 試験概要
CKA(Certified Kubernetes Administrator)試験は、Linux FoundationとCloud Native Computing Foundation（CNCF）がKubernetesエコシステムの開発を支援するための取り組みの一環として提供している認定試験です。本試験はKubernetes管理者として求められるスキル、知識、および能力を体系的に身に付けることができるように設計されています。CKA試験はコマンドラインからKubernetesクラスタ上の問題を解決するパフォーマンスベースの認定試験であり、クラウドネイティブ/DevOpsの分野で取得できる最も実践的な認定資格の1つです。

不合格だった場合でも1回無料で再受験可能です。ただし1回目の受験を欠席した場合、この再受験の権利は付与されないので注意ください。
CKA認定の有効期限は3年間です。再認定には有効期限の3年間のうちに再度認定試験を受験して合格する必要があります。

その他の試験概要は以下のとおりです。
|試験名|CKA-JP|
|---|---|
|受験形式　  |オンライン（[一定の条件](https://lpi.or.jp/k8s/faq/index.shtml#preparation)の下、自宅など希望する場所での受験が可能）  |
|受験料　  |60,200円 |
|試験時間　  |120分 |
|合格に必要な正答率　  |66% |
|認定証　  |PDFとデジタルバッジ |
|ソフトウエアバージョン　  |Kubernetes v1.25 |
|受験結果　  |受験後24時間以内に登録したメールアドレス宛に通知 |

https://training.linuxfoundation.org/ja/certification/certified-kubernetes-administrator-cka/

## 試験範囲
|対象領域|割合|
|---|---|
|クラスタのアーキテクチャ、インストール、構成　  |25%  |
|サービスとネットワーク|20%  |
|トラブルシューティング|30%  |
|ワークロードとスケジューリング|15%  |
|ストレージ|10%  |

特に**トラブルシューティング**は割合が高いので下記内容については重点的に対策を行うことが求められます。
- クラスタとノードのロギング評価
- アプリケーションの監視
- コンテナの標準出力と標準エラーログの管理
- アプリケーション障害のトラブルシューティング
- クラスタ コンポーネント障害のトラブルシューティング
- ネットワークのトラブルシューティング
- etc...

また、本試験はKubernetes管理者としての試験ですので、`kubectl`コマンド以外にも以下の知識が必要です。
- kubeadm
- kubelet
- etcd
- CoreDNS
- systemctl
- journalctl

## 試験環境
実際の試験では、約20問を2時間で回答する必要があります。リモートデスクトップ環境で試験を行うため動作がもっさりしており時間がタイトな試験になります。

2022年12月現在、試験は`Kubernetes v1.25`に基づいています。CKA試験環境はKubernetesのマイナーバージョンリリースから約4〜8週間以内に、最新のKubernetesバージョンに合わせて調整されます。

受験時の注意点については[Candidate Handbook](https://docs.linuxfoundation.org/tc-docs/certification/lf-handbook2)、[Frequently Asked Questions](https://docs.linuxfoundation.org/tc-docs/certification/faq-cka-ckad-cks)、[Important Instructions](https://docs.linuxfoundation.org/tc-docs/certification/tips-cka-and-ckad)を参照ください。例えば以下のような重要情報が記載されているので試験までに一読しておくことをおすすめします。

- 試験環境 (6 Clusters)
    |Cluster|Members|CNI|Description|
    |---|---|---|---|
    |k8s|1 master, 2 worker|flannel|k8s cluster|
    |hk8s|1 master, 2 worker|calico|k8s cluster|
    |bk8s|1 master, 1 worker|flannel|k8s cluster|
    |wk8s|1 master, 2 worker|flannel|k8s cluster|
    |ek8s|1 master, 2 worker|flannel|k8s cluster|
    |ik8s|1 master, 1 base node|loopback|k8s cluster|

- 使用できるディスプレイは1枚のみ（マルチディスプレイは使用不可）
- ベースシステムと全てのクラスターノードで下記はインストールおよび設定済み
    - `k=kubectl`のエイリアスとコマンド補完
    - `jq`, `curl`, `wget`, `man`など
- 試験環境のイメージ
    ![LF_RemoteDesktop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379973/12035b25-adde-a62c-8ef2-ba469b54d3b8.png)

## 受験当日の試験開始までの流れ
### フロー
- 試験予約時間の**30分前**に試験環境にアクセスできます。
- はじめに専用のセキュアブラウザをダウンロードしインストールします。
- 次に、ID(運転免許証など)と顔写真で本人確認を行います。
    - 試験の登録名は英語でしたが、運転免許証（アルファベット表記なし）でもID確認を行えました。
- ID確認完了後、試験官とlive chatがつながります。
    - 机の上、ディスプレイ、机の下などあらゆる角度から怪しいものがないか、カメラで写すように指示されます。
- 最後に試験のチュートリアルを行い、それが完了すると2時間の試験が開始されます。
### 補足
- コップ or ペットボトルで飲み物（水のみ）を持ち込めます。
- 試験中に口に手を当てることはできません（口を隠すことはできません）
- もちろん声を出すこともできません。

# 受験対策
CKA合格やKubernetes学習を目的とした勉強方法について記載します。

## Udemy - Certified Kubernetes Administrator (CKA) with Practice Tests
CKA対策教材の中で最も有名と言っても過言ではないUdemyのCKA対策講座です。CKAの試験範囲をほぼ羅列しています。本コースは、CKAの試験範囲となる各コンポーネントの解説と実試験に近いCKA模擬試験に取り組むことができます。ハンズオンが非常に充実しているので、CKA受験に限らず純粋にKubernetesを学びたい人向けにも大変おすすめできる教材です。
Udemyは月1-3回ほどのペースで最大 94％ 程度割引になるセールを開催しています。急ぎでない場合はセール中に講座を購入することをおすすめします。

https://www.udemy.com/course/certified-kubernetes-administrator-with-practice-tests/

## kubernetes.io
Kubenertes の公式ドキュメントです。ドキュメントは試験中に参照できるため、普段の学習でもわからないことがあったら参照する習慣をつけておくことが重要です。ドキュメントは量が膨大なのですべてを読むことは難しいですが、おおよそどのページにどのようなことが書いてあるのかを把握しておくとよいでしょう。

2022年12月現在、試験実施形式が画面共有形式から**リモートデスクトップ形式**に変更となったため以前のように**事前に作成したブックマークリストを試験中に使用することができません**。試験中にサイト内検索機能を用いて欲しい情報をドキュメントから検索する能力も必要になります。ですので繰り返しになりますが、普段の学習からドキュメントを参照する癖をつけておきましょう。

https://kubernetes.io/ja/docs/home/

## Kubernetes完全ガイド 第2版
その名のとおり完全ガイドで、本書の内容を全て理解することで**完全に理解した**状態になれます。Kubernetesを網羅的に解説した日本語の書籍は実質これしかないので、Kubernets初心者から既に運用されている方にもおすすめな本です。本書記載のコマンドやyamlは[GitHub](https://github.com/MasayaAoyama/kubernetes-perfect-guide)で公開されており、動作確認しながら読み進めることができます。試験範囲外の内容も含まれているので、最初から読み進めるのではなくUdemyや公式ドキュメントを見てもわからなかったときに参照する辞書的な使い方がいいかもしれません。

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

## Killer Shell
実際の試験環境を模擬した試験シミュレーターです。試験に申し込む（受験料を支払う）とKiller Shell上での2回分の試験環境を使用できます。試験環境のみ購入する場合は29.99€です。Killer Shellについては以下のとおりです。
- 試験環境(1回36時間)を2回使用可能
- 25問からなる模擬試験（2回とも問題は同じ）
- 2時間のタイマー付きで試験を体験できる。時間経過後も残り34時間は試験環境で学習できる。
- 模擬試験は実際の試験よりかなり難しいので、試験直前の仕上げに使用するのがおすすめ。
- 試験終了後、各問題の部分点を含む詳細な採点を行える。
- 丁寧な問題の解説も用意されており、100点になるまで繰り返しコマンドラインで操作ができる。
- UIや機能が実際の試験環境とほぼ同様のため、リモートデスクトップ環境上での操作に慣れることができる。
    - **問題文/ブラウザ/ターミナル間のコピペは普段お使いのショートカットと異なる**ため確認必須
    - 上記アプリたちを1枚のディスプレイ上にどのように配置して問題を解いていくかまで決めておくとさらにGood
- 試験環境はリセット可能。

https://killer.sh/

# Kubernetesにおける必須知識
## vi操作
Kubernetesではyamlファイルを編集する場面が多々あるので、vi操作に慣れておく必要があります。
最低限必要なvi操作を以下に列挙します。

|モード| コマンド      | 挙動 |
|:--:|:-----------------:|:------------------|
|インサートモード| i             | カーソルの位置からインサートモード |
|ビジュアルモード| v | ビジュアルモードへ（複数行のインデント修正に使用） |
| その他 | ESC | コマンドモードに戻る |

| カテゴリ| コマンド      | 挙動 |
|:-----------------:|:-----------------:|:------------------|
|移動| j | 下に移動 |
|| k | 上に移動 |
|| h | 左に移動 |
|| l | 右に移動 |
|| :<数値> | <数値>で指定した行へ移動 |
|削除| dd | カーソルがある行を削除 |
|| :<行番号>d | 特定の行を削除 |
|undo&redo| u | undo |
|| Ctrl + r | redo(undoをundo) |
|検索| /<検索文字> |<検索文字>を検索する。(n：次の検索結果、N：前の検索結果) |
|ファイル関連| :w | 保存 |
|| :w! or ZZ | 保存して終了 |
|| :q! | 保存せずに終了 |

## よく使うkubectlコマンド集
全ては書ききれませんが、よく使うkubectlコマンドを記載します。
コマンドに出てくる`k`は`kubectl`のショートカットのaliasです。実際の試験時でも使えます。

### リソースの確認：kubectl get
最も簡単にリソース一覧情報を取得するには`kubectl get`を使用します。`get`コマンドの引数には「リソース種別」と「リソース名(オプション)」をとり、リソース名が指定されている場合には、その名前のリソースに関する情報のみを取得します。
```bash
[controlplane]$ k get リソース種別 リソース名(オプション)
[controlplane]$ k get pods # Podの一覧を表示
[controlplane]$ k get pods my-pod # 特定のPod「my-pod」の情報のみ表示
[controlplane]$ k get all -A # 全てのネームスペースのほぼ全ての種類のリソースを表示
# ネームスペース「myns」内で、label1=val1とlabel2ラベルを持つPodを表示
[controlplane]$ k get pods -n myns  -l label1=val1, label2 --show-labels

# 既存リソースをyamlへ書き出し。リソースに影響はありません。
[controlplane]$ k get po mypod -o yaml > mypod.yaml
```

### リソースの詳細情報の確認：kubectl describe
`kubectl get`で確認できる情報に加えて、リソースに関連するイベントなど、より詳細な情報を確認することができます。
たとえばPodを指定した場合、ボリュームのセットアップやイメージの取得状況などコンテナのライフサイクルに関する情報などが表示されます。Podが正常にRunning Statusにならない場合など、トラブルシューティングをする際はまず`kubectl describe`で状態を確認します。
```bash
[controlplane]$ k describe リソース種別 リソース名
[controlplane]$ k describe pod my-pod
[controlplane]$ k describe deployment my-deployment
[controlplane]$ k describe node my-node
[controlplane]$ k describe service my-service
...
```

### Pod作成：kubectl run
```bash
# podを作成（最もシンプルなケース。pod名=pod1, image=nginx）
[controlplane]$ k run pod1 --image=nginx 

# podを作成（pod名=pod2, image=nginx, port=5701を公開）
[controlplane]$ k run pod2 --image=nginx --port=5701 

# podを作成（pod名=pod3, image=nginx, ラベル app=hazelcast,env=prodを付与）
[controlplane]$ k run pod3 --image=nginx --labels="app=hazelcast,env=prod" 

# 【重要】 --dry-runオプション　実際にpodは作らずにマニフェストだけを作る
[controlplane]$ k run pod4 --image=nginx --dry-run=client -o yaml > pod4.yaml
[controlplane]$ cat pod4.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod4
  name: pod4
spec:
  containers:
  - image: nginx
    name: pod4
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
```

### yamlからリソース作成：kubectl apply
```bash
# yamlからリソースを作成
[controlplane]$ k apply -f pod4.yaml
pod/pod4 created
[controlplane]$ k get po pod4
NAME   READY   STATUS    RESTARTS   AGE
pod4   1/1     Running   0          2m23s

# リソース削除
[controlplane]$ k delete -f pod4.yaml
pod "pod4" deleted
```
yamlファイルを編集して再度applyすることでリソースを編集することもできます。

### 様々なリソースの作成：kubectl create
頻出するほとんどのリソースを作成可能。`--dry-run=client -o yaml`も使用可能。
ただし、DaemonSet, ReplicaSet, PersistentVolume, PersistentVolumeClaim, NetworkPolicyなどは作成できないので注意。特に`kubectl create`が利用できないリソースについては、公式ドキュメントのyamlをベースに編集し`kubectl apply`でリソースを作成します。DaemonSetやReplicaSet用のyamlはDeployment用に生成したyamlを編集する形で作成することもできます。
```bash
# deployment
# deployment名=deployment1, image=busybox, pod数=1
[controlplane]$ kubectl create deployment deployment1 --image=busybox 
# deployment名=deployment2, image=busybox, pod数=3
[controlplane]$ kubectl create deployment deployment2 --image=busybox --replicas=3 
# deployment名=deployment3, image=busybox, pod数=1, 5701ポートを公開
[controlplane]$ kubectl create deployment deployment3 --image=busybox --port=5701 

# ingress
# ingress名=my-ingress, foo.com/bar → svc1:8080, TLS証明書はmy-certを使用
kubectl create ingress my-ingress --rule="foo.com/bar=svc1:8080,tls=my-cert"

# namespace
kubectl create namespace my-namespace

# role
# Podリソースに対してget,list,watchを実行できるpod-readerという名前のRoleを作成
kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
# clusterRole
# Podリソースに対してget,list,watchを実行できるpod-readerという名前のClusterRoleを作成
kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods

# rolebinding
# Namespace「myappnamespace」内で、
#「pod-reader」ClusterRoleをユーザー「bob」に付与するrolebinding「bob-pod-binding」を作成
kubectl create rolebinding bob-pod-binding --clusterrole=pod-reader --user=bob --namespace=myappnamespace

# service
# ポート5678で受け付けてポート8080へ転送するservice「my-service」を作成
kubectl create service clusterip my-service --tcp=5678:8080
```

### 利用可能なAPIリソースを一覧表示：kubectl api-resources 
```bash
[controlplane]$ k api-resources 
NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND
bindings                                       v1                                     true         Binding
componentstatuses                 cs           v1                                     false        ComponentStatus
configmaps                        cm           v1                                     true         ConfigMap
endpoints                         ep           v1                                     true         Endpoints
events                            ev           v1                                     true         Event
limitranges                       limits       v1                                     true         LimitRange
namespaces                        ns           v1                                     false        Namespace
・・・・
[controlplane]$ k api-resources | wc -l
57
```

頻出リソースの略称一覧。覚えると操作が早くなるのでおすすめ。
|リソース名| 略称      |
|:--|:-----------------:|
|pod|po|
|replicasets|rs|
|deployments|deploy|
|daemonsets|ds|
|persistentvolumeclaims|pvc|
|persistentvolumes|pv|
|storageclasses|sc|
|configmaps|cm|
|namespaces|ns|
|nodes|no|
|services|svc|
|serviceaccounts|sa|

# まとめ
CKA概要、おすすめ学習コンテンツ、頻出kubectlコマンドについてまとめてみました。Kubernetesを学習される方にとって少しでも参考になれば幸いです。

自分はCKA受験をきっかけにkubernetesを本格的に勉強し始めたのですが、学習を通してKubernetesの面白さや業務で扱うKubernetes環境およびマニュフェストの内容が理解できるようになってきて楽しさを感じています！まだまだ勉強途中のため、間違いや本記事で紹介されていないおすすめ学習コンテンツや便利なコマンドなどがありましたらコメントにて教えていただけると嬉しいです。皆さんもKubernetesを活用して、良いサービスを作っていきましょう。

最後まで読んでいただきありがとうございました！