イラストでわかるDockerとKubernetesを読んで学んだこと

Kubernetesを勉強したいと思い立って始めたばかりの記録です。

公式サイトの[kubectlチートシート](https://kubernetes.io/ja/docs/reference/kubectl/cheatsheet/)を見ながら手を動かして学んでいたのですが、イメージを図で頭にいれたいと思って書籍に手を出しました。
それが、[イラストでわかるDockerとKubernetes](https://www.amazon.co.jp/%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8BDocker%E3%81%A8Kubernetes-Software-Design-plus-%E5%BE%B3%E6%B0%B8/dp/4297118378)です。
読みながら、一通り絵を描いたりコマンドを打ったり確認することでイメージがつかめたのでその学びを記録します。

## この本の簡単な構成
DockerとKubernetesの両方の話がメインです。
どちらも丁寧に関係図を用意することで、イメージがつかめる内容になっています。
Dockerの仕組みを先に知ることで、Kubernetesでの比較がしやすく、Kubernetesのたくさんのリソースの中でも重要なポイントを抑えているのが心強いです。
ただ、あくまで概要。実業務や資格試験を考えている人は、次なる学習が必要な内容です。

## 環境用意のハードルが少しある
ある程度Linuxに精通していることを前提とした書籍と感じました。
Dockerコマンド操作に必要な準備に本書でも、Ubuntu20.04を前提としています。
もちろん、MacやWindowsでも環境用意すればできるでしょうが、それによって、のちのコマンド操作で注意する点があります。

### overlay2の体験
[overlay2](https://docs.docker.com/storage/storagedriver/overlayfs-driver/)を体験するのにコマンド操作が紹介されています。
しかし、Linux系OS（かつ対応Kernel）でないと、マウントの際にファイルシステムが未対応となってつまずくのが注意です。
そこで、ハンズオンをしている方の記事をあわせて参考にすると理解が進むと思います。

https://www.mtioutput.com/entry/docker-overlayfs-tutorial

https://tech-lab.sios.jp/archives/21103

このあたりが参考になると思います。

### runcの実行は環境次第
[OCI(Open Container Initiative) Runtime Specification](https://github.com/opencontainers/runtime-spec) の学びに `runc` でのコマンド体験があります。
このruncもすんなり入る環境をもっていないとつまずくなと感じました。
続けて操作する `namespece` も同様です。

よって、こちらの資料を補完として活用しました。

https://www.slideshare.net/KoheiTokunaga/ocirunc

https://medium.com/nttlabs/runc-overview-263b83164c98

### 理解が進んだ箇所
- Dockerを通じてコンテナレイヤを学ぶ

https://qiita.com/okmtz/items/f8231c83134a6363647b

こちらの記事にあるようにコンテナのレイヤ構造のイメージが掴めると、Dockerfileの扱いにも気を使えるようになります。
本書でもDockerの章の中で丁寧に記載がありました。

・Kubernetesの仕組みの中心であるOCIやCRIの使われ方が見えてくる

イメージ図で求めたいてのはここだったので、大変役に立ちました。
CRIがわかると、CNIやCSIといった用語にも反応できるようになります。
この辺りは英単語として覚えた方が意味がそのままなので丸暗記がよさそうでした。

- kubectl環境が用意できればリソースの組み合わせが見えてくる

たくさんのyamlファイルを用意する理由が、実際にDeployment, Serviceと用意するとわかってくるのでよかったです。
特に[公式のチートシート](https://kubernetes.io/ja/docs/reference/kubectl/cheatsheet/#%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%97)にある `kubectl api-resources` のコマンドを使って一覧を見ると全体像が掴めてよく、いろんなリソースがあることが見えてkubernetesの奥深さが見えます。

### コマンド体験のつまずきまとめ
実際にコマンドを打って初心者あるあるをしてしまったところを記録します。

#### 名前がかぶるったときの対処を考える
```yaml
❯ kubectl apply -f nginx-deployment3.yaml
Warning: resource deployments/nginx-deployment is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.
The Deployment "nginx-deployment" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"nginx"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable
```

これは、ファイルを指定してのapply例です。
記述が間違っている場合は、行の警告が出るので見直せますが、このエラーの場合はどうすればいいのかわからずつまずきました。
結果は、ファイルの中身に記載していたDeploymentがすでに別で使われていることが原因。

この何かと名前の被りでつまずくとういのがkubernetesを使ったときの特徴に思います。
podsでかぶっているのかnodeなのかは適切に見ていきたいところです。
書籍に沿ったテスト操作でも本番環境も想定すると知っておきたい箇所に感じました。

https://qiita.com/tkusumi/items/0bf5417c865ef716b221

その点はこちらの記事で補完して内容理解に努めました。

#### `kubectl delete pods` を覚える
```yaml
/var/tmp/20220211 ❯ kubectl run --rm -it svc-client --image=cetnos:8 --restart=Never -- curl http://nginx-service:8080            23:40:38
Error from server (AlreadyExists): pods "svc-client" already exists
```
コマンドの意味は省略しますが、こちらは、すでにpodsが存在している場合です。
これは、podsの名前被りがおきているのですが、いざ削除するときのコマンドを知らないとハンズオンとしてはハマります。
タイトルの通りで `kubectl delete poods xxx` と名前を指定するとよいでしょう。

なお、このとき原因究明のためにはpodsのdescribeを見るとよく、その中の `EVENT` 行を見ることや
`kubectl get pods` で `STATUS` を見るとわかることが学べました。`ImagePullBackOff` とあり、正常な起動でないと判断。

```yaml
❯ kubectl get pods
NAME         READY   STATUS             RESTARTS   AGE
svc-client   0/1     ImagePullBackOff   0          12h
```

今回の原因はなんと、起動するイメージをtypoしていたことが原因でしたが、名前がかぶっているのでやりたいことを満たすにはpodを消す必要があるということでした。

```
## ~ ここまで省略
Events:
Type    Reason   Age                  From     Message

---

Normal  BackOff  61s (x496 over 12h)  kubelet  Back-off pulling image "cetnso:8"
```
Eventsより、 `centso` とtypoしていることがわかります。こういう切り分け知識が試すと見えてきます。

### 次の展望
この書籍によって、cluster-ipの存在（外部接続の必要性）や様々なリソースによるロードバランサの仕組みもざっくり学べます。
あとは、それを実際に使っていくだけなので、yamlをどんどん書いていけそうです。