kubernetesを学ぶ～その４：マニフェスト・コントローラ～

# 目次
1. 前回のあらすじ
2. マニフェストについて
3. コントローラについて
4. 用語について
5. あとがき

# 前回のあらすじ
　前回の[kubernetesを学ぶ～その３～](https://qiita.com/shintoshin_se/items/41075f552cea0eef8a78)は、kubectlについて記載してみた。ほんの一部分だけであったが基本を抑えることが大事だと思う。特に私のようなK8s未経験者にとっては基本を忠実にすることが大事かと。あれ？部活みたい。

# マニフェストについて
　K8sのオブジェクトを生成するためにオブジェクトに対応したAPIやメタ情報をYAML形式やJSON形式で書かれた宣言書のことをいいます。色んな情報ググったり体験談を拝見すると運用ではマニフェストでポッドの起動とかしないみたい。理由としては、運用でよく使うのが「コントローラ」であり、コントローラのマニフェストにポッドの雛形を記述した部分があるからだそうです。なるほど。コントローラについては、別でやろう。

## 形式の選択
　YAML形式か、JSON形式かどちらにしようか検討する時、読みやすさやぱっと見のわかりやすさ（可読性）からYAML形式がよいと思います。

## 書き方
　手始めに書き方を学ぶため、ポッドを起動するマニフェストを作ってみる。ホントはコントローラから作るのがいいんですが、基本を知るということでお許しを。別途やります。
test.ymlは、OpenLiteSpeedのポッドを作るマニフェストです。

```test.yml
apiVersion: v1
kind: Pod
metadata: 
 name: litespeed
spec: 
 containers: 
  - name: litespeed
    image: indeedplusplus/openlitespeed:latest
```

```yml:1行目
apiVersion: v1
→キー（左側）と値（右側）で構成
```

・apiVersionは、オブジェクトが管理されているバージョンを指定します。
※キーや値については、K8s APIリファレンスを確認ください。

あと、よくやってしまうのですが、**:（コロン）の右側に半角スペースが必要です**。
これがないと、正しく認識しません。
※何度も「あれー？ error parsingでたー。あぁ、半角スペースすぅ～(´；ω；｀)」となっちゃった。何か気づく方法ないかな。

さらに、**キーの大文字小文字も一致させないとエラー**になっちゃった。


```yml:2～4行目
kind: Pod
metadata:
 name: litespeed
```

・kindは、クライアントからリクエストを送るときのRESTリソースを表す文字を指定します。ポッド作るようにしたので、Podです。
・metadataは、オブジェクトのメタデータを指定します。必須項目のnameはポッドのオブジェクト名になります。なので、名前空間内で一意にする必要があります。
・metadata:を改行して半角スペースでインデントすると、ネストできます。
ハッシュなので、metadataというキーに対して、{name: litespeed}とハッシュが値になります。

```yml:5～8行目
spec: 
 containers: 
  - name: litespeed
    image: indeedplusplus/openlitespeed:latest
```

・specは、kindで指定した値の仕様を記述します。
・containersは、ポッドで動かくコンテナの起動条件などを記述します。
・nameの左にハイフンがありますが、これは配列を表します。

例の場合、要素数は１つだけ。
ちなみに、imageの左にハイフンをつけると要素数が２つになります。いや、この場合つけないけど。


なお、１つのポッドに２つコンテナが存在するサイドカーの構成では、containersの配列に複数コンテナを記述します。

```yml:複数コンテナの例
spec: 
 containers: 
  - name: litespeed #メインコンテナ
    image: indeedplusplus/openlitespeed:latest
  - name: cloner    #サイドカーコンテナ
    image: maho/c-cloner:0.1
```

その他にもボリュームをコンテナのファイルシステムにマウントする設定や、環境変数をコンテナに設定するキー項目があります。更に学んでいくと使うので、ここでは省略。

# コントローラについて
　コントローラはポッドの実行を制御するオブジェクト。
いくつも種類があって、デプロイメントコントローラやジョブコントローラなどがあります。

## デプロイメントコントローラ
　Webサーバやアプリケーションサーバのようなサービス提供を継続するサーバに適しています。理由としては、ポッドの稼働数や不要なポッドの後始末をするので負荷が増えたり減ったりアクセス変化が激しい機能に向いているのかと。

まずは、デプロイメントコントローラを作ってみます。

```デプロイメントコントローラ作成
D:\Repository\kubernetes\vagrant-kubernetes>kubectl create deployment --image=hello-world hello-world
deployment.apps/hello-world created

確認
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get all
NAME                               READY   STATUS      RESTARTS   AGE
pod/hello-world-7fd49b7477-rgl9v   0/1     Completed   2          40s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.32.0.1    <none>        443/TCP   2d23h

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/hello-world   0/1     1            0           40s

NAME                                     DESIRED   CURRENT   READY   AGE
replicaset.apps/hello-world-7fd49b7477   1         1         0       40s
```

４つオブジェクトができました。
pod/hello-world-7fd49b7477-rgl9vは、ポッド
service/kubernetesは、サービス
deployment.apps/hello-worldは、デプロイメントコントローラ
replicaset.apps/hello-world-7fd49b7477は、レプリカセット
です。

サービスは、別途学ぶとしてレプリカセット？

###レプリカセット
　ポッドの稼働数を目的の数になるように制御するオブジェクトです。
デフォルトでポッドの稼働数は１つだけって設定されています。なので、増やしてみましょう。

```
確認します。
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get pods
NAME                           READY   STATUS             RESTARTS   AGE
hello-world-7fd49b7477-5pm66   0/1     CrashLoopBackOff   4          2m55s

３つに増やします。
D:\Repository\kubernetes\vagrant-kubernetes>kubectl scale --replicas=3 deployment/hello-world
deployment.extensions/hello-world scaled

確認します。
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get pods
NAME                           READY   STATUS             RESTARTS   AGE
hello-world-7fd49b7477-5pm66   0/1     CrashLoopBackOff   5          3m51s
hello-world-7fd49b7477-dkxzv   0/1     CrashLoopBackOff   1          11s
hello-world-7fd49b7477-tzqjh   0/1     CrashLoopBackOff   1          11s
```

増えたー！！！この制御をしているのが、レプリカセットだということです。
※ちなみにSTATUSがCompletedになっていないのは訳があるのでスルーしててください。describeで確認したらLast State:のexitコードは0デス。

もとに戻します。

```
１つになーれ。
D:\Repository\kubernetes\vagrant-kubernetes>kubectl scale --replicas=1 deployment/hello-world
deployment.extensions/hello-world scaled

２つ抹殺されていっています。
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get pods
NAME                           READY   STATUS             RESTARTS   AGE
hello-world-7fd49b7477-5pm66   0/1     CrashLoopBackOff   7          16m
hello-world-7fd49b7477-dkxzv   0/1     Terminating        7          12m
hello-world-7fd49b7477-tzqjh   0/1     Terminating        7          12m

１つ生き残りました。
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get pods
NAME                           READY   STATUS             RESTARTS   AGE
hello-world-7fd49b7477-5pm66   0/1     CrashLoopBackOff   8          20m
```

## ジョブコントローラ
　デプロイメントコントローラで利用したイメージは、メッセージを出力したら終了する処理だったので、コンテナもメッセージ出力、そして終了！というバッチ処理だったので、コンテナ終了する→レプリカセットが目標数の１にしなきゃ！生成！！ってやっていたので、CrashLoopBackOffが表示されてました。describeで確認した内容を見たらそんな感じです。
　バッチ処理にはジョブコントローラです。

まずは、ジョブコントローラを作ってみます。

```
ジョブコントローラ作成
D:\Repository\kubernetes\vagrant-kubernetes>kubectl create job hello-world --image=hello-world
job.batch/hello-world created

確認
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get all
NAME                    READY   STATUS      RESTARTS   AGE
pod/hello-world-b6wg6   0/1     Completed   0          105s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.32.0.1    <none>        443/TCP   3d

NAME                    COMPLETIONS   DURATION   AGE
job.batch/hello-world   1/1           5s         105s
```

pod/hello-world-b6wg6は、ポッド
job.batch/hello-worldは、ジョブコントローラですね。
ジョブコントローラのCOMPLETIONSが1/1になっているので、ジョブが完了していますね。

ジョブ消します。

```
ジョブさようなら
D:\Repository\kubernetes\vagrant-kubernetes>kubectl delete job hello-world
job.batch "hello-world" deleted

確認
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.32.0.1    <none>        443/TCP   3d
```


# 用語について

・**REST**
　REST(REpresentational State Transfer)はWebサービスの設計モデルです。このモデルで作ったサービスのURIにHTTPメソッドでアクセスすることでデータの送受信を行います。
・**サイドカーコンテナ**
　主となるコンテナと共にそれを補助する役割を果たすコンテナです。

# あとがき
　アーキテクチャを把握しながらやっていたので、結構時間がかかったなー。Hello-worldのイメージ使ってたらSTATUSがCompletedにならなかったので原因調査をずーっとしてたｗ。色々調べたりしてコントローラの使い分けかーって身を持って体験したので良かったと思う。※そもそもHello-worldが何してるか先に調べろよってｗ
　次は、ヘルスチェックについて学ぼうと思う。

## 参考文献
[プログラマーのための YAML 入門 (初級編)](https://magazine.rubyist.net/articles/0009/0009-YAML.html#yaml-%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)
[15Stepで習得Dockerから入るKubernetes](https://www.amazon.co.jp/dp/4865941614)
[API OVERVIEW](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#pod-v1-core)